不使用camera.rotation或lookAt()函数旋转相机,我希望可以直接传递一个“观察向量”给相机...是否可以直接设置相机的“观察向量”,并且是否可以从相机读取“观察向量”?
camera.lookAt( point );
如果相机没有父级(场景之外的其他对象),以下是确定相机朝向的方法:
相机沿着其内部负z轴朝下看,因此需要创建一个指向负z轴的向量:
var vector = new THREE.Vector3( 0, 0, - 1 );
现在,将应用于相机的旋转同样应用于应用于该相机的向量:
vector.applyQuaternion( camera.quaternion );
生成的向量将指向相机所看的方向。
或者,您可以使用以下方法,即使相机是另一个对象的子对象也可以使用:
camera.getWorldDirection( dirVector );
three.js r.73
lookAt()
会查看 3D 空间中的一个点,而不管相机在哪里。因此,要获取相机正在查看的点,您需要通过调用进行相机位置调整:
vec.add( camera.position );
还值得一提的是,相机不是在查看一个点,而是在查看无限多个点的线路,每个点与相机的距离不同。其他答案中的代码返回一个长度为一的向量,因为将四元数应用于归一化的 z 轴向量(0, 0, -1)会返回另一个归一化向量(朝不同方向)。要计算距相机任意距离 x
的观察点,请使用:
THREE.Vector3( 0, 0, -x ).applyQuaternion( camera.quaternion ).add( camera.position );
这将获取沿着 z 轴距原点 x
的点,将其旋转到相机方向,然后通过添加相机的位置创建一个“世界点”。我们需要一个“世界点”(而不仅仅是“相对于相机的点”),因为 camera.lookAt()
也需要一个“世界点”作为参数。Vector3
类可用于表示点、向量或方向向量。在这种情况下,问题是关于方向向量的。所接受的答案解释了如何从方向向量中“设置”相机方向。它还解释了如何从相机方向“推断”出方向向量。关于所接受的答案没有任何错误之处。你正在回答别人的问题。 - WestLangleynlerp()
而不是 slerp()
,因为它的计算成本要低得多,并且可以通过选择距离 x 处的相机 lookAt 点并插值到所需的 lookAt 点也在距离 x 处来实现近乎相等的效果。但你是正确的。这是另一个话题。对于任何误解,我表示歉意。抱歉。 - chorpitaTHREE.Utils = {
cameraLookDir: function(camera) {
var vector = new THREE.Vector3(0, 0, -1);
vector.applyEuler(camera.rotation, camera.eulerOrder);
return vector;
}
};
THREE.Utils.cameraLookDir(camera);
调用。<!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>