javascript - Three.js 检测对象何时被部分和完全遮挡

标签 javascript three.js 3d occlusion occlusion-culling

我正在尝试检测 Three.js 中的对象何时被部分和完全遮挡(隐藏在后面)另一个对象。

我目前的简单解决方案是将一条光线转换到物体的中心:

function getScreenPos(object) {
  var pos = object.position.clone();
  camera.updateMatrixWorld();
  pos.project(camera);
  return new THREE.Vector2(pos.x, pos.y);
}

function isOccluded(object) {
  raycaster.setFromCamera(getScreenPos(object), camera);
  var intersects = raycaster.intersectObjects(scene.children);
  if (intersects[0] && intersects[0].object === object) {
    return false;
  } else {
    return true;
  }
}

但是它不考虑对象的尺寸(宽度、高度、深度)。

没有被遮挡(因为物体中心不在后面) Object not occluded

被遮挡(因为物体中心在后面) Object occluded

查看工作演示:

https://jsfiddle.net/kmturley/nb9f5gho/57/

目前认为我可以计算对象框的大小,并为框的每个 Angular 转换光线。但这可能还是有点太简单了:

var box = new THREE.Box3().setFromObject(object);
var size = box.getSize();

我想找到一种更稳健的方法,它可以给出部分遮挡完全遮挡 bool 值,甚至可能是遮挡百分比

最佳答案

搜索 Stack Overflow 和 Three.js 示例以获取“GPU 挑选”。这个概念可以分解为三个基本步骤:

  1. 将每个形状的 Material 更改为独特的平面(MeshBasicMaterial)颜色。
  2. 使用独特的 Material 渲染场景。
  3. 读取渲染帧的像素以收集颜色信息。

您的场景允许您注意一些事项。

  1. 只为您正在测试的形状提供独特的颜色——其他一切都可以是黑色。
  2. 您不需要渲染整个场景来测试一个形状。您可以调整视口(viewport)以仅渲染相关形状周围的区域。
  3. 因为您只为测试部分提供了一种颜色,其余数据应该为零,从而更容易找到与您的独特颜色匹配的像素。

现在您有了像素数据,您可以确定以下内容:

  • 如果没有像素与独特的颜色相匹配,则该形状被完全遮挡。
  • 如果某些像素匹配独特的颜色,则形状至少部分可见。

第二个项目符号表示该形状“至少部分”可见。这是因为您无法使用当前拥有的信息测试完整的可见性。

会做的(其他人可能有更好的解决方案)是第二次渲染相同的视口(viewport),但只有测试形状可见,即相当于完全可见的部分。掌握了这些信息后,将像素与第一次渲染进行比较。如果两者具有相同数量(可能在公差范围内)的独特颜色像素,那么您可以说该部分完全可见/未被遮挡。

关于javascript - Three.js 检测对象何时被部分和完全遮挡,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59978782/

相关文章:

camera - 如何在 THREE.JS 中将一个物体放在相机前面?

c++ - 无法识别 glMatrixMode() 或 GL_PROJECTION 并提供所有需要的库

javascript - 模型使用 MeshBasicMaterial 但不使用 MeshPhongMaterial 进行渲染

c# - WPF 3D 动态纹理

javascript - YUIDocs 中类和模块的文档

javascript - radio 隐藏。改为显示 div 类。单击 div 选择链接的 radio

javascript - 使用动态 radio 显示/隐藏 div 不起作用

javascript - Three.js 对象移动到目标

javascript - 变量更改回调

javascript - jQuery ui 组合框添加多个搜索查询