ThreeJS camera.lookAt() has no effect, is there something I'm doing wrong?
Solution 1
Looking at the source code of THREE.TrackballControls
, I figured out that I can make the camera look where I want by setting trackballControls.target
to the THREE.Vector3
I want it to look at, and then rerendering the scene.
Solution 2
Yes Please beware... It seems that having THREE.TrackballControls or THREE.OrbitControls seems to override the camera.lookAt function as your are passing in your camera when you instantiate an instance of the controls. You might want to get rid of the controls and then performing camera.lookAt() or tween your camera some other way to verify that the controls are having a overriding effect on your Camera. I googled for a while why camera.lookat() seemed to have no effect.
Solution 3
In my opinion, we are not supposed to mess with the original code. I found a way around to achieve the objective of looking at any particular point. After having declared your "control" variable, simply execute these two lines of code:
// Assuming you know how to set the camera and myCanvas variables
control = new THREE.OrbitControls(camera, myCanvas);
// Later in your code
control.object.position.set(camX, camY, camZ);
control.target = new THREE.Vector3(targetX, targetY, targetZ);
Keep in my mind that this will switch the center of the focus to your new target. In other words, your new target will be the center of all rotations of the camera. Some parts will be difficult to look at as you became familiar to manipulate the camera assuming the default center. Try zoom in as much as you can and you will have a sense of what I am saying Hope this help.
Solution 4
I figured it out. To prevent THREE.TrackballControls
or THREE.OrbitControls
from overriding camera.lookAt
upon initialization, you need to change the line that sets the control's target
property to equal the sum of the camera.position
vector and the camera.getWorldDirection()
vector, instead of how it's currently implemented using a new THREE.Vector3()
(which defaults to (0, 0, 0)
).
So, for THREE.TrackballControls
, change line 39 to:
this.target = new THREE.Vector3().addVectors(/*new line for readability*/
object.position, object.getWorldDirection());
Same goes for THREE.OrbitControls
, on line 36.
I actaully haven't tested it on TrackballControls.js
but it does work on OrbitControls.js
. Hope this helps.
Solution 5
Here's an alternative solution: create an object (i.e. cube) with 0 dimensions.
var cameraTarget = new THREE.Mesh( new THREE.CubeGeometry(0,0,0));
In the render function set the camera.lookAt to the position of the cameraTarget.
function render() {
camera.lookAt( cameraTarget.position );
renderer.render( scene, camera );
}
Then just move cameraTarget around as you wish.
houbysoft
Updated on May 30, 2020Comments
-
houbysoft almost 4 years
In Three.js, I want a camera to be pointed at a point in 3D space.
For this purpose, I tried using the
camera.lookAt
function like so:camera.lookAt(new THREE.Vector3(-100,-100,0));
However, I found out that the call has no effect whatsoever. It just does nothing at all. I tried changing the numbers in the vector, and I always get the same look on screen, when it should be changing.
I just found now that if I remove the
THREE.TrackballControls
I have in my code, thecamera.lookAt()
works as it should. Is there something wrong with how I use THREE.TrackballControls? This is how I initialize them:controls = new THREE.TrackballControls( camera, renderer.domElement ); controls.rotateSpeed = 10.0; controls.zoomSpeed = 1.2; controls.panSpeed = 0.2; controls.noZoom = false; controls.noPan = false; controls.staticMoving = true; controls.dynamicDampingFactor = 1.0; var radius = 5; controls.minDistance = radius * 1.1; controls.maxDistance = radius * 100; controls.keys = [ 65, 83, 68 ]; // [ rotateKey, zoomKey, panKey ]*/
And then in my render function I do:
function render() { controls.update(); renderer.render(scene, camera); }
Documentation on Three.js is pretty scarce, so I thought I'd ask here. Am I doing something wrong?
-
Wang Liang over 10 yearsThanks! I've googled for the answer for like forever, finally!
-
theprof over 10 yearsCorrect answer! Set controls.target = new THREE.Vector3(1500, 500, 0); where 1500, 500, 0 is my desired target to look at
-
Andrea Aloi over 9 yearsYes, precisely the issue I'm facing and for which I posted a new quesiton here. In my case, manually changing the source code of
THREE.OrbitControls
by initializing itstarget
property to the same vector passed tocamera.lookAt()
is not feasible, I'd rather come up with an inverse function so I could write something liketarget = getLookAtVectorFor(camera)
and never have to changeOrbitControls.js
's source code every time I change the lookAt vector of my camera. -
lhrec_106 about 8 yearsSame here, searched the result for literally two days! wanted to change the camera lookat but got no result until this answer.
-
ty. about 5 yearsThis answer helped me. If you have
OrbitControls
,TrackballControls
, etc in your visualization, you should use thecontrols.target
property instead ofcamera.lookAt
. -
dcromley almost 4 yearsWith revision 88 R88 the issue went away.
-
Grant Vinson about 3 yearsIf you don't want to override the source code, you can update your controls target in the render loop