THREE.js Orthographic camera position not updating after *dolly* with OrbitControl - three.js

I'm using THREE.OrbitControls to dolly a THREE.OrthographicCamera. But, even thought the ortho camera renders correctly as repositioned, all that is updating on the orthographic camera is the 'zoom' property. Even after calling camera.updateProjectionMatrix(). Do I need to manually update the 'position' property of the camera based on the updated 'zoom' property? I want to display its position in my UI after dollying it.
(Note, this is a rewrite of my other question,THREE.js Orthographic camera position not updating after zoom with OrbitControl, in which I thought I was zooming with the OrbitControl but was actually dollying. Sorry about this).

Dollying in/out with an ortho cam would have an unnoticeable effect. With ortho cams there is no perception of proximity because it has no perspective. All objects appear the same in size regardless of distance from the lens because the projection rays are all parallel. The only difference you'd notice is when the objects get clipped because they're past the near or far plane.
So, the decision was made that scrolling with OrbitControls would change the zoom of the camera, narrowing in/out of the center.
If you want to force the camera to move further/closer of its focus point, you could just translate it back/forth in the z-axis with:
camera.translateZ(distance); A (-) distance would move it closer, and a (+) distance would move it further from its focus point.

Related

Aframe orbit control camera pan and rotation ease animation when reach limit

I am trying to do a navigation system like google cloud infrastructure like this:
google cloud infrastructure.
I want to do this using aframe rather than threejs. So I am now customising aframe orbit control by keven ngo:
aframe orbit control.
The problem is that, I succeeded in limiting the auto rotation in a certain angle, so as pan. But I have some following problem that I do not know how to do after searching every posiblities and tried my self:
how to achieve the same effect of bouncing back smoothly after reaching out the pan limit;
for some reason if I pan and after mouseup then when mouse moves, it still pans rather than rotate. Why is that?
how to make camera rotates slightly like in google's example(I modified the original library to rotate camera when mousemove rahter than mousedown)?
Below is the glitch link of my experiment:
aframe customized orbit control
what I customized(I notated my change with slashes and ADDITION text):
autorotates between set angle;
mouse click only pans; when mouse move, camera rotates and autorotate stops;
pan can be limited.
This is a long question, very appreciated if anyone can help!!
how to achieve the same effect of bouncing back smoothly after reaching out the pan limit?
One idea: on mouseup (ie release of pan mode), check if the camera target is outside of the camera's viewing frustrum. If so, calculate a new target position, say half way between current target position, and a point in line with the camera z axis( ie, the center of the screen). Then make an animation, that moves the camera target from current location, to new location.
for some reason if I pan and after mouseup then when mouse moves, it still pans rather than rotate. Why is that?
It seems that the navigation mode (panning, orbitting,or zooming), does not change on mouse up. Make a new (mouseup) listener, that forces orbit mode back to a default mode (orbit?).
how to make camera rotates slightly like in google's example(I modified the original library to rotate camera when mousemove rahter than mousedown)?
It looks like in the google example, orbit direction is determined by which side of center the cursor is in. Left side makes autorotate go clockwise, and right side counterclockwise. You will need to use the cursor component to detect this, and change the orbit direction accordingly.
Also, it appears that in the google version, orbitting is not determined by mousedown (ie dragging), but by cursor distance to center, and this is added to the auto rotate. It appears to be a buffer system, where distance to center initially creates a value to alter the auto orbit (by adding or subtracting to the orbit amount), but that value is a buffer, meaning that it degrades to 0 over time (each frame the value is reduced slowly to 0).

THREE.js Orthographic camera position not updating after zoom with OrbitControl

I'm using THREE.OrbitControls to zoom a THREE.OrthographicCamera. But, even thought the ortho camera renders correctly as zoomed, all that is updating on the camera is the 'zoom' property. Even after calling camera.updateProjectionMatrix(). Do I need to manually update the 'position' property of the camera based on the updated 'zoom' property? I want to display its position in my UI.
"Zooming" should never change a camera's position. Zooming changes the field of view of a camera, while it remains in the same position. Zooming in is the same as cropping an image.
When you move closer or further away from a subject, this is called "dolly". When you have an orthographic camera, because there is no perspective deformation, dollying has very little effect.
Do I need to manually update the 'position' property of the camera based on the updated 'zoom' property?
Yes, but "based on the..." is very very relative, for each zoom level you have infinitely many viable positions for your camera.

Creating a magnifying-glass effect in three.js WebGL

I'm working with an orthographic view in three.js/WebGL renderer, and I want a magnifying glass that tracks with the user mouse. I'm looking for the best way of doing this that's efficient.
When working with html5 canvas raw commands, this was easy: I simply defined a circular clip region, zoomed my coordinates, and re-drew the whole scene. With 3d objects, it's less obvious how do to it.
The method I've found so far is to do the following:
Define a second camera that looks into the zoomed region. Set the orthographic clip coordinates to be small so that it doesn't need to do much work
Create a THREE.WebGLRenderTarget
Tell the renderer and all my line textures that the resolution is about to change
Render the scene into the RenderTarget
Add a CircleGeometry as a MeshObject at the spot at the mouse position (in world coordinate but above the rest of the scene, close to the camera). Call this the lens.
Give the lens the WebGLRenderTarget as a texture.
Go back to my default camera, reset all my resolution parameters, and redraw the scene with the 'lens' object added.
This works (see image below) but I'm worried about parts of it:
I have to render twice per frame
Lines don't draw well, because the resolution problems. I have to keep track of all materials that need to know screen resolution and update all of them twice per screen render.
Related problems:
I want to overlay some plot axes on top of this, and possibly gridlines. These would change as the view pans. I'm not sure if I should make these 3d objects, or do it in a 2d canvas context I lay overtop.
I want to overlay some plot lines, and have them show up sensibly in the zoomed view. "Sensible" here is hard to figure out: I don't want them too fat in the zoomed view, but I also don't want to scale them up as much as the image detail (which is being rendered as a texture onto Plane objects behind).
This is a long post, but I'm still new to three.js and looking for good ideas.

How to create an orthographic/isometric directional light with three.js

I'm trying to create a shadow in my orthographic scene in three.js. I'd like to have a directional light so the shadow is offset from all objects equally in the scene. I am however having problems using DirectionalLight.
My first problem is that I can't get the shado to cover the entire scene, only part of it ever has a shadow. I played with the light's frustum settings, but can't figure out how to get it to cover the scene. Ideally I'd want the frustrum to match that of the camera.
The second problem is that the shadows aren't "clean". If I use a SpotLight the shadows have nice crisp borders (but obviously not the universal directionality I want). When I use a DirectionalLight the borders are misshappen and blurry.
In the samples the tile is a simply box created with CubeGeometry.
How can I create an ortographic directional light source for my scene?

Working with Three.js

Context: trying to take THREE.js and use it to display conic sections.
Method: creating a mesh of vertices and then connect face4's to all of them. Used two faces to produce a front and back side so that when the conic section rotates it won't matter from which angle the camera views it.
Problems encountered: 1. Trying to find a good way to create a intuitive mouse rotation scheme. If you think in spherical coordinates, then it feels like just making up/down change phi and left/right change phi would work. But that requires that you can move the camera. As far as I can tell, there is no way to change actively change the rotation of anything besides the objects. Does anyone know how to change the rotation of the camera or scene? 2. Is there a way to graph functions that is better than creating a mesh? If the mesh has many points then it is too slow, and if the mesh has few points then you cannot easily make out the shape of the conic sections.
Any sort of help would be most excellent.
I'm still starting to learn Three.js, so I'm not sure about the second part of your question.
For the first part, to change the camera, there is a very good way, which could also include zooming and moving the scene: the trackball camera.
For the exact code and how to use it, you can view:
https://github.com/mrdoob/three.js/blob/master/examples/webgl_trackballcamera_earth.html
At the botton of this page (http://mrdoob.com/122/Threejs) you can see the example in action (the globe in the third row from the bottom).
There is an orbit control script for the three.js camera.
I'm not sure if I understand the rotation bit. You do want to rotate an object, but you are correct, the rotation is relative.
When you rotate or move your camera, a matrix is calculated for that position/rotation, and it does indeed rotate the scene while keeping the camera static.
This is irrelevant though, because you work in model/world space, and you position your camera in it, the engine takes care of the rotations under the hood.
What you probably want is to set up an object, hook up your rotation with spherical coordinates, and link your camera as a child to this object. The translation along the cameras Z axis relative to the object should mimic your dolly (zoom is FOV change).
You can rotate the camera by changing its position. See the code I pasted here: https://gamedev.stackexchange.com/questions/79219/three-js-camera-turning-leftside-right
As others are saying OrbitControls.js is an intuitive way for users to manage the camera.
I tackled many of the same issues when building formulatoy.net. I used Morphing Geometries since I found mapping 3d math functions to a UV surface to require v little code and it allowed an easy way to implement different coordinate systems (Cartesian, spherical, cylindrical).
You could use particles instead of a mesh I suppose but a mesh seems best. The lattice material is not too useful if you're trying to understand a surface mathematically. At this point I'm thinking of drawing my own X,Y lines on the surface (or phi, theta lines etc) to better demonstrate cross-sections.
Hope that helps.
You can use trackball controls by which you can zoom in and out of an object,rotate the object,pan it.In trackball controls you are moving the camera around the object.Object still rotates with respect to the screen or renderer centre (0,0,0).

Resources