偽造全域照明

為什麼要偽造全域照明?

Godot 提供了數種全域照明(GI)技術,各有其優缺點。然而,你也可以完全不使用 GI 技術,改採手動方式。選擇手動處理全域照明(而不是 VoxelGI、SDFGI 或烘焙光照貼圖)的理由包括:

  • 你需要良好的繪圖效能,但又無法承受繁瑣的光照貼圖烘焙流程。

  • 你需要一種能夠全即時、且可支援程式化產生關卡的 GI 解法。

  • 你需要一種全即時且不會明顯漏光的 GI 方法。

以下介紹的方法僅涵蓋間接漫射光,並不包含鏡面反射光。若需鏡面反射,建議搭配 ReflectionProbes 使用,這類探針通常效能負擔低,適合和這些假 GI 技術一起運用。

也參考

不確定用燈光模擬全域照明是否適合你的需求嗎?請參考 我該選用哪一種全域照明技術?,了解 Godot 4 支援的各種 GI 技術比較。

模擬 DirectionalLight3D 的全域照明

雖然天空本身會提供定向光,場景中的主要 DirectionalLight3D 節點通常也會發出大量光線。使用 GI 技術時,這些光會在實體表面反射,並在多數戶外陰影區域產生二次反射。

我們可以透過新增第二個 DirectionalLight3D 節點,並做以下設定來模擬這種效果:

  • 將這盞燈旋轉 180 度,讓它模擬主 DirectionalLight3D 反射回來的光線。

  • 陰影 設為 關閉,同時降低輔助光的效能負擔,並讓陰影區域能獲得「一些」照明(這正是所需效果)。

  • 能量 調整為原始值的 10-40%。沒有「絕對正確」的數值,請根據實際燈光和材質顏色自行微調。

  • 鏡面 (Specular)設為 0.0 ,間接光通常不會產生可見的鏡面反射,因此需要完全關閉輔助光的鏡面效果。

備註

這種作法最適合大多數為戶外場景的情境。進入室內時,由於輔助 DirectionalLight3D 關閉陰影,光線會在室內仍然可見。

你可以在進入室內時,平滑地降低輔助 DirectionalLight3D 的能量(離開時再恢復),這個流程可以用 Area3D 搭配 AnimationPlayer 來達成。

模擬位置光源的全域照明

對於位置光源(OmniLight3D 與 SpotLight3D),也能用類似 DirectionalLight3D 的手法。不過這需要對場景內每一個位置光進行多次手動設定才能達到理想效果。

理想情況下,每當大量光線照射在夠亮的表面時都應新增一個輔助 OmniLight3D。但由於時間或設計限制(尤其在程式化關卡生成時),通常沒辦法全部手動處理。

如果趕時間,可以直接將輔助 OmniLight3D 節點放在主要 OmniLight3D 同一位置,並將其設為主節點的子節點,日後就能一起移動或隱藏。

在輔助 OmniLight3D 節點上,請做以下設定:

  • 範圍 (Range)增加 25-50%,讓輔助光可以補足原本主光未照亮的區域。

  • 陰影 設為 關閉,同時降低輔助光的效能負擔,並讓陰影區域能獲得「一些」照明(這正是所需效果)。

  • 能量 設為主光的 10-40%。沒有絕對標準值,依光線與場景實際狀況調整。

  • 鏡面 (Specular)設為 0,間接光不會產生明顯的鏡面反射,所以要完全關閉輔助光的鏡面效果。

對於 SpotLight3D 也能用同樣方法。這時輔助 OmniLight3D 的擺放位置應該靠近 SpotLight3D 主要照射、光線最多反射的區域。

下圖範例中,SpotLight3D 用來照亮房間地板,但由於沒有間接照明,其他區域仍然很暗。現實中,牆壁和天花板會因光線反彈而亮起。如果在 SpotLight3D 的起點與地板之間放一個 OmniLight3D,就能模擬這種效果:

../../../_images/faking_global_illumination_comparison.webp