即使复制相机的位置和旋转角度,物体也不会停留在相机前面

时间:2019-09-23 08:16:14

标签: typescript three.js

我试图在照相机移动时使物体(球体)居中放置在照相机前面。我通过更改相机的位置和旋转lookAt()为相机设置动画,这似乎正常工作。但是球体对象不会在框架中说出来。我尝试过

const centerSphereInCameraWithQuaternion = (sphere: THREE.Mesh, camera: THREE.PerspectiveCamera) => {
  const vec = new THREE.Vector3( 0, 0, - 4 );
  vec.applyQuaternion( camera.quaternion );

  sphere.position.copy( vec );
}

使球体完全消失。我也尝试过

const centerSphereInCamera = (sphere: THREE.Mesh, camera: THREE.PerspectiveCamera) => {
  sphere.position.copy( camera.position );
  sphere.rotation.copy( camera.rotation );
  sphere.updateMatrix();
  sphere.translateZ( - 4 );
}

几乎起作用的

,但是球体沿相机所面对的相反方向旋转。也尝试过

sphere.position.sub(camera.position);

什么也没显示。

我尝试添加一个相机助手,以确保正确更新了相机的世界矩阵,而且看起来确实如此。

我在这里做错了什么?有没有一种方法可以完成此任务而无需将网格添加为相机的子级?

1 个答案:

答案 0 :(得分:0)

除非您要对照相机的位置做一些不合常规的事情,否则您真正需要将物体固定在照相机前面(不将其嵌套在照相机内)的三行内容:

sphere.position.copy(camera.position);
sphere.rotation.copy(camera.rotation);
sphere.translateZ(-40);

您可以运行下面的代码片段以查看其运行情况。我使照相机在整个场景中滑动,然后使用上面的三行线将球体保持在每帧镜头的正前方。相关代码在底部附近的animate()函数中:

var camera, scene, renderer;

// scene
scene = new THREE.Scene();
scene.background = new THREE.Color(0xe1e1e1);

// camera
camera = new THREE.PerspectiveCamera(35, window.innerWidth / window.innerHeight, 0.1,       100);

const ambient = new THREE.DirectionalLight(0xddeeff, 1);
ambient.position.set(0, 1, 1);

const floor = new THREE.Mesh(
    new THREE.BoxBufferGeometry(20, 0.25, 20),
    new THREE.MeshPhongMaterial()
);
const wall = new THREE.Mesh(
    new THREE.BoxBufferGeometry(.5, 3, 10), 
    new THREE.MeshPhongMaterial({ color: 0xc4ffc4})
);
const sphere = new THREE.Mesh(
    new THREE.SphereBufferGeometry(3, 20, 20),
    new THREE.MeshPhongMaterial({ color: 0xff0000 })
);

scene.add(ambient, floor, wall, sphere);

renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, Infinity));

document.body.appendChild(renderer.domElement);

function animate(t) {
    // Move camera
    const xPos = Math.sin(t / 777) * 50;
    const yPos = Math.sin(t / 666) * 25;
    const zPos = Math.cos(t / 1000) * 50;
    camera.position.set(xPos, yPos, zPos);
    camera.lookAt(0, 0, 0);
    
    // Move sphere
    sphere.position.copy(camera.position);
    sphere.rotation.copy(camera.rotation);
    sphere.translateZ(-40);
    
    renderer.render(scene, camera);
    requestAnimationFrame(animate);
}

animate(0);
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/104/three.min.js"></script>