Up to date
This page is up to date for Godot 4.2
.
If you still find outdated information, please open an issue.
遮擋剔除¶
在 3D 渲染引擎中,**遮蔽剔除**是執行隱藏幾何體移除的過程。
在本指南中,我們將學到:
什麼是遮擋剔除的優點缺點。
如何在 Godot 中設定遮擋剔除。
解決 Godot 中控制器的問題。
也參考
除了這份說明文件,你可能也會想看看 Godot Demo 專案 。
遮擋模式¶
在這個有數百個房間相鄰堆疊的範例場景中,一個動態物件(紅色球體)隱藏在明亮房間的牆後面(在門的左側):
停用遮擋剔除後,必須渲染照亮房間後方的所有房間。動態物件也必須被渲染:
啟用遮擋剔除後,只需渲染實際可見的房間。動態物件也被牆壁遮擋,因此不再需要渲染:
由於引擎要做的工作較少(需要渲染的頂點較少,繪製呼叫也較少),因此只要場景中有足夠的遮擋剔除機會,效能就會提高。這意味著遮擋剔除在室內場景中最有效,最好有許多較小的房間,而不是較少的較大房間。將此與 doc_mesh_lod 和 doc_visibility_ranges 結合起來,可以進一步提高效能效益。
備註
當使用叢集前向渲染後端時,引擎已經執行了*深度預通道*。這包括在渲染場景的實際材質之前渲染場景的僅深度版本。這用於確保每個不透明像素僅著色一次,從而顯著降低過度繪製的成本。
使用 Forward Mobile 渲染後端時可以觀察到最大的效能優勢,因為出於效能原因,它不具有深度預通道。因此,遮蔽剔除將主動減少渲染後端的著色過度繪製。
儘管如此,即使使用深度預通道,複雜 3D 場景中的遮蔽剔除仍然具有明顯的優勢。然而,在遮蔽剔除機會很少的場景中,遮蔽剔除可能不值得增加設定和 CPU 使用率。
遮擋模式¶
備註
「遮擋物」是指遮擋視線的形狀,而「被遮擋物」是指被隱藏的物體。
在 Godot 中,遮蔽剔除的工作原理是將場景的遮蔽幾何圖形光柵化到 CPU 上的低解析度緩衝區。這是使用軟體光線追蹤庫 Embree 完成的。
然後,引擎使用此低解析度緩衝區來測試遮擋物的 AABB(軸對齊邊界框)與遮擋物形狀。被遮擋物的 AABB(軸對齊邊界框)必須被要剔除的遮擋物形狀「完全遮擋」。
因此,較小的物件比較大的物件更有可能被有效剔除。較大的遮蔽物(例如牆壁)也往往比較小的遮擋物(例如裝飾道具)更有效。
遮擋模式¶
使用遮蔽剔除的第一步是啟用 渲染 > **遮蔽剔除 > 使用遮蔽剔除 專案設定。 (確保在“專案設定”對話框中啟用“高級”開關才能看到它。)
專案設定會立即應用,無需重啟編輯器。
啟用專案設定後,您仍然需要建立一些遮蔽物。出於性能原因,引擎不會自動使用所有可見幾何體作為遮擋剔除的基礎。相反,引擎需要簡化的場景表示,僅需要烘焙靜態物件。
有兩種方法可以為伺服器匯出專案:
自動烘焙遮擋物(建議)¶
備註
目前*遮擋器*烘焙過程中僅考慮 MeshInstance3D 節點。烘焙遮蔽物時,**不**考慮 MultiMeshInstance3D、GPUParticles3D、CPUParticles3D 和 CSG 節點。如果您希望將它們視為遮擋物,則必須手動建立(大致)以配對其幾何形狀的遮擋物形狀。
此限制不適用於*被遮蔽者*。任何繼承自 GeometryInstance3D 的節點型別都可以被遮蔽。
啟用上述遮擋剔除專案設定後,將 OcclusionrInstance3D 節點新增至包含 3D 關卡的場景。
選擇 OccluderInstance3D 節點,然後點擊 3D 編輯器視窗頂部的 Bake Occlusionrs。烘焙後,OccluderInstance3D 節點將包含一個 Occluder3D 資源,用於儲存關卡幾何的簡化版本。此遮擋物幾何體在 3D 視圖中顯示為紫色線框線(只要在 透視 選單中啟用 查看 Gizmos)。然後使用此幾何體為靜態和動態被遮蔽物提供遮蔽剔除。
烘焙後,您可能會注意到動態物件(例如玩家、敵人等)包含在烘焙的網格中。為了防止這種情況發生,請在 OccluderInstance3D 上設定 Bake > Cull Mask 屬性,以排除某些視覺層的烘焙。
例如,您可以停用剔除蒙版上的第 2 層,然後將動態物件的 MeshInstance3D 節點配置為位於視覺層 2(而非第 1 層)上。為此,請選擇相關的MeshInstance3D 節點,然後在**VisualInstance3D > Layers** 屬性上,取消選取圖層1,然後選取圖層2。配置剔除遮罩和圖層後,依照上述流程再次烘焙遮擋物。
多預留位置¶
這種方法更適合專門的用例,例如為 MultiMeshInstance3D 設定或 CSG 節點建立遮蔽(由於上述限制)。
啟用上述遮擋剔除專案設定後,將 OcclusionrInstance3D 節點新增至包含 3D 關卡的場景。選擇 OccluderInstance3D 節點,然後選擇要新增至 Occlusionr 屬性中的遮擋器型別:
QuadOcclusionr3D(單平面)
BoxOcclusionr3D(長方體)
SphereOcclusionr3D(球狀遮擋器)
PolygonOccluder3D(具有任意數量點的 2D 多邊形)
還有 ArrayOccluder3D,其點無法在編輯器中修改,但可用於從腳本進行程式產生。
遮擋模式¶
您可以啟用除錯繪製模式來預覽遮擋剔除實際「看到」的內容。在3D 編輯器視窗的左上角,按一下**透視** 按鈕(或**正交**,取決於您目前的相機模式),然後選擇**顯示進階... > 遮擋剔除緩衝區**。這將顯示引擎用於遮蔽剔除的低解析度緩衝區。
在同一選單中,您還可以啟用**查看資訊**和**查看影格時間**來查看右下角的繪製呼叫和渲染像素(頂點+索引)的數量,以及右上角渲染的每秒影格數。
如果在顯示此資訊時在專案設定中切換遮擋剔除,您可以看到遮擋剔除對場景效能的改善程度。請注意,性能優勢在很大程度上取決於 3D 編輯器相機的視角,因為遮擋剔除僅在相機前面存在遮擋物時才有效。
若要在運作時切換遮蔽剔除,請在根視窗上設定“use_occlusion_culling”,如下所示:
get_tree().root.use_occlusion_culling = true
在運作時切換遮擋剔除對於比較正在運作的專案的效能很有用。
效能¶
在建構關卡時考慮遮擋¶
這就是很多專業人士的秘密。好的關卡設計並不只是滿足遊戲性的需求,也應該同時考慮遮擋。
對於室內環境,新增不透明的牆壁以定期“打破”視線,並確保一次不會看到太多場景。
對於大型開放場景,請盡可能使用類似金字塔的結構來確定地形的標高。與任何其他地形形狀相比,這提供了最大的剔除機會。
避免在遊戲過程中移動 OcclusionInstance3D 節點¶
這包括移動 OccluderInstance3D 節點的父節點,因為這將導致節點本身在全域空間中移動,因此需要重建 BVH(邊界體積層次結構)。
切換 OccluderInstance3D 的可見性(或其父級之一的可見性)並不那麼昂貴,因為更新只需要發生一次(而不是連續發生)。
例如,如果您有一扇滑動門或旋轉門,則可以使 OccluderInstance3D 節點不是門本身的子節點(以便遮擋器永遠不會移動),但您可以在門開始打開後隱藏 OccluderInstance3D 可見性。一旦門完全關閉,您就可以重新顯示 OcclusionrInstance3D。
如果您絕對必須在遊戲過程中移動 OcclusionrInstance3D 節點,請為其使用原始 Occlusionr3D 形狀,而不是複雜的烘焙形狀。
使用盡可能簡單的遮擋物形狀¶
如果您發現複雜 3D 場景中效能低或卡頓,則可能表示 CPU因渲染詳細遮蔽物而過載。選擇 OccluderInstance3D 節點,增加 Bake > Simplification 屬性,然後再次烘焙遮蔽物。
請記得保持簡化值合理。對於關卡幾何形狀來說太高的值可能會導致發生不正確的遮蔽剔除,如 我的被遮蔽者在不該被剔除的情況下被剔除 所示。
如果這仍然沒有導致足夠低的 CPU 使用率,您可以嘗試調整 渲染 > 遮擋剔除 > BVH 建構品質 專案設定和/或減少 渲染 > 遮擋剔除 > 每線程遮擋光線。您需要在「專案設定」對話方塊中啟用「進階」開關才能查看這些設定。
疑難排解¶
我的被遮蔽者在該被剔除的時候卻沒有被剔除¶
在遮擋器一側:
首先,仔細檢查 OccluderInstance3D 中的 Bake > Cull Mask 屬性是否設定為允許烘焙您想要的網格。 MeshInstance3D 節點的可見性層必須存在於剔除遮罩中,網格才能包含在烘焙中。
另請注意,遮擋器烘焙僅考慮具有“不透明”材質的網格。表面將*透明*材質將**不**包含在烘焙中,即使應用在其上的紋理是完全不透明的。
最後,請記住,烘焙遮擋物時**不**考慮 MultiMeshInstance3D、GPUParticles3D、CPUParticles3D 和 CSG 節點。作為解決方法,您可以手動為這些節點新增 OccluderInstance3D 節點。
在被遮蔽方:
確保**額外剔除餘裕**設定為盡可能低(通常應為``0.0``),並且在物件的 GeometryInstance3D 部分中停用**忽略遮蔽剔除**。
另外,檢查 AABB 的大小(選擇節點時以橘色框表示)。此軸對齊的邊界框必須被遮擋物形狀*完全*遮擋,才能隱藏被遮擋物。
我的被遮蔽者在不該被剔除的情況下被剔除¶
造成這種情況的最可能的原因是,遮擋物烘焙中包含的物件在烘焙遮擋物後已被移動。例如,當行動關卡幾何圖形或重新排列其佈局時,可能會發生這種情況。要解決此問題,請選擇 OccluderInstance3D 節點並再次烘焙遮擋物。
這種情況也可能發生,因為動態物件包含在烘焙中,儘管它們不應該包含在內。使用遮蔽剔除除錯繪製模式 <doc_occlusion_culling_preview>` 尋找不應出現的遮蔽形狀,然後相應調整烘焙剔除蒙版 <doc_occlusion_culling_baking>`。
最後一個可能的原因是在遮擋器烘焙過程中過於激進的網格簡化。選擇 OccluderInstance3D 節點,減少 Bake > Simplification 屬性,然後再次烘焙遮蔽物。
作為最後的手段,您可以啟用被遮蔽者的 忽略遮蔽剔除 屬性。這將抵消該物件的遮蔽剔除的效能改進,但對於永遠不會被剔除的物件(例如第一人稱視圖模型)執行此操作是有意義的。