javascript - 使用 three.js 和 React 迭代定位具有 DOM 像素的球体

标签 javascript reactjs three.js

我正在尝试使用从 SO 中找到的函数渲染一堆球体,以将 DOM 像素转换为 three.js 世界中的坐标(这样我就可以将球体放在与我的文本相同的位置)。

我的问题是第一个球体在错误的位置,如下图所示。 (其余位置完美)。

First sphere out of place

这是我将像素转换为 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 1

Sphere 2(DOM 像素为 x = 124,y = 200)

Sphere 2

球体 3(DOM 像素为 x = 224,y = 200)

Sphere 3

如您所见,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/

相关文章:

javascript - 为什么我们应该在 return 语句中使用 {}

reactjs - 如何在 3js 中对 GLTF 元素进行分组和拖放

javascript - 在 JS 中检查互联网连接的最快方法

javascript - 在不改变位置的情况下淡入淡出内联div?

javascript - 排序 JSON 对象

javascript - meteor 错误处理

javascript - 在 react Bootstrap Form.Control 中显示可编辑值

html - 从 Rails 后端发送图像路径时,图像标签在 React 中不起作用

javascript - 在 MeshPhongMaterial 地面和聚光灯下看不到 Collada 模型的任何阴影

javascript - 渲染带有 alpha channel 的 png 时, Three.js 会从显卡中泄漏像素