光线投射以与已被顶点着色器置换的对象相交

时间:2019-05-07 21:03:57

标签: three.js

假设我有一个垂直列表,这些列表是从PlaneBufferGeometryShaderMaterial创建的。网格垂直分布并均匀分布。

列表将具有两种状态:

  1. 按原样显示网格
  2. 显示由顶点着色器转换为相同任意值的每个对象的顶点的网格,例如z = -50。这样会提供缩小效果,用户可以滚动浏览此列表(在代码中,我们通过移动相机y的位置来实现此目的)

在我的应用中,我试图使鼠标悬停事件在第二种状态下起作用,但这很棘手,因为GPU会转换顶点,因此更新后的顶点不会反映在JS端的属性中。

*请注意,我已经研究过GPU选择,并且不希望使用它,因为我认为应该有一种更简单的方法来实现渲染目标

尝试的解决方案

我当前的方法是在处于第二种状态时手动更改每个平面的boundingBox,例如:

var box = new THREE.Box3().setFromObject(plane);
box.min.z = -50;
box.max.z = -50;

plane.geometry.boundingBox = box;

计算后,将boundingSphere的中心更改为与z相同的-50位置。

之所以采用这种方法,是因为我查看了THREE.js的RaycasterMesh代码,似乎他们检查了boundingSphere和boundingBox是否存在对象交集。因此,我认为如果修改它们两者以反映GPU所做的转换,光线投射器将可以正常工作,但对我而言似乎并不起作用。

有关raycaster的代码在这里:

// mouse being vec2 of normalized coordinates and camera being a perspective camera
raycaster.setFromCamera( mouse, camera );
const intersects = raycaster.intersectObjects( planes );

可能的理论

关于这种方法,我唯一能想到的就是我可能不是在投影鼠标坐标系吗?由于现在所有对象都位于平面z = -50上,因此我需要将这些鼠标坐标投影到该平面上吗?

1 个答案:

答案 0 :(得分:0)

受@ prisoner849发布的the link的启发,我找到了一个可行的解决方案,可以创建与场景中平面数量相等的其他透明平面。在这些平面中,我将z的位置设置为-50,并在状态2下与它们相交。

有点hacky,但现在可以使用。