【发布时间】:2018-05-27 18:04:51
【问题描述】:
我试图在一个方向范围内沿着平面找到一个点到大型复杂网格的最近距离:
for (var zDown in verticalDistances) {
var myIntersect = {};
for (var theta = Math.PI / 2 - 0.5; theta < Math.PI / 2 + 0.5; theta += 0.3) {
var rayDirection = new THREE.Vector3(
Math.cos(theta),
Math.sin(theta),
0
).transformDirection(object.matrixWorld);
// console.log(rayDirection);
_raycaster.set(verticalDistances[zDown].minFacePoint, rayDirection, 0, 50);
// console.time('raycast: ');
var intersect = _raycaster.intersectObject(planeBufferMesh);
// console.timeEnd('raycast: '); // this is huge!!! ~ 2,300 ms
// console.log(_raycaster);
// console.log(intersect);
if (intersect.length == 0) continue;
if ((!('distance' in myIntersect)) || myIntersect.distance > intersect[0].distance) {
myIntersect.distance = intersect[0].distance;
myIntersect.point = intersect[0].point.clone();
}
}
// do stuff
}
将鼠标悬停在同一表面上时我得到了很好的结果,但是在执行此循环时,每次投射需要 2 秒以上的时间。我唯一能想到的是 DoubleSide 材料的背面要慢很多?
我还注意到,当我将verticalDistances[zDown].minFacePoint 隔开以使其相距更远时,光线投射开始加速(500 毫秒/投射)。因此随着verticalDistances[i].minFacePoint 和verticalDistances[i+1].minFacePoint 之间的距离增加,raycaster 的执行速度会更快。
我会走使用八叉树的路线,但鼠标悬停事件在完全相同的平面缓冲区上运行得非常好。这是材料问题的一面吗?可以通过加载 2 个指向相反方向的 FrontSide 网格来解决?
谢谢!!!!
编辑:这不是前后问题。我在平面缓冲区几何体的正面和背面运行我的光线投射,并获得相同的点结果。活生生的例子来了。
编辑 2:工作示例 here。性能略好于原始案例,但仍然太慢。我需要实时移动气缸。我可以通过查找某些东西来进行一些优化,但是鼠标悬停是即时的。当您查看控制台时间时,前两个(500 毫秒)是我得到的所有结果的结果。
编辑 3:添加了鼠标悬停事件,其执行与其他光线投射器相同。我在我的工作代码中没有得到我在这个示例中得到的结果。我得到的所有光线投射的结果与我在 500 毫秒左右的样本中的前 1 或 2 个得到的结果相同。如果我能把它降低到 200 毫秒,我可以瞄准我正在寻找的项目并减少光线投射。我完全愿意接受有关更好方法的建议。八叉树是要走的路吗?
raycast: : 467.27001953125ms
raycast: : 443.830810546875ms
编辑 4:@pailhead 这是我的计划。 1.找到最近的网格顶点指向平面。我可以在 x/y 方向扫描顶点,然后计算最小距离。 2.一旦我有了最近的顶点,我就知道我最近的点必须在包含该顶点的面上。因此,我将使用 object.mesh.index.array 找到具有该顶点的所有面,并计算每个面的平面到点。与网格相交并至少根据最大距离剔除点时,似乎光线投射应该比完全扫描更智能一点? @WestLangley 有什么建议吗?
编辑 5: @pailhead 谢谢你的帮助。其赞赏。我真的简化了我的example(
编辑 6:看起来所有网格在 raycast 函数中的处理方式相同。这意味着它不会聪明地寻找平面缓冲区几何的区域。查看mesh.js 第 266 行,我们遍历整个索引数组。我猜对于常规网格,您不知道哪些面在哪里,因为它是 TIN,但是 planeBuffer 可以真正使用边界框/球体规则,因为您的 x/y 是已知的顺序位置,只有 Z 是未知的。最后编辑,答案将在下一个
【问题讨论】:
-
为什么你认为背面或正面应该重要?你能发布一些实时代码吗?
-
现在正在处理示例。正面/背面没有区别。从相机和鼠标设置光线投射然后从点方向设置光线投射有区别吗?我标准化了我的 Ray 方向,认为可能是一些奇怪的浮点问题。谢谢。将在几个小时后返回示例
-
@pailhead link
-
FWIW,当光线投射器尝试与背面相交时,它只是简单地重新排列面的顶点,这是一个微不足道的操作。
-
您正在对一个具有 300k 个面的对象执行数十次光线投射。这就是为什么它很慢。
标签: javascript three.js raycasting