【问题标题】:Three.js Ray ignore transparent pixelsThree.js Ray 忽略透明像素
【发布时间】:2014-10-25 05:14:56
【问题描述】:

我有一些 Vector3ds,其中包含使用透明 png 的平面几何图形,因为它们是材料。

我遇到的麻烦是 Raycaster 正在拾取整个对象,因此在材质附近单击足以激活相应的功能。

是否可以对光线投射器隐藏网格的透明部分?

在亚历克斯的帮助下,我已经了解了该物体的实际意义。

我现在如何将其转换为图像上的像素,以测试透明度?

【问题讨论】:

  • 你能测试一下交叉点的像素值吗?
  • 嗯,也许吧。我的 raycaster var intersects = ray.intersectObjects(targetList, true);正在测试大量对象,我如何检查它找到的实际像素!?
  • 您需要将反射点与图像在空间中的位置和尺寸相关联,然后将此相对点转换为图像的相应像素。如果像素是透明的,那么您可以丢弃阳性结果。请记住,此测试必须考虑图像的 X、Y 和 Z 旋转。
  • 好的,我正在努力实现这个概念。关于实际代码而不是高级视图的任何想法?

标签: javascript 3d three.js


【解决方案1】:

我不熟悉Three.js,但online documentation 向我暗示,Raycast 算法是基于对象在空间中的分布而不是它们的组成来计算的。在这方面,我认为没有任何具体的方法可以通知 Raycast 我们只希望测试不透明的像素。

我在想,首先,使用Three.jsRaycast.intersectObjects(pObjects, pRecursive) 来分析您的哪些对象与光线的空间范围广泛碰撞。过滤对象后,您需要执行特定测试以确定光线是否与不透明像素发生碰撞。

执行此操作的一种简单方法是获取我们保证与射线发生碰撞的物体,并确定射线穿过物体时的中心位置。 (这将增加不复杂性,具体取决于您的对象是否可以缩放,或者您的对象/光线是否可以旋转。)可以使用三角学找到光线在 3D 空间中的交点的绝对位置,这需要考虑对于您的射线的nearfar 值。

通过了解图像的位置和尺寸,您可以将 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)。您可以使用它来确定光线投射是否与您的对象成功碰撞。

【讨论】:

  • 好的,这真的很有帮助.. 将再次尝试使用它。谢谢!
猜你喜欢
  • 2015-12-07
  • 2023-01-17
  • 1970-01-01
  • 1970-01-01
  • 2014-01-14
  • 2011-03-22
  • 1970-01-01
  • 2018-08-21
  • 1970-01-01
相关资源
最近更新 更多