我有一些包含平面几何的Vector3ds,它们使用透明png作为它们的材质。
我的问题是Raycaster会选中整个对象,所以在材质附近点击就足以激活相应的功能。
有没有可能从射线跟踪器中隐藏网格的透明部分?
在Alex的帮助下,我已经得到了物体上的实际点。
现在如何将其转换为图像上的像素,以测试透明度?
我有一些包含平面几何的Vector3ds,它们使用透明png作为它们的材质。
我的问题是Raycaster会选中整个对象,所以在材质附近点击就足以激活相应的功能。
有没有可能从射线跟踪器中隐藏网格的透明部分?
在Alex的帮助下,我已经得到了物体上的实际点。
现在如何将其转换为图像上的像素,以测试透明度?
我不熟悉 Three.js
,但是在线文档向我表明,Raycast算法是基于空间中物体的分布而不是它们的组成进行计算的。在这方面,我认为没有特定的方法可以“通知” Raycast,我们仅希望测试不透明像素。
我考虑首先使用Three.js
中的 Raycast.intersectObjects(pObjects, pRecursive)
来分析哪些对象与射线的空间范围广泛碰撞。一旦对象被过滤,您需要执行特定的测试来确定射线是否与不透明像素发生碰撞。
一个简单的方法是取我们保证与射线相撞的物体,并确定射线穿过该物体时的中心位置。(这将变得更加复杂,具体取决于对象是否可以缩放,或者对象/射线是否可以旋转。)可以使用三角函数找到射线在3D空间中的交点的绝对位置,这将需要考虑您的射线的near
和far
值。
通过了解图像的位置和尺寸,您可以将射线投射的坐标在您的3D世界中转换为相对于您使用的图像的离散2D坐标。
例如,想象一个简单的2D案例。如果您有一个坐落在原点上的50px²图像,并且射线与图像在位置(25,25)相交,则可以使用此信息索引像素数据数组并测试像素的alpha值。由于PNG图像数据存储RGBA数据,因此您正在查看每个像素四个字节。因此,您需要一个实现类似于下面示例的内容,因为图像数据是连续存储的。
byte lPixelRed = bitmap.getData()[(X + Y*bitmap.getWidth())*4];
byte lPixelGreen = bitmap.getData()[(X + Y*bitmap.getWidth())*4 + 1];
byte lPixelBlue = bitmap.getData()[(X + Y*bitmap.getWidth())*4 + 2];
byte lPixelAlpha = bitmap.getData()[(X + Y*bitmap.getWidth())*4 + 3];
一旦找到像素数据的区域,您可以测试alpha字节以确定它们是不透明的(0xFF)还是透明的(0x00)。这可以用来确定raycast是否已成功与您的对象碰撞。