场景中的静态对象 - Three.js
Static Object in Scene - Three.js
我的场景中有两个对象。我正在使用
<script src="js/controls/LeapTrackballControls.js" ></script>
用于移动相机,所以感觉物体随着我手的移动而旋转。
问题是另一个物体也在移动,我希望它始终保持在我的面前。我的意思是,即使相机移动,对象也始终位于 canvas/explorer 内的相同位置。
抱歉,如果我没有正确解释自己。
感谢任何帮助。
编辑:
var controls = new THREE.LeapTrackballControls( camera , controller );
所以,我在场景中间有一个球体。我使用 LeapTrackball 库将相机围绕场景中心移动。这让用户感觉球体围绕着他的中心旋转。
model = new THREE.Mesh(modelGeo, modelMat);
model.geometry.dynamic = true;
model.position.set(0, 0, 0);
scene.add(model);
我的问题是我有另一种形状:
myMesh = new THREE.Mesh(circleGeometry, material);
myMesh.position.set(0, 0, 10);
scene.add(myMesh);
这也受到相机旋转的影响。我想要的是保持球体的'fake rotation',而另一个网格保持在屏幕中间(0,0,10)。
好的,这是我的相机对象。
var camera = new THREE.PerspectiveCamera(55, window.innerWidth / window.innerHeight, 0.1, 5000);
还有我的渲染函数,用于更新相机的control/movement。
function render() {
controls.update();
renderer.render(scene, camera);
doMouse();
if(useOrbitControls){
orbitControls.update();
}
}
我正在使用 Leap 控制器,这是构建它的函数:
function leapMotion() {
var controllerOptions = {
enableGestures: true
, background: true
, frameEventName: 'animationFrame'
, };
[...]
controller.on('frame', onFrame);
基本上,这意味着每次接收到帧时都会执行 onFrame 函数(大约每秒 60 个。)
function onFrame(frame){
[...]
}
没有更多了,所有的魔法都来自你可以在这里找到的图书馆:
执行此操作的简单方法是让您的对象跟踪相机的位置。
跟踪意味着,在每次相机更新时,您将相机和物体移动相同的量,同时保持它们之间的固定距离。
为此,您需要设置一个固定位置,您的对象将始终在该位置被查看,在您的示例中它应该是 (0, 0, 10)。
var fixedPosition = new THREE.Vector3(0, 0, 10);
然后,在您的 render()
函数中,您需要在相机移动后但在渲染所有内容之前更新对象的位置。
function render() {
controls.update();
// let's update the object's position now!
myMesh.position.sub(camera.position, fixedPosition);
// now camera and mesh are at the same distance
renderer.render(scene, camera);
//...
}
在这种情况下,向量减法 工作正常,我们基本上采用相机的位置,减去我们的固定量(Z 轴上的 10),你就会得到你的对象的位置将始终位于 Z 轴上距相机 10 个单位的位置
一般来说,您将要执行的许多操作都涉及 3D 向量和一些数学运算,因此了解这些操作(基本加法、减法、乘法等)如何影响您在屏幕上看到的内容会很有用。
如果您有更多疑问,我建议您阅读一些有关矢量数学的内容,这并不难,您不需要记住 公式(Three.js 实现了所有您已经需要的数学),但了解这些操作的作用非常有用。
如果您希望某个对象(例如十字准线)固定在相机前面,您可以通过将该对象添加为相机的子对象来实现。使用像这样的模式:
scene.add( camera ); // required when the camera has a child
camera.add( object );
object.position.set( 0, 0, - 100 ); // or whatever distance you want
three.js r.71
希望这对使用 @react-three/fiber
的人有所帮助
import {useFrame, useThree} from "@react-three/fiber";
const { gl } = useThree();
const [ vrEnabled, setVREnabled ] = useState(false);
useFrame(({camera}) => {
setVREnabled(gl.xr.isPresenting);
if (vrEnabled) {
camera.add(ref.current);
ref.current.position.set( 18, 0, 0 );
}
});
我的场景中有两个对象。我正在使用
<script src="js/controls/LeapTrackballControls.js" ></script>
用于移动相机,所以感觉物体随着我手的移动而旋转。
问题是另一个物体也在移动,我希望它始终保持在我的面前。我的意思是,即使相机移动,对象也始终位于 canvas/explorer 内的相同位置。
抱歉,如果我没有正确解释自己。
感谢任何帮助。
编辑:
var controls = new THREE.LeapTrackballControls( camera , controller );
所以,我在场景中间有一个球体。我使用 LeapTrackball 库将相机围绕场景中心移动。这让用户感觉球体围绕着他的中心旋转。
model = new THREE.Mesh(modelGeo, modelMat);
model.geometry.dynamic = true;
model.position.set(0, 0, 0);
scene.add(model);
我的问题是我有另一种形状:
myMesh = new THREE.Mesh(circleGeometry, material);
myMesh.position.set(0, 0, 10);
scene.add(myMesh);
这也受到相机旋转的影响。我想要的是保持球体的'fake rotation',而另一个网格保持在屏幕中间(0,0,10)。
好的,这是我的相机对象。
var camera = new THREE.PerspectiveCamera(55, window.innerWidth / window.innerHeight, 0.1, 5000);
还有我的渲染函数,用于更新相机的control/movement。
function render() {
controls.update();
renderer.render(scene, camera);
doMouse();
if(useOrbitControls){
orbitControls.update();
}
}
我正在使用 Leap 控制器,这是构建它的函数:
function leapMotion() {
var controllerOptions = {
enableGestures: true
, background: true
, frameEventName: 'animationFrame'
, };
[...]
controller.on('frame', onFrame);
基本上,这意味着每次接收到帧时都会执行 onFrame 函数(大约每秒 60 个。)
function onFrame(frame){
[...]
}
没有更多了,所有的魔法都来自你可以在这里找到的图书馆:
执行此操作的简单方法是让您的对象跟踪相机的位置。
跟踪意味着,在每次相机更新时,您将相机和物体移动相同的量,同时保持它们之间的固定距离。
为此,您需要设置一个固定位置,您的对象将始终在该位置被查看,在您的示例中它应该是 (0, 0, 10)。
var fixedPosition = new THREE.Vector3(0, 0, 10);
然后,在您的 render()
函数中,您需要在相机移动后但在渲染所有内容之前更新对象的位置。
function render() {
controls.update();
// let's update the object's position now!
myMesh.position.sub(camera.position, fixedPosition);
// now camera and mesh are at the same distance
renderer.render(scene, camera);
//...
}
在这种情况下,向量减法 工作正常,我们基本上采用相机的位置,减去我们的固定量(Z 轴上的 10),你就会得到你的对象的位置将始终位于 Z 轴上距相机 10 个单位的位置
一般来说,您将要执行的许多操作都涉及 3D 向量和一些数学运算,因此了解这些操作(基本加法、减法、乘法等)如何影响您在屏幕上看到的内容会很有用。
如果您有更多疑问,我建议您阅读一些有关矢量数学的内容,这并不难,您不需要记住 公式(Three.js 实现了所有您已经需要的数学),但了解这些操作的作用非常有用。
如果您希望某个对象(例如十字准线)固定在相机前面,您可以通过将该对象添加为相机的子对象来实现。使用像这样的模式:
scene.add( camera ); // required when the camera has a child
camera.add( object );
object.position.set( 0, 0, - 100 ); // or whatever distance you want
three.js r.71
希望这对使用 @react-three/fiber
import {useFrame, useThree} from "@react-three/fiber";
const { gl } = useThree();
const [ vrEnabled, setVREnabled ] = useState(false);
useFrame(({camera}) => {
setVREnabled(gl.xr.isPresenting);
if (vrEnabled) {
camera.add(ref.current);
ref.current.position.set( 18, 0, 0 );
}
});