Instead of rotating the camera with camera.rotation or with the lookAt() function I'd like to pass a look vector directly to the camera... Is it possible to set a camera look vector directly and is it possible to read the look vector from the camera?
4 Answers
The camera does not have a "look vector", so you cannot set it.
You can, however, construct a point
to look at by adding your look vector to the camera's position, and then calling
camera.lookAt( point );
Here is how to determine the direction in which the camera is looking, assuming the camera either has no parent (other than the scene).
The camera is looking down its internal negative z-axis, so create a vector pointing down the negative z-axis:
var vector = new THREE.Vector3( 0, 0, - 1 );
Now, apply the same rotation to the vector that is applied to the camera:
vector.applyQuaternion( camera.quaternion );
The resulting vector will be pointing in the direction that the camera is looking.
Alternatively, you can use the following method, which works even if the camera is a child of another object:
camera.getWorldDirection( dirVector );
three.js r.73

- 102,557
- 10
- 276
- 276
-
This is good info, thanks West. I still think there must be a look vector somewhere internally it should be fundamental to the 3d camera... Ah, ok I think I understand the reasoning behind this, the camera never moves and the entire scene is transformed around it, aways looking -z, so the look vector is always 0 0 -1 and everything else is rotated – Dev Mar 29 '13 at 14:40
-
No. The camera moves in world space, but from the camera's frame of reference, it is looking down its negative z-axis. – WestLangley Mar 29 '13 at 15:52
-
sure West, another way to do this (if you are using a lookat point) is to normalize (camera - lookat).. this way should be able to avoid extra calculation when parented – Dev Apr 04 '13 at 21:50
These other answers are very insightful, but not completely correct. The code returns a vector that points in the same direction that the camera is pointing at. That's a great start!
But unless the camera is at the origin (0, 0, 0) (or lies exactly on the line segment that connects the origin to the rotated vector point without passing beyond that point so that the point is behind the camera) the camera won't be looking at that point. Clearly -- just common sense -- the position of the camera also influences what points are being looked at. Just think about it!!
The camera method lookAt()
looks at a point in 3D space regardless of where the camera is. So to get a point that the camera is looking at you need to adjust for the camera position by calling:
vec.add( camera.position );
It is also worth mentioning that the camera is looking not at a single point but is looking down a line of an infinite number of points, each at a different distance from the camera. The code from the other answers returns a vector that is exactly one unit in length because the application of a quaternion to the normalized z-axis vector (0, 0, -1) returns another normalized vector (in a different direction). To calculate the look at point at an arbitrary distance x
from the camera use:
THREE.Vector3( 0, 0, -x ).applyQuaternion( camera.quaternion ).add( camera.position );
This takes a point along the z-axis at a distance x
from the origin, rotates it to the direction of the camera and then creates a "world point" by adding the camera's position. We want a "world point" (and not just a "relative to the camera point") since camera.lookAt()
also takes a "world point" as a parameter.

- 221
- 2
- 5
-
1In three.js, the `Vector3` class can be used to represent either a point, a vector, or a direction vector. In this case, the question is about a direction vector. The accepted answer explains how to _set_ the camera orientation from a direction vector. It also explains how to _infer_ a direction vector from the camera orientation. There is nothing incorrect about the accepted answer. You are answering someone else's question. – WestLangley Feb 07 '15 at 23:57
-
Yes. You are correct. I gave this more thought and saw that you even mentioned adding the vector to the camera position. Great job on your part. To me it is interesting to think about how to use `nlerp()` instead of `slerp()` as it is computationally much less expensive and can be made to work nearly equally if one chooses the camera lookAt point at a distance x and interpolates to the desired lookAt point also at a distance x. But you are correct. This is another topic. I apologize for any misunderstanding. Sorry. – chorpita Feb 09 '15 at 07:53
-
*The accepted answer explains how to set the camera orientation from a direction vector.* No, you didn't. – zwcloud Apr 18 '18 at 11:37
The above answer wrapped as a util, this is what I do with my Three Utils:
THREE.Utils = {
cameraLookDir: function(camera) {
var vector = new THREE.Vector3(0, 0, -1);
vector.applyEuler(camera.rotation, camera.eulerOrder);
return vector;
}
};
Call it with THREE.Utils.cameraLookDir(camera);

- 6,984
- 4
- 40
- 44
-
very nice style matt, can I expect that another util would follow the close curly brace of cameraLookDir in the same format? – Dev Jun 25 '13 at 03:53
-
Yes, you just have to comma separate them. This is literal javascript object notation and you should note that you will need to make sure THREE is loaded before this script in order for it all to work. – mattdlockyer Jun 25 '13 at 16:43
-
And for the capitalization I'm assuming: package = THREE, class = Utils, method = cameraLookDir. In case that appeared to be a little funky. – mattdlockyer Jun 25 '13 at 16:45
-
Looks good @mattdlockyer , is there a way to use this — while orbiting a 3d model — to keep text labels oriented towards the camera? – Agent Zebra Aug 14 '15 at 04:31
-
1Use sprites for text labels, they will always point and orient correctly towards the camera – mattdlockyer Aug 18 '15 at 20:53
What I did was to use method lookAt(Vector) just before render the scene like in below code , just try it using it on a new html file :)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style >
*{
margin: 0 ;
}
#WebGlElement {
height: 500px;
width: 500px;
background-color: red
}
</style>
</head>
<body>
<script src="js/three.min.js"></script>
<div id="WebGlElement"></div>
<script>
var contianer = document.getElementById("WebGlElement");
var origin = new THREE.Vector3(0,0,0);
// CREATE THREE BASIC ELEMENTS
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 40, 300/300, 1, 1000 );
var renderer = new THREE.WebGLRenderer();
// SET RENDERER AND ATTACH IT TO BODY
renderer.setSize( 500, 500 );
//document.body.appendChild( renderer.domElement );
contianer.appendChild( renderer.domElement);
// CREATE A GEOMETRY AND ADD IT TO SCENE
/*var geometry = new THREE.BoxGeometry( 1, 1, 5 );
var material = new THREE.MeshBasicMaterial( { color: 0x1abc9c } );
material.wireframe = true ;
material.wireframeLinewidth = 0.1 ;
var cube = new THREE.Mesh( geometry, material );
scene.add( cube );*/
var geometry = new THREE.Geometry();
geometry.elementsNeedUpdate=true;
geometry.vertices.push(
new THREE.Vector3( -0, 1, 0 ),
new THREE.Vector3( -1, -1, 0 ),
new THREE.Vector3( 1, -1, 0 )
);
geometry.faces.push(
new THREE.Face3( 0, 1, 2 ),
new THREE.Face3( 2, 1, 0 )
);
var material = new THREE.MeshBasicMaterial( { color: 0x1abc9c } );
//material.wireframe = true ;
//material.wireframeLinewidth = 0.1 ;
var cube = new THREE.Mesh( geometry, material );
scene.add( cube );
var axisHelper = new THREE.AxisHelper( 1 );
scene.add( axisHelper );
// POSITION OF CAMER ON Z
camera.position.z = 5;
camera.position.y = 5;
camera.up = new THREE.Vector3(0,0,1);
var dir = 1;
var number = 0.115
// CREATE FUNCTION FOR RENDER
var render = function () {
requestAnimationFrame( render );
//circle.rotation.x += 0.01;
if ( camera.position.x> 5) {
dir = -1;
}
if ( camera.position.x< -5) {
dir = 1;
}
camera.lookAt(cube.position);
//camera.rotation.y += 0.015 * dir;
camera.position.x += number * dir;
renderer.render(scene, camera);
};
// EXECUTE FIRST RENDER
render();
</script>
</body>
</html>