我在WebGL中有一个动态表面,它在顶点着色器中设置动画。我希望其他对象与此表面交互(例如,骑在动态地形上的对象)。最好的方法是什么?所有这些计算都应该在CPU上完成吗?有没有办法在GPU上计算这些东西?
基本上,我想要的是顶点着色器,可以访问其他(已经变换过的)顶点 - 这将是完美的。
答案 0 :(得分:1)
不幸的是,我不确定你能在着色器上做到这一点。我能想到的最接近的是传递第二组属性,但是顶点数必须相同,并且你只能验证一个模型的一个顶点对一个具有相同索引的顶点。另一个模型(因为你没有办法迭代它们)。不知何故,我认为这不是你想要的。
最好的办法是在CPU上实现这些类型的东西(例如碰撞检测)。它在JavaScript中非常慢,你需要长时间地思考用于场景的最佳算法,但这是我能想到的唯一可以实际工作的东西。
一个良好的开端是使用空间分区(示例:octree,BSP -- binary space partitioning -- tree)。我还没有做过任何基准测试,但是我有一个预感BSP树在大多数JavaScript场景中比八叉树更有效。整体检查通常较少,并且递归可能更少。此外,BSP树提供了几乎独特的能力,可以相对于空间中的任意点从后到前或从前到后处理几何体,而无需对几何体进行不断的排序和重新排序。 BSP树的缺点(以及更小但仍然非常重要的八叉树)是它们的几何必须保持静态。也就是说,动态移动单个三角形对这些树的效果不佳,因为几何 必须重新排序。如果您的网格动画相对简单,轻微且可预测(例如在风中飘扬的旗帜),我认为空间分区的静态性质不是特别麻烦的问题,但如果它们更复杂(例如摇摇欲坠)那些类型的空间分区可能根本不适合你。
更新:如果你的模型由部分静态和部分动态三角形组成,例如风车(其塔是静态的,鳍是动态的),那么你可以对静态部分使用空间分区,这样如果你只采取动态三角形的不必要的性能命中,并为那些没有移动太多的三角形获得空间分区的好处。
更新:实际上,有一种方法可以“有点”至少部分地在着色器上执行此操作。具体来说,参考您在动态地形上骑行的对象的示例,您可以将该动态地形渲染到屏幕外的帧缓冲区,然后将对象的位置绘制到同一帧缓冲区上,并使用readpixels()读取地形的高度那个位置。这只适用于高度贴图,并且每次地形变化时(如果有的话)显然需要更新帧缓冲。但是,这是一种相对简单的方法,可以看到对象在动态地形上的位置有多高,而无需在CPU上进行地形生成。然而,这不是真正的碰撞检测,并且该物体仍然会受到其他问题的影响(例如在地形上或在地形下方有一个轮子而在半空中有一个轮子)。您可以解决这些问题,但解决方案将是非常重要的,可能涉及对帧缓冲区数据的多次检查。