Up to date
This page is up to date for Godot 4.3.
If you still find outdated information, please open an issue.
對其他架構重複相同的過程。
這個頁面是對 Godot 4 內部算繪器設計的高階概述。不適用於舊版本的 Godot。
這個頁面的目標是記述最符合 :ref:`Godot 設計理念 <doc_best_practices_for_engine_contributors>`的設計決策,為新的算繪貢獻者提供入手點。
如果你有關於內部算繪的問題在此未得到解答,歡迎在 Godot 貢獻者聊天 <https://chat.godotengine.org/channel/rendering>`__的 ``#rendering` 頻道中進行提問。
備註
如果你在理解這個頁面上的概念時遇到了困難,建議先過一遍 LearnOpenGL 等 OpenGL 教學。
要想高效使用現代低階 API(Vulkan/Direct3D 12)需要具備中等水平的更高階 API(OpenGL/Direct3D 11)知識。值得慶倖的是,貢獻者很少需要直接使用底層 API。Godot 的算繪器完全基於 OpenGL 和 RenderingDevice,後者是我們對 Vulkan/Direct3D 12 的抽象。
算繪
Forward+
這是一種前向算繪器,使用*集群*方法實作光照。
集群光照使用計算著色器將燈光按照 3D 視錐柵格進行群組。然後在算繪時,像素就能夠查詢影響某個柵格單元的有哪些燈光,僅對影響該像素的燈光進行光照計算。
這種方法能夠大幅提升在桌面硬體上的算繪性能,但是在移動端會略為低效。
移動裝置
這是使用傳統單階段光照方法的向前算繪器。
針對移動平臺設計,但是也能夠在桌面平臺運作。這種算繪方法針對移動 GPU 進行了優化。移動 GPU 的架構與桌面 GPU 有很大的區別,因為需要考慮電池使用、散熱、讀寫資料時的總體頻寬限制等約束。對計算著色器的支援也非常有限,甚至完全不支援。因此,移動算繪器單純使用基於光柵的著色器(片段/頂點)。
與桌面 GPU 不同,移動 GPU 執行的是*基於圖塊的算繪*。整個圖像不是作為整體算繪的,而是會細分為較小的圖塊,適合放置到移動 GPU 更快的內部儲存中。圖塊單獨算繪後就會寫入到目標紋理上。圖形驅動會自動進行這一步操作。
問題在於,這種做法會在我們的傳統方法中造成瓶頸。對於桌面算繪,我們會先算繪所有不透明的幾何體,然後處理背景,再處理透明的幾何體,最後進行後期處理。每個步驟都需要將目前的結果讀進圖塊記憶體,執行對應的運算後再寫出。我們需要等待所有圖塊都完成後才能繼續下一個階段。
The first important change in the mobile renderer is that the mobile renderer does not use the RGBA16F texture formats that the desktop renderer does. Instead, it is using an R10G10B10A2 UNORM texture format. This halves the bandwidth required and has further improvements as mobile hardware often further optimizes for 32-bit formats. The tradeoff is that the mobile renderer has limited HDR capabilities due to the reduced precision and maximum values in the color data.
第二個重要更改就是盡可能使用子階段(sub-pass)。子階段能夠按照圖塊來執行算繪步驟,節省每個算繪階段之間讀寫圖塊帶來的開銷。使用子階段帶來的限制是無法讀取相鄰像素,因為我們只能針對單一圖塊進行處理。
子階段的這一限制導致我們無法高效實作輝光、景深等功能。類似地,如果需要讀取螢幕紋理或者深度紋理,我們就必須將算繪結果完全寫出,限制對子階段的使用。啟用這種功能時,會混用子階段和正常階段,因此會帶來明顯的性能損失。
在桌面平臺,使用子階段對性能不會有任何影響。但對於簡單的場景而言,這種算繪方法仍然比集群 Forward 要高效,因為複雜度和頻寬佔用都相對較低。這種情況在低端 GPU、集成顯卡、VR 應用中尤為明顯。
由於關注點在於低端裝置,這種算繪方法並不提供 SDFGI、:ref:`doc_volumetric_fog`等高端算繪功能。部分後期處理效果也不可用。
編譯
備註
這是使用 OpenGL 驅動時唯一可用的算繪方法。這種算繪方法在使用 Vulkan 和 Direct3D 12 時不可用。
這是傳統的(非集群)向前算繪器,針對的是不支援 Vulkan 的老舊 GPU,但在較新的硬體上仍然能夠非常高效地工作。確切地說,這種算繪器針對較舊、較低端的移動裝置進行了優化。不過,很多優化也適用於較舊、較低端的桌面裝置,因此也是不錯的選擇。
與“移動”算繪器類似,“相容”算繪器在進行 3D 算繪時使用的也是 R10G10B10A2 UNORM 紋理。與移動算繪器不同的是,顏色都經過了色調對應,以 sRGB 格式儲存,因此不支援 HDR。這樣就不需要再執行色調對應階段,能夠使用低位紋理,不會產生明顯的條帶。
“相容”算繪器在繪製帶光照的物件時使用的傳統的單階段向前方法,但是帶陰影的燈光會使用多階段方法。確切地說,第一個階段能夠繪製多個不帶陰影的燈光以及一個帶陰影的 DirectionalLight3D。後續的各個階段中,最多只能分別繪製一個帶陰影的 OmniLight3D、 SpotLight3D、 DirectionalLight3D。帶陰影的燈光對場景的影響與不帶陰影的燈光不同,因為光照的混合使用的是 sRGB 空間而不是線性空間。這種區別會影響場景的外觀,針對“相容”算繪器設計場景時需要謹記於心。
由於關注點在於低端裝置,這種算繪方法並不提供高端算繪功能(與 Forward 移動相比更少)。大多數後期處理效果不可用。
為什麼不使用延遲算繪?
向前算繪通常能夠在性能和靈活性之間達到更好的平衡,尤其是在燈光使用了集群方法的情況下。延遲算繪雖然在某些情況下更快,但是靈活性較低、使用 MSAA 需要特殊處理。MSAA 能夠為非寫實畫風的遊戲帶來很大提升,因此我們選擇在 Godot 4 使用向前算繪(Godot 3 也一樣)。
話雖如此,向前算繪器中*確實*有一部分是使用延遲方法執行的,以便在可能的情況下進行一些優化。這一點尤其適用於 VoxelGI 和 SDFGI。
未來可能會開發集群延遲算繪器。這種算繪器可以在對性能的要求大於靈活性的場合使用。
算繪
Godot 可匯入下列圖片格式:
Vulkan
這是 Godot 4 的主要驅動,大部分開發集中在這個驅動上。
Vulkan 1.0 是必要的基準,Vulkan 1.1 和 1.2 的功能會有可用時使用。我們使用 volk 作為 Vulkan 載入器,使用 Vulkan Memory Allocator 進行記憶體管理。
使用 Vulkan 驅動時支援 Forward+ 和移動 算繪。
Vulkan 本文的建立:
Direct3D 12 context creation:
字典
與 Vulkan 類似,Direct3D 12 驅動僅支援現代平臺,是針對 Windows 和 Xbox 設計的(鑒於 Xbox 上無法直接使用 Vulkan)。
使用 Direct3D 12 時支援 Forward+ 和移動 算繪。
自定功能 are shared with the Vulkan renderer. Shaders are transpiled from SPIR-V to DXIL using Mesa NIR (more information).
This driver is still experimental and only available in Godot 4.3 and later. While Direct3D 12 allows supporting Direct3D-exclusive features on Windows 11 such as windowed optimizations and Auto HDR, Vulkan is still recommended for most projects. See the pull request that introduced Direct3D 12 support for more information.
Metal
Godot 透過 MoltenVK 支援 Metal 算繪,因為 macOS 和 iOS 本身不支援 Vulkan。在專案設定中指定 Vulkan 驅動程式時,此操作會自動完成。
MoltenVK 讓驅動程式維護變得容易,但代價是一些效能開銷。此外,MoltenVK 有一些本地 Metal 驅動程式實作所沒有的限制。叢集和移動 doc_internal_rendering_architecture_methods 都可以透過 MoltenVK 與 Metal 後端一起使用。
未來計劃推出原生 Metal 驅動程式,以獲得更好的效能和相容性。
OpenGL
這個驅動使用 OpenGL ES 3.0,針對的是不支援 Vulkan 的舊有裝置以及低端裝置。桌面平臺運作該驅動時使用的是 OpenGL 3.3 Core Profile,因為桌面平臺的大部分圖形驅動不支援 OpenGL ES。Web 匯出使用的是 WebGL 2.0。
It is possible to use OpenGL ES 3.0 directly on desktop platforms
by passing the --rendering-driver opengl3_es command line argument, although this
will only work on graphics drivers that feature native OpenGL ES support (such
as Mesa).
使用 OpenGL 驅動是只能使用 編譯 算繪方法。
自定功能 與 Vulkan 算繪器完全不同。
Many advanced features are not supported with this driver, as it targets low-end devices first and foremost.
算繪驅動/方法總結
目前可用的算繪 API + 算繪方法組合如下:
自由觀看 前
Vulkan + Forward 移動
Direct3D 12 + Forward+
Direct3D 12 + Forward 移動
Metal + Forward+(通過 MoltenVK)
Metal + Forward 移動(通過 MoltenVK)
OpenGL + 相容
每種組合都有其自身的限制和性能特徵。如果可能,請確保在打開拉取請求之前測試所有算繪方法的變更。
RenderingDevice 抽象
備註
OpenGL 驅動不使用 RenderingDevice 抽象。
為了使現代低階圖形 API 的複雜性更易於管理,Godot 使用自己的抽象,稱為 RenderingDevice。
這意味著在為現代算繪方法編寫程式碼時,您實際上並不會直接使用 Vulkan 或 Direct3D 12 API。雖然這仍然比 OpenGL 這樣的 API 等級低,但這使得算繪器上的工作變得更容易,因為 RenderingDevice 將為您抽像出許多特定於 API 的怪癖。 RenderingDevice 呈現與 Metal 或 WebGPU 類似的抽象層次。
Vulkan RenderingDevice 實作:
Direct3D 12 RenderingDevice implementation:
核心算繪類架構
下圖展示了 Godot 中算繪類別的結構,包括 RenderingDevice 抽象:
自定功能
使用 參考 GLSL 製作的著色器語言 之純文字著色器。
這些核心著色器嵌入在編輯器中,並在編譯時匯出模板二進位。要查看這些 GLSL 著色器所做的任何更改,您需要重新編譯編輯器或匯出模板二進位。
某些材質功能(例如高度貼圖、折射和鄰近淡入淡出)不是核心著色器的一部分,而是使用 Godot 著色器語言(不是 GLSL)在預設的 BaseMaterial3D 中執行。這是透過根據材質中啟用的功能按程式產生所需的著色器程式碼來完成的。
按照慣例,名稱中帶有 _inc 的著色器檔案包含在其他 GLSL 檔案中,以便更好地重複使用程式碼。標準 GLSL 預處理用於實作此目的。
警告
場景中的每種材質都將使用核心材質著色器 - 包括預設的 BaseMaterial3D 和自訂著色器。因此,這些著色器必須盡可能簡單,以避免效能問題並確保著色器編譯不會變得太慢。
如果您在著色器中使用「if」分支,效能可能會下降,因為著色器中的 VGPR(向量通用暫存器)使用量會增加。即使給定影格中所有像素的計算結果為“true”或“false”,也會發生這種情況。
如果您使用「#if」預處理器分支,則場景中所需的著色器版本的數量將會增加。在最壞的情況下,新增單一布林值「#define」可以使給定場景中可能需要編譯的著色器版本的數量加倍。在某些情況下,Vulkan 專業化常數可以用作更快(但更有限)的替代方案。
這意味著在 Godot 中新增新的內建材質功能存在很高的障礙,無論是在核心著色器還是 BaseMaterial3D 中。雖然 BaseMaterial3D 可以利用動態程式碼產生僅在啟用該功能的情況下包含著色器程式碼,但當在專案中使用這些功能時,它仍然需要產生更多著色器版本。這會使著色器編譯的卡頓現像在複雜的 3D 場景中更加明顯。
請參閱「著色器排列問題<https://therealmjp.github.io/posts/shader-permutations-part1/>`__ 和「GPU 上的分支<https://medium.com/@jasonbooth_86226/branching-on - a-gpu-18bfc83694f2>`__ 部落格文章以獲取更多資訊。
核心 GLSL 材質著色器:
Forward+: servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl
Forward Mobile: servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl
Compatibility: drivers/gles3/shaders/scene.glsl
材質著色器生成:
Forward+ 和 Forward Mobile 算繪方法的其他 GLSL 著色器:
Compatibility 算繪方法的其他 GLSL 著色器:
2D 與 3D 算繪的拆分
備註
以下僅適用於Forward+和Forward Mobile算繪方法,不適用於Compatibility。使用相容性後端時,可以使用多個視窗來模擬這一點,或執行 2D 解析度縮放。
2D 和 3D 算繪到單獨的緩衝區,因為 Godot 中的 2D 算繪是在 LDR(低動態範圍)sRGB 空間中執行的,而 3D 算繪則使用 HDR(高動態範圍)線性空間。
用於 2D 算繪的顏色格式是 RGB8(如果啟用了視窗上的 Transparent 屬性,則為 RGBA8)。 3D 算繪使用 24 位元無符號標準化整數深度緩衝區,如果硬體不支援 24 位元深度緩衝區,則使用 32 位元有符號浮點。 2D 算繪不使用深度緩衝區。
根據是否使用雙線性縮放或 FSR 1.0 縮放,3D 解析度縮放的執行方式有所不同。使用雙線性縮放時,不會執行特殊的放大著色器。相反,視口的紋理被拉伸並使用線性取樣器顯示(這使得篩選直接在硬體上發生)。這可以最大限度地提高雙線性 3D 縮放的效能。
當解析度或縮放比例改變時,RenderSceneBuffersRD 中的「configure()」函式會重新分配 2D/3D 緩衝區。
目前尚不支援動態解析度縮放,但計劃在未來的 Godot 版本中支援。
2D與3D算繪緩衝區配置C++程式碼:
FSR 1.0:
Animation - 動畫選項
2D 燈光算繪在單通道中執行,以便在大量燈光下獲得更好的效能。
Forward+ 和 Mobile 算繪方法尚不具備 2D 批次功能,但計劃在未來版本中提供。
相容性後端具有 2D 批次功能,可提高效能,這在螢幕上有大量文字時尤其明顯。
可以在 2D 中啟用 MSAA 以提供「自動」線條和多邊形抗鋸齒,但 FXAA 不會影響 2D 算繪,因為它是在 2D 算繪開始之前計算的。 Godot 的 2D 繪圖方法(例如 Line2D 節點或某些 CanvasItem “draw_*()” 方法)提供了自己的基於三角形條和頂點顏色的抗鋸齒方式,不需要 MSAA 即可運作。
A 2D signed distance field representing LightOccluder2D nodes in the viewport is automatically generated if a user shader requests it. This can be used for various effects in custom shaders, such as 2D global illumination. It is also used to calculate particle collisions in 2D.
2D SDF 生成 GLSL 著色器:
Animation - 動畫選項
Animation - 動畫選項
在 Forward+ 後端,Vulkan 實例化用於對相同物件的算繪進行群組以提高效能。這不像靜態網格合併那麼快,但它仍然允許單獨剔除實例。
Sprite、多邊形與線條算繪引擎。
備註
反射探查和裝飾算繪目前在相容性後端不可用。
顧名思義,Forward+ 後端使用集群照明。這允許您使用任意數量的燈光;性能很大程度取決於螢幕覆蓋範圍。如果無影燈在螢幕上不佔據太多空間,那麼它們幾乎可以是免費的。
所有算繪方法還支援同時算繪最多 8 個定向光源(儘管當多個光源啟用陰影時陰影品質較低)。
Forward Mobile 後端使用單通道照明方法,影響每個網格*資源*的限制為 8 個 OmniLights + 8 個 SpotLights(加上攝影機視圖中的 256 個 OmniLights + 256 個 SpotLights 限制)。這些限制是硬編碼的,無法在專案設定中進行調整。
相容性後端使用混合單通道 + 多通道照明方法。沒有陰影的燈光在單通道中算繪。帶有陰影的燈光通過多次算繪。出於行動裝置效能方面的考慮,這是必需的。因此,許多陰影投射燈的性能無法很好地擴充。建議在相機視錐體中一次只放置少量帶有陰影的燈光,並將這些燈光分散開,以便每個物件一次僅接觸 1 或 2 個陰影燈光。可以在專案設定中調整一次可見的最大燈光數量。
在所有 3 種方法中,沒有陰影的光線比有陰影的燈光便宜得多。為了提高效能,僅當修改燈光或其半徑內的物件時才會更新燈光。 Godot 目前並未將靜態陰影算繪與動態陰影算繪分開,但計劃在未來版本中實作這一點。
聚類也用於 Forward+ 後端中的反射探查和裝飾算繪。
陰影貼圖
Forward+ 和 Forward Mobile 方法都使用 PCF(百分比接近篩選)來篩選陰影貼圖並建立柔和的半影。這些方法不使用固定的 PCF 模式,而是使用沃格爾盤模式,該模式允許改變樣本數量並平滑地改變品質。
Godot 還支援百分比接近軟陰影 (PCSS),以實作更真實的陰影半影算繪。 PCSS 陰影僅限於 Forward+ 後端,因為它們要求太高,無法在 Forward Mobile 後端中使用。 PCSS 也使用 vogel 碟形核心。
此外,這兩種陰影貼圖技術都會在每個像素的基礎上旋轉內核,以幫助柔化取樣不足的偽影。
相容性後端尚不支援任何燈光型別的陰影貼圖。
多取樣抗鋸齒
備註
僅在 Forward+ 後端可用,在 Forward Mobile 或相容性方法中不可用。
Godot 使用基於「Spartan Engine <https://github.com/PanosK92/SpartanEngine>」的舊 TAA 實作的自訂 TAA 實作。
時間抗鋸齒需要運動向量才能發揮作用。如果運動向量沒有正確生成,當相機或物體移動時就會出現重影。
運動向量在 GPU 上的主材質著色器中產生。這是透過除了目前算繪影格的頂點著色器之外還運作與先前算繪影格(使用先前的相機變換)相對應的頂點著色器,然後將它們之間的差異儲存在顏色緩衝區中來完成的。
Alternatively, FSR 2.2 can be used as an upscaling solution that also provides its own temporal antialiasing algorithm. FSR 2.2 is implemented on top of the RenderingDevice abstraction as opposed to using AMD's reference code directly.
TAA 解決方案:
FSR 2.2:
定數
備註
VoxelGI 和 SDFGI 僅在 Forward+ 後端中可用,在 Forward Mobile 或相容性方法中不可用。
LightmapGI *烘焙*僅在 Forward+ 和 Forward Mobile 方法中可用,並且只能在編輯器中執行(不能在匯出的專案中執行)。 LightmapGI *算繪*最終將由相容性後端支援。
Godot 支援基於體素的 GI (VoxelGI)、有符號距離場 GI (SDFGI) 以及光照貼圖烘焙和算繪 (LightmapGI)。如果需要,這些技術可以同時使用。
光照貼圖烘焙使用 Vulkan 計算著色器在 GPU 上進行。基於GPU的光照貼圖器在LightmapperRD類別中實作,該類別繼承自Lightmapper類別。這允許實作額外的光照貼圖器,為 Godot 3.x 中基於 CPU 的光照貼圖器的未來移植鋪平道路。這將允許在使用相容性後端時烘焙光照貼圖。
核心 GI C++ 程式碼:
scene/3d/voxel_gi.cpp - VoxelGI node
editor/plugins/voxel_gi_editor_plugin.cpp - Editor UI for the VoxelGI node
核心 GI GLSL 著色器:
servers/rendering/renderer_rd/shaders/environment/voxel_gi.glsl
servers/rendering/renderer_rd/shaders/environment/voxel_gi_debug.glsl - VoxelGI debug draw mode
servers/rendering/renderer_rd/shaders/environment/sdfgi_debug.glsl - SDFGI Cascades debug draw mode
servers/rendering/renderer_rd/shaders/environment/sdfgi_debug_probes.glsl - SDFGI Probes debug draw mode
servers/rendering/renderer_rd/shaders/environment/sdfgi_integrate.glsl
servers/rendering/renderer_rd/shaders/environment/sdfgi_preprocess.glsl
servers/rendering/renderer_rd/shaders/environment/sdfgi_direct_light.glsl
光照貼圖器 C++ 程式碼:
scene/3d/lightmap_gi.cpp - LightmapGI node
editor/plugins/lightmap_gi_editor_plugin.cpp - Editor UI for the LightmapGI node
scene/3d/lightmapper.cpp - Abstract class
modules/lightmapper_rd/lightmapper_rd.cpp - GPU-based lightmapper implementation
光照貼圖器 GLSL 著色器:
景深
備註
僅在 Forward+ 和 Forward Mobile 方法中可用,在相容性後端中不可用。
Forward+ 和 Forward Mobile 方法使用不同的 DOF 算繪方法,具有不同的視覺結果。這樣做是為了最好地配對目標硬體的效能特徵。在 Clustered Forward 中,DOF 是使用計算著色器執行的。在 Forward Mobile 中,DOF 是使用片段著色器(光柵)執行的。
提供方框、六邊形和圓形散景形狀(從最快到最慢)。當啟用時間抗鋸齒時,可以選擇每個畫面抖動景深以改善其外觀。
景深
景深 GLSL 著色器(計算 - 用於 Forward+):
景深 GLSL 著色器(光柵 - 用於 Forward Mobile):
螢幕空間反射(SSR)
備註
僅在 Forward+ 後端可用,在 Forward Mobile 或相容性方法中不可用。
Forward+ 後端支援螢幕空間環境光遮蔽、螢幕空間間接照明、螢幕空間反射和次表面散射。
SSAO 使用源自英特爾`ASSAO <https://www.intel.com/content/www/us/en/developer/articles/technical/adaptive-screen-space-ambient-occlusion.html>`__ 的實作(轉換為到伏爾甘)。 SSIL源自SSAO,提供高效能間接照明。
當 SSAO 和 SSIL 同時啟用時,部分 SSAO 和 SSIL 會被共用以減少效能影響。
預設情況下,SSAO 和 SSIL 以半解析度執行以提高效能。 SSR 始終以半解析度執行以提高效能。
GLES3: 螢幕空間反射。
GLES3: 螢幕空間週遭遮擋。
servers/rendering/renderer_rd/shaders/effects/ssao_blur.glsl
servers/rendering/renderer_rd/shaders/effects/ssao_interleave.glsl
servers/rendering/renderer_rd/shaders/effects/ssao_importance_map.glsl
螢幕空間間接光照 GLSL 著色器:
servers/rendering/renderer_rd/shaders/effects/ssil_blur.glsl
servers/rendering/renderer_rd/shaders/effects/ssil_interleave.glsl
servers/rendering/renderer_rd/shaders/effects/ssil_importance_map.glsl
GLES3: 螢幕空間反射。
servers/rendering/renderer_rd/shaders/effects/screen_space_reflection.glsl
servers/rendering/renderer_rd/shaders/effects/screen_space_reflection_scale.glsl
servers/rendering/renderer_rd/shaders/effects/screen_space_reflection_filter.glsl
次表面散射
算繪
也參考
Godot 支援使用著色器來算繪天空背景。輻射度貼圖(用於為 PBR 材質提供環境光和反射)會根據天空著色器自動更新。
SkyMaterial 資源(例如 ProceduralSkyMaterial、PhysicalSkyMaterial 和 PanoramaSkyMaterial)產生用於天空算繪的內建著色器。這類似於 BaseMaterial3D 為 3D 場景材質提供的內容。
詳細的技術實作可以在《Godot 4.0 中的自訂天空著色器 <https://godotengine.org/article/custom-sky-shaders-godot-4-0>》一文中找到。
天空算繪 C++ 程式碼:
servers/rendering/renderer_rd/environment/sky.cpp - Sky rendering
scene/resources/sky.cpp - Sky resource (not to be confused with sky rendering)
scene/resources/sky_material.cpp SkyMaterial resources (used in the Sky resource)
天空算繪 GLSL 著色器:
體積霧
備註
僅在 Forward+ 後端可用,在 Forward Mobile 或相容性方法中不可用。
也參考
Godot 支援使用平截頭體對準體素 (froxel) 方法來進行體積霧算繪。與後處理濾鏡相反,這種方法更通用,因為它可以適用於任何光線型別。霧還可以使用著色器進行自訂行為,從而允許對霧進行動畫處理或使用 3D 紋理來表示密度。
FogMaterial 資源為 FogVolume 節點產生內建著色器。這類似於 BaseMaterial3D 為 3D 場景材質提供的內容。
詳細的技術解釋可以在《Godot 4.0 中引入 Fog Volumes <https://godotengine.org/article/fog-volumes-arrive-in-godot-4>》一文中找到。
體積霧 C++ 程式碼:
servers/rendering/renderer_rd/environment/fog.cpp - General volumetric fog
scene/3d/fog_volume.cpp - FogVolume node
scene/resources/fog_material.cpp - FogMaterial resource (used by FogVolume)
體積霧 GLSL 著色器:
遮擋剔除
雖然現代 GPU 可以處理繪製大量三角形,但複雜場景中的繪製呼叫數量仍然可能是瓶頸(即使使用 Vulkan 和 Direct3D 12)。
Godot 4 支援遮蔽剔除以減少透支(當深度預通道停用)並減少頂點吞吐量。這是透過使用 Embree 對 CPU 上的低解析度緩衝區進行光柵化來完成的。緩衝區的解析度取決於系統上 CPU 執行緒的數量,因為這是並行完成的。此緩衝區包括在編輯器中烘焙或在運作時建立的遮擋器形狀。
由於複雜的遮蔽物會對 CPU 造成很大的壓力,因此在編輯器中產生時可以自動簡化烘焙的遮蔽物。
Godot 的遮擋剔除尚未支援動態遮擋器,但 OccluderInstance3D 節點仍可切換或移動其可見性。但是,以這種方式更新複雜的遮蔽物時,速度會很慢。因此,在運作時更新遮擋物最好僅在簡單的遮擋物形狀(例如四邊形或長方體)上進行。
與其他解決方案(例如入口網站和房間或基於 GPU 的剔除解決方案)相比,這種基於 CPU 的方法具有一些優點:
無需手動設定(但可以手動調整以獲得最佳性能)。
沒有畫面延遲,這在攝影機切換期間或攝影機在牆後快速移動時的過場動畫中是有問題的。
在所有算繪驅動程式和方法上的工作方式相同,根據驅動程式或 GPU 硬件,不會出現不可預測的行為。
遮擋剔除是透過註冊遮擋器網格來執行的,這是使用 OccluderInstance3D 節點*(其本身使用 Occlusionr3D *資源)完成的。然後RenderingServer透過呼叫RendererSceneOcclusionCull中的Embree來執行遮蔽剔除。
遮擋模式
Visibility Rect(可見性區域)
Godot 支援手動建立的細節層級 (HLOD),距離由使用者在檢視器中指定。
在 RenderingSceneCull 中,「_scene_cull()」和「_render_scene()」函式是大多數 LOD 決定發生的地方。每個視窗都可以使用不同的 LOD 算繪相同的網格(以允許分割畫面算繪看起來正確)。
可見範圍C++程式碼:
自動重新匯入
ImporterMesh 類別用於編輯器中的 3D 網格匯入工作流程。它的「generate_lods()」函式使用「meshoptimizer <https://meshoptimizer.org/>」函式庫處理產生。
LOD網格生成同時也產生陰影網格。這些網格的頂點都是焊接的,無論平滑度和材料如何。這用於透過降低算繪陰影所需的頂點吞吐量來提高陰影算繪效能。
RenderingSceneCull 類別的 _render_scene() 函式決定算繪時應使用哪個網格 LOD。每個視窗都可以使用不同的 LOD 算繪相同的網格(以允許分割畫面算繪看起來正確)。
網格 LOD 是根據螢幕覆蓋指標自動選擇的。這會考慮解析度和相機視場變化,而無需使用者乾預。閾值乘數可以在專案設定中調整。
為了提高效能,陰影算繪和反射探查算繪還選擇自己的網格 LOD 閾值(可以與主場景算繪不同)。
匯入 C++ 程式碼時產生網格 LOD:
網格LOD測定C++程式碼: