三.js/webgl RayCasting Sprites in Scene with Transparency or Alternatives

Three.js/webgl RayCasting Sprites in Scene with Transparency or Alternatives

我正在开发一个网页游戏,它需要选择绘制的对象,而不是简单的几何形状。为此,我使用 Three.JS 在 canvas 的场景中将它们绘制为精灵。几个月来,我一直在绞尽脑汁,试图弄清楚如何确定我的 webgl 上下文(使用 ThreeJS)中的 raycaster 光线是否与精灵的透明部分发生碰撞。我搜索并阅读了尽可能多的帖子,但我只找到了两个解决方案帖子:

var ctx =renderer.getContext("experimental-webgl", {preserveDrawingBuffer: true})
const pixel = new Uint8Array(4)
ctx.readPixels(10,30,1,1, ctx.RGBA,  ctx.UNSIGNED_BYTE,  pixel); log(pixel);

这需要使用 preserveDrawingBuffer,这会破坏我的性能,或者:

raycaster.intersectObject(scene.getObjectByName('some sprite')[0]].uv

然后使用数学魔法将 UV 坐标与图像本身进行比较,我猜是从 scene.getObjectByName('some sprite').material.map.image.src.valueOf() 加载到某个缓冲区中,然后如果匹配像素或模糊区域是透明的,那么我们就不会考虑选择的精灵。这将更加困难,因为精灵经常旋转、缩放、中心偏移等。我什至不能 100% 确定我将如何实现它。

我想知道是否还有其他方法,尤其是更 'proper' 的方法。有什么方法可以用某种网格转换精灵图像 into/supply 我的图像,然后用图像精确地绘制网格,这样光线追踪器实际上必须使用正确的物体形状而不仅仅是图像平面(精灵)?在 3D 建模程序中采用每个精灵并煞费苦心地对其边缘进行建模会更好吗?我已经尝试了 "mesh," "geometry," "image," "sprite," 等的所有组合,但没有找到解决方案。

感谢任何帮助。乞丐不能选择,但我也希望最终有动画对象,所以如果这个解决方案没有使它变得不可能,那将是额外的帮助。

谢谢

e:请参阅下面@gman 的评论。我在颜色选择系统中工作,只真正将 emissive.setHex 更改为 material.color.set(id),然后检查颜色而不是自发光。效果很好,但似乎有点慢了。将不得不看看我是否实施得很糟糕,或者我是否可以提高效率。谢谢你们!

通过额外的绘制通道,您可以将场景渲染成每个对象都有专用 material 的纹理,然后将 2D 点选取到其中

您可以创建一个基本的 material,其颜色与 this OpenGL hack 中描述的每个对象的 ID 相匹配(将其转换为 WebGL)

在绘制之前使用Scene.overrideMaterial to assign a material to all the objects and Object3D.onBeforeRender设置每个对象的颜色

会有一定的成本,但我觉得值得一试