我已经为正在开发的体素游戏添加了粒子系统。此刻,所有物理过程都在CPU上完成,而且非常慢(我的CPU挣扎着2000个粒子)。
对于每个粒子,我确定理论上可以碰撞的体素的范围(基于粒子的位置和速度以及经过的时间),然后检查与该范围内所有体素的碰撞,并使用最近的碰撞。
为了提高性能,我正在研究是否可以使用计算着色器执行物理操作。
如果我将体素世界转换为位数组并在SSBO中抛弃,则计算着色器将具有执行碰撞检测所需的所有几何信息。但是...
我为CPU编写的冲突检测代码在GPU上根本没有效率。有很多分支/循环的方法。在计算着色器上,是否有一种使粒子与体素网格碰撞的有效方法?
答案 0 :(得分:1)
为简化起见,请将粒子视为点状对象,仅具有位置P和速度V单位/刻度。除了精确计算粒子将触摸哪个体素外,对粒子运动的第一近似方法可能只是检查P + V是否被固体体素占据(使用3D采样器),并将V设置为零(或为零)。本身)(如果是这种情况),否则将P乘V。这些条件运算可以通过整数算术有效完成,不需要分支。
如果这种近似过于粗糙,因为V通常是多个体素单位长,并且由于您的体素几何形状足够精细以至于可能导致粒子穿过实体壁,因此您可以在着色器中简单地重复上述操作N次。 ,使用V / N而不是V,其中N应该是最小常数常量,使大部分时间停止剪切。着色器编译器将展开恒定长度的For循环,因此您仍然不需要真正的分支。
现在,使用此算法,粒子的行为将是一旦它们到达障碍物就停止所有(或大多数)运动。如果它们受到重力的影响(最好在着色器内完成),它们将直线下降,但仅在失去垂直速度之后才会下降。如果他们到达地板,他们将留在原处。
如果您希望粒子在水平表面上滑动而不是停在它们着陆的地方,并且在碰壁时仍保持垂直动量,则可以将V分为水平和垂直分量,并对两个分量分别执行上述步骤组件。
您还可以选择将V的所有三个坐标分开,因此以对角水平运动击中墙壁的粒子将跟随该墙壁而不是垂直下落,但是与两个分量相比,性能损失可能会超过收益。