3D 粒子碰撞
由於 GPU 粒子完全在 GPU 上處理,因此無法直接取得遊戲的物理世界。如果你需要讓粒子與環境產生碰撞,必須設置粒子碰撞節點。目前共有四種類型:GPUParticlesCollisionBox3D、GPUParticlesCollisionSphere3D、GPUParticlesCollisionSDF3D 以及 GPUParticlesCollisionHeightField3D。
通用屬性
通用碰撞屬性
所有碰撞節點都具有一些共同屬性,這些屬性位於屬性面板中的 GPUParticlesCollision3D 區段。
Cull Mask (剔除遮罩)屬性用來控制哪些粒子系統會受到碰撞節點的影響,依據每個系統的 可見圖層 設定。只有當粒子系統的任一可見圖層在碰撞器的剔除遮罩內啟用時,該粒子系統才會與該碰撞節點產生碰撞。
警告
目前 GPU 粒子碰撞存在 已知問題,導致剔除遮罩在 Godot 4.0 中無法正確運作。待問題修正後,本文件將會更新相關內容。
方塊碰撞
節點清單中的方塊碰撞
方塊碰撞節點外形為實心長方體,可以透過 Extents``(範圍)屬性調整其大小。範圍值代表邊長的一半,例如 ``(X=1.0, Y=1.0, Z=1.0) 就會產生一個每邊長 2 公尺的方塊。這類節點很適合用來模擬粒子需要碰撞的地板或牆面等幾何物件。
要建立方塊碰撞節點,只需在場景中新增一個子節點,然後從節點清單選擇 GPUParticlesCollisionBox3D。你可以對方塊的位置進行動畫設定,或者將其綁定到會移動的節點,以產生動態效果。
兩個粒子系統與方塊碰撞節點發生碰撞
球體碰撞
節點清單中的球體碰撞
球體碰撞節點的形狀為實心球體,其尺寸由 Radius (半徑)屬性控制。與方塊碰撞不同,球體碰撞節點始終保持球形。如果你需要分別調整寬度和高度,可以在 Node3D 區段修改 Scale (縮放)屬性。
要建立球體碰撞節點,請在場景中新增子節點,並從節點清單選擇 GPUParticlesCollisionSphere3D。你可以對球體的位置進行動畫,也可以將其綁定到會移動的節點,以實現動態效果。
兩個粒子系統與球體碰撞節點發生碰撞
高度場碰撞
節點清單中的高度場碰撞
高度場粒子碰撞非常適合用於需要與粒子互動的大型戶外區域。執行時,此節點會將範圍內且符合剔除遮罩的所有網格產生為高度場,粒子會與此高度場代表的網格發生碰撞。由於高度場是動態產生的,因此可隨攝影機移動並即時反映場景變化。你可以調整高度場密度,以平衡效能與準確度。
要建立高度場碰撞節點,請在場景中新增子節點,然後從節點清單選擇 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 碰撞與高度場碰撞類似,皆會把範圍內多個網格合併成單一碰撞體,不同的是有號距離場可以描述洞穴、隧道、懸挑等高度場無法處理的結構。不過其效能需求較高,建議用於中小型區域。
要建立 SDF 碰撞節點,請在場景中新增子節點,並從節點清單中選擇 GPUParticlesCollisionSDF3D。SDF 碰撞節點必須先經過烘焙才能對粒子產生效果。你可以在檢視區工具列中選取該節點後,點擊 Bake SDF 按鈕,並選擇儲存烘焙資料的資料夾。由於 SDF 碰撞必須在編輯器內烘焙,因此運行時無法動態更改。
SDF 粒子碰撞可實現高細節的三維碰撞形狀
SDF 碰撞節點的外形為方塊,其大小由 Extents 屬性決定。範圍值為邊長的一半,因此 (X=1.0, Y=1.0, Z=1.0) 會產生每邊 2 公尺的方塊。超出節點範圍的部分不會參與碰撞。
Resolution (解析度)屬性決定距離場的細節程度。較低的解析度會提升效能但降低準確度。若解析度太低,粒子可能會穿透場景或在碰撞時卡住,也可能完全無視較小的網格物件。
同一區域在不同解析度下的有號距離場:16(左)與 256(右)
Thickness (厚度)屬性能為通常中空的距離場增加厚度,以避免粒子高速穿透。如果發現有些粒子未與場景產生碰撞而直接穿過,請嘗試提高此屬性值。
Bake Mask (烘焙遮罩)屬性決定烘焙 SDF 時會納入哪些網格。只有那些在烘焙遮罩啟用圖層上的網格,才會影響粒子的碰撞。
疑難排解
要讓粒子碰撞生效,粒子的 可見 AABB 必須與碰撞體的 AABB 重疊。如果你已設置碰撞器但碰撞似乎沒有效果,請於 3D 編輯器上方選取 GPUParticles3D 節點,並執行 GPUParticles3D > 產生可見 AABB... 來更新可見區域。
若粒子移動速度很快且碰撞體很薄時,可能會穿透碰撞體。可以透過以下兩種方式改善:
加厚碰撞體。例如,如果你要防止粒子穿越實心地板,可以讓地板的碰撞體厚度大於其實際視覺厚度。高度場碰撞體本身就會自動處理這種狀況,因為高度場無法表現「上下重疊房間」這類結構。
提高 GPUParticles3D 節點的
Fixed FPS(固定 FPS)設定,讓碰撞檢查頻率增加。不過這會降低效能,請避免設定過高。