Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

3D粒子碰撞

粒子碰撞

由于 GPU 粒子完全在 GPU 中处理,所以它们无法访问游戏中的物理世界。如果你需要粒子与环境碰撞,你必须设置粒子碰撞节点。共有四种: GPUParticlesCollisionBox3DGPUParticlesCollisionSphere3DGPUParticlesCollisionSDF3DGPUParticlesCollisionHeightField3D

Common properties

常用粒子碰撞属性

常用碰撞属性

有一些属性你可以在所有碰撞节点中找到。它们位于检查器的 GPUParticlesCollision3D 区域中。

Cull Mask 属性决定哪个粒子系统被基于每个 系统的 :ref:`visibility layers <class_VisualInstance3D>`的碰撞节点影响。当且仅当至少一个 系统的 visibility layers 在碰撞者的 cull mask 中启用时,粒子系统与碰撞节点碰撞。

警告

There is a known issue with GPU particle collision that prevent the cull mask from working properly in Godot 4.0. We will update the documentation as soon as it is fixed.

盒型碰撞

粒子碰撞盒

节点列表中的盒型碰撞

盒子碰撞节点的形状像一个实心的矩形盒子。你可以使用 Extents 属性控制它们的大小。盒子范围始终测量其边界边的一半,因此值 (X=1.0,Y=1.0,Z=1.0) 将创建一个每边宽 2 米的盒子。箱体碰撞节点可用于模拟粒子应碰撞的地板和墙壁几何形状。

要创建盒型碰撞节点,请在场景中添加一个新的子节点,并在可选节点列表中选择 GPU3D粒子碰撞盒``GPUParticlesCollisionBox3D``。如果想要更多动态效果,你可以将节点位置动画化,或将它附加到其他移动节点上。

粒子系统的盒型碰撞

两个粒子系统与盒型碰撞节点碰撞

球形碰撞

粒子碰撞球

节点列表中的球面碰撞

球形碰撞节点的形状类似于一个实心球体。半径 Radius``属性控制球体的大小。盒型碰撞节点不一定是完美的立方体,但是球形碰撞节点始终是球体。如果要独立于高度设置宽度,则必须更改 3D节点``Node3D``部件中的缩放``Scale 属性。

要 创建 球面 碰撞 节点, 向你的 场景添加一个新子节点并从可选节点 列表中选中 GPUParticlesCollisionSphere3D。可以改变球面的位置或将其附加到移动的节点以使效果更加动态。

粒子系统中的球面碰撞

两个粒子系统与球型碰撞节点碰撞

高度场碰撞

粒子碰撞高度场

节点列表中的高度场碰撞

高度场粒子碰撞对于参与粒子碰撞的大型室外区域非常有用。在运行时,节点会根据范围内的所有不被遮罩剔除的网格,创建一个高度场。粒子会与该高度场所代表的网格发生碰撞。由于高度场是动态生成的,因此它可以跟随玩家的摄像机移动,并对关卡中的变化做出反应。如果改变高度场的密度参数,性能也会有很大的调整。

要创建高度场碰撞节点,请在场景中添加一个新的子节点,然后从可用节点列表中选择GPU粒子碰撞高度场3D GPUParticlesCollisionHeightField3D

高度场碰撞节点的形状像一个盒子。外延``Extents``属性控制其大小。外延属性总是测量其边界边长的一半,因此``(X=1.0,Y=1.0,Z=1.0)``的值会创建一个边长 2 米的盒子。在创建高度场时,会忽略外延以外的任何内容。

分辨率 ``Resolution``属性控制高度场的精确程度。分辨率越低,执行速度越快,但精确度会受到影响。如果高度场分辨率太低,在碰撞事件中,粒子可能会穿透场景中的几何体或卡在空中。它们还可能完全忽略一些较小的网格。

高度场分辨率

在低分辨率下,高度场碰撞会错过一些更精细的细节(左图)

更新模式``Update Mode``属性可以控制何时根据其范围内的网格重新创建高度场。将其设置为移动时``When Moved`` 可使其仅在移动时刷新。这种模式性能良好,适合不经常变化的静态场景。如果需要粒子与位置经常变化的动态物体碰撞,可以选择 "Always"(始终),使其每帧都刷新。这样做会影响性能,建议只在必要时使用。

备注

重要的是要记住,当更新模式``Update Mode`` 设置为 移动时``When Moved`` 时,是*高度场节点*的移动触发了更新。当场内的某个网格移动时,高度场不会更新。

启用跟随摄像机``Follow Camera Enabled``属性后,高度场将跟随当前摄像机。只要摄像机移动,它就会更新。该属性可用于确保玩家周围始终存在粒子碰撞,同时不会在视线之外或太远的区域浪费性能。

带符号距离场(SDF)碰撞

粒子碰撞带符号距离场(SDF)

节点列表中的 SDF 碰撞

SDF 碰撞节点会创建一个粒子可以碰撞的带符号距离场`signed distance field <https://www.reddit.com/r/explainlikeimfive/comments/k2zbos/eli5_what_are_distance_fields_in_graphics>`_。SDF 碰撞与高度场碰撞类似,都是将其范围内的多个网格转化单一粒子碰撞体积。主要区别在于带符号的距离场可以表示孔洞、隧道和悬臂,而这是高度场无法做到的。与高度场相比,带符号距离场的性能开销较大,因此最适合中小型环境。

要创建 SDF 碰撞节点,请在场景中添加一个新的子节点,然后从可用节点列表中选择GPU粒子碰撞SDF3D GPUParticlesCollisionSDF3D。SDF 碰撞节点必须经过烘焙才能对关卡中的粒子产生影响。为此,请在选中 SDF 碰撞节点时单击视口工具栏上的 "烘焙 SDF "按钮,并选择一个目录来存储烘焙数据。由于 SDF 碰撞需要在编辑器中烘焙,因此它是静态的,无法在运行时更改。

SDF 粒子碰撞

SDF 粒子碰撞允许实现非常精细的三维碰撞形状

SDF 碰撞节点的形状就像一个盒子。外延``Extents ``属性控制其大小。外延属性总是测量其边界边长的一半,因此``(X=1.0,Y=1.0,Z=1.0)``的值会创建一个边长2米的盒子。节点范围以外的任何东西都将被忽略,不会发生碰撞。

分辨率 ``Resolution``属性控制距离场的精细程度。分辨率越低,执行速度越快,但精确度会降低。如果分辨率太低,在碰撞事件中,粒子可能会穿透场景中的几何体或卡在空中。它们还可能完全忽略一些较小的网格。

分辨率比较

不同分辨率的带符号距离场覆盖会覆盖一片相同区域:16(左)和 256(右)

厚度``Thickness``属性赋予距离场(通常内部是空心的)一定的厚度,以防止粒子高速穿透。如果发现有些粒子没有与场景中的几何体发生碰撞,而是直接穿透了它们,请尝试将此属性设置为更高的值。

烘焙遮罩``Bake Mask``属性控制烘焙带符号距离场时将考虑哪些网格。只有在烘焙遮罩的活动图层上渲染的网格才会参与粒子碰撞。

故障排除

For particle collision to work, the particle's visibility AABB must overlap with the collider's AABB. If collisions appear to be not working despite colliders being set up, generate an updated visibility AABB by selecting the GPUParticles3D node and choosing GPUParticles3D > Generate Visibility AABB… at the top of the 3D editor viewport.

If the particles move fast and colliders are thin. There are two solutions for this:

  • Make the colliders thicker. For instance, if particles cannot get below a solid floor, you could make the collider representing the floor thicker than its actual visual representation. The heightfield collider automatically handles this by design, as heightfields cannot represent "room over room" collision.

  • Increased Fixed FPS in the GPUParticles3D node, which will perform collision checks more often. This comes at a performance cost, so avoid setting this too high.