I'm using a Perspective Camera for my top down Three.js game, but it curves a bit too much because it's designed to be used as "first person view". Is there a way to adjust how much objects bend/curve in the frustum from the sides?
Essentially, I would like something like a mix of a Perspective Camera and an Orthographic Camera
E.g -- The walls of the buildings should be less visible from a certain distance
You can adjust the camera FOV.
https://threejs.org/docs/?q=persp#api/en/cameras/PerspectiveCamera
Made a simple Pen here:
https://codepen.io/cdeep/pen/eYEOqrz
camera.fov = 30;
camera.updateProjectionMatrix ();
The lesser the FOV, the more flatter things look.
Please note that you'll need to position the camera farther away at lower FOVs to ensure the contents fit inside the view which also requires you to increase the camera's far property so things don't get cut out
Related
I saw this great implementation of a parallax view, which creates an illusion of depth and I want to build something similar in Three.js.
http://www.anxious-bored.com/blog/2018/2/25/theparallaxview-illusion-of-depth-by-3d-head-tracking-on-iphone-x
However, it seems that a non-symmetric camera frustum is needed. That means that the frustum of the camera is somehow fixed to the rendered object.
My question is, how do I realize that in three.js? Is it possible to manipulate the frustum corners or frustum sides?
Here you can see the top down view on my camera.
Looking strait to the object
After moving the camera to the left
You could use setViewOffset so skew the frustum. You can also directly manipulate the cameras projection matrix.
The solution to my problem was the projection matrix as pailhead already suggested.
Changing the 8. and 9. index of the matrix array does the affine transformation in x and y direction.
https://i.stack.imgur.com/Qrjb0.png
The short story: I am trying to use THREE.TrackballControls to move the camera, but the (upside-down) x-z plane is where the x-y plane should be. Can anyone help?
The long story: I've been trying to add device orientation controls to a project. I have already used the THREE.TrackballControls to move the camera when mouse and touch are being used, and the direction the camera points feeds into other functionality. I am using v69 of three.js.
So, I have been looking into using THREE.DeviceOrientationControls to enable device orientation. Specifically, what I'm after is for rotation to be in the x-y plane when the device is upright in front of me and I turn around. Or in other words, when the device is face up on the table it is looking in the -ve z-direction, and when upside down it it looking in the +ve z-direction. Sounds fairly straightforward, right?
There are plenty of examples around to follow, but I seem to be stuck with axes incorrectly orientated, i.e. what should be my x-y plane is coming out as the x-z plane, but upside-down. I created a test page based on an example with a BoxGeometry cube I found, and then added red, yellow and blue spheres to the middle of the faces that corresponded to the +ve x-, y-, and z-directions respectively, and then pale versions of the same coloured spheres for the corresponding -ve directions. Testing this on an iPad confirmed that the scene axes and the real world axes were not lining up.
I have spent a bit of time trying to get to grips with how this Object works, and the main sticking point is in the function returned by setObjectQuaternion() which does the tricky bit:
...
return function (quaternion, alpha, beta, gamma, orient) {
euler.set(beta, alpha, -gamma, 'YXZ'); // 'ZXY' for the device, but 'YXZ' for us
quaternion.setFromEuler(euler); // orient the device
quaternion.multiply(q1); // camera looks out the back of the device, not the top
quaternion.multiply( q0.setFromAxisAngle( zee, - orient ) ); // adjust for screen orientation
}
...
where q1 is quaternion for a -pi/2 rotation around the x-axis, and zee is a unit z-axis vector.
I set up a jsfiddle here to help me debug this, but it wasn't rendering correctly on the iPad itself, so I had to add in some faking of orientation events, and plenty of logging, and continue on a normal desktop + console. This jsfiddle goes through each of the 6 basic orientations and sees whether the camera is looking in the direction I expect.
(Initially it would seem that a pi/2 rotation around the x-axis is what is required, but removing the quaternion.multiply(q1) doesn't fix it - I haven't even started looking at non-zero screen orientations yet.)
Ultimately, I'd like to make this more like the TrackballControls/OrbitControls with a target point that the camera always looks at (unless panned) and rotates around, once I've figured this "simple" stuff out.
Anybody have any ideas how I can orientate my camera properly?
Let cube be a THREE.Mesh added to the scene space.
cube.position.set( 10, 10, 10 );
scene.add( cube );
After rotating the scene with the mouse, I would like to hide the cube object if its position, as seen from the current camera's position, lies beyond the scene space origin at (0,0,0). I guess where I stumble is: How can I transform the scene space coordinates to get the according coordinates from the camera perspective?
Add-on
As a novice to 3D I probably lack the proper "space"-vocabulary to describe the situtation. Some terminological clarification would be highly welcome as an add-on :)
Update 2015-01-30
An improved explanation of what I want: Using the frustum-far-analogy from gaitat's comment, we may think of the above task as identifying all objects that lie beyond an imaginary frustum plane that passes through the red point. Now I want to identify all point that lie beyond that plane given that point, which in my case is (0,0,0).
You could create an opaque plane that is perpendicular to the camera. Then anything behind it will be hidden. Based on this other SO post, you could use the myPlane.lookAt() function to look at the camera's position and thereby make it perpendicular to the camera.
How do you make a mini-cam or mini-map using three.js?
Two camera views. One mini-map "mini-cam" - top right corner (see image below), and the main camera view should span the rest of the scene (the rest, without the border in image below).
N.B. This actually can't quite be done via the viewport method, as the scene shouldn't be cropped off by the x-dimensionality, but should stretch out.
I have created a working example of a scene together with a minimap at:
http://stemkoski.github.io/Three.js/Viewports-Minimap.html
I don't understand your N.B. about not able to be done using viewports; as you'll see in the code at the website posted above, if you use for example an orthogonal camera positioned above the scene, you can set the left/right/top/bottom values so that the entire scene is included in your render, you just have to be careful about the height-to-width ratio so that your scene doesn't appear stretched.
On the other hand, if you're looking to go to the render-to-texture route, I have a relevant example at http://stemkoski.github.io/Three.js/Camera-Texture.html but as yaku mentioned in his response, you will have to update the position of the plane mesh so that it follows both the camera position (offset by some amount) and also rotation so that it always faces the camera. Due to the more complex nature of this approach, I really recommend the viewport method.
You can make a plane geometry (normal 3D object, and it actually doesn't need to be a plane, any shape goes) representing the minimap, and add it to camera so it follows the camera movement and is always visible.
Then use "Render to Texture" method to render the minimap and slap the texture to the plane "container".
There are render to texture examples around the net, SO, as well as in the Three.js examples folder, those should help get you started with that.
THREE JS, can often seem angular and straight edged. I haven't used it for very long and thus am struggling to understand how to curve the world so to speak. I would imagine a renderer or something must be changed, but the idea is to take a 2d map and turn it into a simple three lane running game. However, if you look at the picture below from another similar game, how can i achieve the fish eye effect?
I would do that kind of effect on per-vertex base depending on the distance from the camera.
Also, maybe a bit tweaked perspective camera with bigger vertical fov would boost up the effect of the "curviness".
It's just a simple distortion effect that has been simulated in some way, it probably isn't really curved. Hope this helps.
I'm sure there are many possible different approaches... Here's one that creates nice barrel distortion effect.
You can do something like that by rendering normal wide angle camera to a texture, then project it to a lens-shaped plane (a sphere even), then the actual on-screen render is from a camera pointing to that.
I don't have the code available ATM, but I should be able to dig it up in few days if interested. Or you can just adapt from the three.js examples. Three.js includes some postprocessing examples where the scene is first rendered into a texture, that texture is applied to a a quad then photographed with ortographic camera. You can modify such an example by changing the ortographic camera to a perspective one, then distorting/changing the quad to something more appropriately shaped.
Taken to extremes, this approach can produce some pixelization / blocky artifacts.