我正在尝试使用从 SO 中找到的函数渲染一堆球体,以将 DOM 像素转换为 three.js 世界中的坐标(这样我就可以将球体放在与我的文本相同的位置)。
我的问题是第一个球体在错误的位置,如下图所示。 (其余位置完美)。
这是我将像素转换为 three.js 坐标的代码:
function convertDomPosToThreePos(x, y, camera) {
const vPos = new THREE.Vector3()
vPos.set(
-1.0 + 2.0 * x / window.innerWidth,
-(-1.0 + 2.0 * y / window.innerHeight),
0,
).unproject(camera)
// Calculate a unit vector from the camera to the projected position
const vDir = vPos.clone()
vDir.sub(camera.position)
vDir.normalize()
// Project onto z=0
const flDistance = -camera.position.z / vDir.z
// Return vector
const vOutPos = camera.position.clone()
vOutPos.add(vDir.multiplyScalar(flDistance))
// This returned vector is applied to the sphere's position property
return vOutPos
}
为了说明发生了什么,这里是我的调试器的监视选项卡的一些屏幕,显示了前三个球体在渲染时的主要值:
球体 1:(DOM 像素为 x = 24,y = 200
)
Sphere 2(DOM 像素为 x = 124,y = 200
)
球体 3(DOM 像素为 x = 224,y = 200
)
如您所见,flDistance
从球体 1 到 2 从 2000 跳到 2181,此时它显然应该高于 2181 才能开始。
vOutPos
中输出的 x 值从 ~0 到 -870 从球体 1 到 2,此时它应该明显低于 -870 才能开始。
我的第一个想法是可能在第一次调用 convertDomPosToThreePos
时未定义值,但在记录每次迭代的参数时,它们都已正确定义。
最佳答案
Three.js 对几件事使用惰性初始化,包括相机系统(投影矩阵)。只有在您第一次渲染场景时才会完全初始化。
当您计算第一个行星的位置时,场景之前从未渲染过,因此从“相机” Angular 取消投影无法正常工作。
解决方案是在定位行星之前渲染一次场景:
function initThree() {
....
// initialize camera
renderer.render(scene, camera);
}
关于javascript - 使用 three.js 和 React 迭代定位具有 DOM 像素的球体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53769506/