如何在THREE.JS中将一个物体放到摄像机前面?

16

我想将一个物体放在相机前方,但一直没有成功。

我正在使用FlyControls移动相机,现在我想在其前方放置一个物体。我该如何实现?我尝试了许多不同的方法,但都没有成功。

谢谢


你能展示一些代码,这样我们就可以看到错误出在哪里吗? - gaitat
7个回答

30

你尝试过将你的物体作为相机的子对象并向前移动吗?

camera.add(nanobot);
nanobot.position.set(0,0,-100);

上述内容将纳米机器人永久地放置在相机前方100个单位的位置...在你进行以下操作之前,它将一直待在那里:

camera.remove(nanobot);

在这一点上,它应该留在全局空间中,直到您使用其他方法移动它。


18
你还需要将相机设置为场景的子元素(通常不是默认设置),使用命令scene.add(camera) - mattdlockyer
2
请确保 nanobot.position.set(0,0,-100);camera.add(nanobot); 之后:position 是相对于相机的本地位置。[threejs r89] - zwcloud
这个回答已经6年了,所以我猜我应该预料到会出现错误。我在camera.add()上得到了object not an instance of Object3d的错误。有没有什么办法可以修复它? - user8866053
1
简单来说,你不能再这样做了。以前相机被视为3D对象,现在被视为独立实体。 - MacK
2
这个答案对我有用,我刚刚将它添加到一个非常复杂的 WebXR 项目中,该项目正在最新的 Three.js(0.120.1)上运行。这是在一个 WebXR 场景中,所以相机经常移动,场景坐标不稳定,但精灵仍然停留在应该停留的位置。 - Jascha Ehrenreich
谢谢 @mattdlockyer,不把场景的相机设定好是我遇到的问题 :) - Doug

7

我正在使用three.js r88,并且从Kaspar Lee发布的内容开始,已经找到了解决方案。

function updatePositionForCamera(camera) {
    // fixed distance from camera to the object
    var dist = 100;
    var cwd = new THREE.Vector3();
    
    camera.getWorldDirection(cwd);
    
    cwd.multiplyScalar(dist);
    cwd.add(camera.position);
    
    myObject3D.position.set(cwd.x, cwd.y, cwd.z);
    myObject3D.setRotationFromQuaternion(camera.quaternion);
}

3

您可以将对象放置在相机的位置,然后稍微向后移动一点。

// from: https://github.com/mrdoob/three.js/issues/641#issuecomment-2369456

object.position.copy( camera.position );
object.rotation.copy( camera.rotation );
object.updateMatrix();
object.translateZ( - 10 );

如果您不想旋转物体,可以旋转助手对象,然后使用助手对象的位置。

// from: https://github.com/mrdoob/three.js/issues/641#issuecomment-808045236
var helperObject = new Object3d()

helperObject.position.copy( camera.position );
helperObject.rotation.copy( camera.rotation );
helperObject.updateMatrix();  // this line seems unnecessary
helperObject.translateZ( - 10 );

// just use helperObject.position and do not rotate yourObject
yourObject.position.set(helperObject.position)


2
var cx, cy, cz, lx, ly, lz;



dir.set(0,0,-1);
dir.applyAxisAngle(0,camera.rotation.x);
dir.applyAxisAngle(1,camera.rotation.y);
dir.applyAxisAngle(2,camera.rotation.z);
var dist = 100;

cx = camera.position.x;
cy = camera.position.y;
cz = camera.position.z;

lx = dir.x;
ly = dir.y;
lz = dir.z;


var l;

l = Math.sqrt((dist*dist)/(lx*lx+ly*ly+lz*lz));

var x1, x2;
var y1, y2;
var z1, z2;     

x1 = cx + lx*l;
x2 = cx - lx*l;

y1 = cy + ly*l;
y2 = cy - ly*l;

z1 = cz + lz*l;
z2 = cz - lz*l;


nanobot.position.set(x1, y1, z1 );

我尝试计算摄像机方向的方向向量,然后计算通过摄像机的直线,在该直线上距离摄像机一定距离处放置一个点。


2
将对象作为相机的子级是最直接的方法。我刚在THREE r126上测试了它,请注意先将相机添加到场景中 :)

谢谢,伙计!我一开始完全忘了把相机加入场景中!:D - dirkk0

1
这里有另一种方法 - 将相机的四元数应用于向量( dist 是您希望对象与相机保持的距离):
var vec = new THREE.Vector3( 0, 0, -dist );
vec.applyQuaternion( camera.quaternion );

nanobot.position.copy( vec );

将对象作为相机的子级对我无效,但这个applyQuarternion方法有效(从@WestLangley的答案中适应:Three.js: Get the Direction in which the Camera is Looking)。
如果您希望物体始终面向相机,则还可以复制相机的旋转。如果要在此之后微调物体的确切位置,则可以进行translateX、translateY等操作。

0
使用这段代码,您的对象将与相机处于同一位置。如果您希望在移动相机时对象跟随相机移动,请在渲染之前在animate函数中添加此代码。
object.position.copy (new THREE.Vector3 (camera.position.x, camera.position.y, camera.position.z));

如果你想查看你的对象,例如:
不要把 < camera.position.z > 放进去,而是放入 < camera.position.z - 10 > 或者 < camera.position.z + 10 >


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接