Up to date

This page is up to date for Godot 4.2. If you still find outdated information, please open an issue.

3D 燈光與陰影

前言

光源發出燈光,燈光會與材質相混合,產生可見的結果。場景可以有很多不同型別的光源:

  • 來自材質本身的自發光顏色(但是無法影響附近的物件,除非進行了烘焙,或者啟用了螢幕空間間接光照)。

  • 燈光節點:DirectionalLight3D、OmniLight3D、SpotLight3D。

  • Environment反射探查 中的環境光。

  • 全域光照(LightmapGIVoxelGISDFGI)。

自發光是材質的屬性。更多相關內容見 標準 3D 材質與 ORM 3D 材質 教學。

也參考

除了這份說明文件,你可能也會想看看 Godot Demo 專案

燈光節點

燈光節點有三種:DirectionalLight3DOmniLight3DSpotLight3D。讓我們來看看燈光的通用參數:

../../_images/light_params.png

每個屬性都有特定的功能:

  • **Color:**發光的基礎顏色。

  • **Energy:**能量乘數。這對於使燈光飽和或使用 高動態範圍光照 非常有用。

  • **Indirect Energy:**間接能量。用於間接光(反彈的光)的次級乘數。適用於 使用光照貼圖全域光照、VoxelGI 和 SDFGI。

  • **Volumetric Fog Energy:**體積霧能量。用於體積霧的次級乘數。僅在啟用體積霧時有效。

  • Negative(減色) : 光變為減色而不是新增. 手動補償一些黑暗角落有時很有用.

  • **Specular:**鏡面反射。影響受此光影響的物體中鏡面反射斑點的強度。值為零時,該光變為純漫反射光。

  • **Bake Mode:**設定燈光的烘焙模式。見 使用光照貼圖全域光照

  • 剔除蒙版Cull Mask: 在下面選定的圖層中的物體將受到此光的影響。請注意,通過這個遮罩禁用的物件仍然會投射陰影。如果你不希望被禁用的物體投射陰影,請將GeometryInstance上的 cast_shadow 屬性調整為所需值。

也參考

如果您希望使用現實世界的單位來配置燈光的強度和色溫,請參閱 doc_physical_light_and_camera_units`。

光節點

當使用 Forward+ 渲染器時,Godot 使用*聚類*方法進行即時光照。可以新增所需數量的燈光(只要性能允許)。但是,目前相機視圖中可以出現的「聚集元素」的預設限制仍然是 512 個。群集元素是全向燈、聚光燈、貼紙 <doc_using_decals>` 或反射探查 <doc_reflection_probes>`。可以透過調整 渲染 > 限制 > 叢集產生器 > 最大叢集元素 進階專案設定來增加此限制。

使用前向移動渲染器時,每個網格資源有 8 個 OmniLight + 8 個 SpotLight 的限制。目前攝影機視圖中可渲染的 OmniLights + 256 SpotLights 數量也有限制。這些限制目前無法變更。

使用相容性渲染器時,每個網格資源最多可以渲染 8 個 OmniLight + 8 個 SpotLight。可以在高級專案設定中透過調整**渲染> 限制> OpenGL > 最大可渲染燈光** 和/或**渲染> 限制> OpenGL > 每個物件的最大燈光** 來增加此限制,但代價是效能和更長的著色器編譯時間。還可以減少該限制以減少著色器編譯時間並略微提高效能。

對於所有渲染方法,一次最多可以看到 8 個方向光。但是,每個啟用陰影的附加 DirectionalLight 都會降低每個 DirectionalLight 的有效陰影解析度。這是因為定向陰影合集在所有燈光之間共用。

如果超出渲染限制,燈光將在攝影機移動期間開始突然進出,這可能會分散注意力。在輕節點上啟用 Distance Fade 可以幫助減少此問題,同時還可以提高效能。將網格體分割成更小的部分也有幫助,特別是對於關卡幾何(這也提高了剔除效率)。

如果您需要在給定渲染後端中渲染比可能更多的燈光,請考慮使用烘焙光照貼圖 <doc_using_lightmap_gi>` 並將燈光烘焙模式設為 靜態。這使得燈光能夠完全烘焙,這也使得它們的渲染速度更快。您也可以將發射材質與任何全局照明技術一起使用,作為在大面積上發光的光節點的替代品。

陰影貼圖

燈光可以可選地投射陰影. 這使它們具有更好的真實感(光線不會照到被遮擋的區域), 但它會帶來更大的性能開銷. 有一個通用陰影參數列表, 每個參數也有一個特定的功能:

  • Enabled(啟用) : 勾選以啟用陰影貼圖.

  • Color(顏色) : 遮擋的區域會被乘以此顏色. 預設為黑色, 但可以更改來給陰影染色.

  • Bias(偏置):當此參數太小時,陰影會打在物體自己身上。當太大時,陰影會與物體本體分開。請調整到最適合你的狀態。

  • Bias(偏置):當此參數太小時,陰影會打在物體自己身上。當太大時,陰影會與物體本體分開。請調整到最適合你的狀態。

  • Bias(偏置):當此參數太小時,陰影會打在物體自己身上。當太大時,陰影會與物體本體分開。請調整到最適合你的狀態。

  • Reverse Cull Face: 反轉表面剔除,當陰影貼圖使用反轉表面剔除渲染時,在某些場景表現更好。

  • 模糊: 乘以該光的陰影模糊半徑。這適用於傳統陰影貼圖和接觸硬化陰影(**角度距離**或**大小**大於``0.0``的燈光)。數值越高,陰影越柔和,對於移動的物體來說,這也顯得在時間上更穩定。增加陰影模糊的缺點是,它會使用於篩選的顆粒圖案更加明顯。另請參閱:ref:doc_lights_and_shadows_shadow_filter_mode

../../_images/lights_and_shadows_blur.webp

Tweaking shadow bias

下圖是調整偏置的樣子。預設值適用於大多數情況,但通常取決於幾何的大小和複雜程度。

如果對於給定光源,**陰影偏差**或**陰影法線偏差**設定得太低,則陰影將「塗抹」到物件上。這將導致燈光的預期外觀變暗,稱為“陰影痤瘡”:

../../_images/lights_and_shadows_acne.webp

另一方面,如果對於給定光源,**陰影偏差**或**陰影法線偏差**設定得太高,則陰影可能看起來與物件斷開連接。這稱為「彼得平移」:

../../_images/lights_and_shadows_peter_panning.webp

一般來說,增加**陰影法線偏差**優於增加**陰影偏差**。增加**陰影法線偏差**不會像增加**陰影偏差**那樣造成那麼多的麻煩,但它仍然可以有效解決大多數陰影痤瘡問題。增加**陰影法線偏差**的缺點是,它會使某些物體的陰影顯得更薄。

任何偏置問題都可以通過提高陰影貼圖解析度來解決,儘管可能會導致性能下降。

備註

調整陰影貼圖設定是一門藝術 - 不存在「一刀切」的設定。為了獲得最佳視覺效果,您可能需要針對每個光源使用不同的陰影偏差值。

平行光

這是最常見的光線型別, 代表了很遠的光源(如太陽). 它也是計算中最便宜的光, 應該盡可能使用(雖然它不是計算起來最便宜的陰影貼圖, 但這點稍後再說).

平行光模擬覆蓋整個場景的無限數量的平行光線。平行光節點由指示光線方向的大箭頭表示。但是,節點的位置根本不會影響照明,它可以在任何地方。

../../_images/light_directional.png

每個表面的正面被光線照射,而其他部分則保持黑暗。大多數燈光型別都有特定的參數,但平行光本質上非常簡單,所以它們沒有。

定向光也提供**角距離**屬性,它決定光的角度大小(以度為單位)。將其增加到「0.0」以上將使陰影在距離施法者更遠的地方變得更柔和,同時也會影響太陽在程式天空材質中的外觀。這稱為“接觸硬化”陰影(也稱為 PCSS)。

作為參考,從地球觀看太陽的角距離約為「0.5」。這種陰影很昂貴,因此如果在啟用陰影的燈光上將此值設為高於“0.0”,請檢查 PCSS 建議 中的建議。

方向光陰影貼圖

為了計算陰影貼圖, 會從正交視圖(僅深度)渲染整個場景(或直到最大距離). 但是, 這種方法存在問題, 因為靠近相機的物體會得到塊狀陰影.

為了解決這個問題, 使用了名為"Parallel Split Shadow Maps"(平行分割陰影, 或PSSM)的技術. 這將視錐體分成2或4個區域. 每個區域都有自己的陰影貼圖. 這允許靠近觀察者的小區域具有與巨大的遙遠區域相同的陰影解析度.

../../_images/lights_and_shadows_pssm_explained.webp

有了它, 陰影變得更加詳細:

../../_images/lights_and_shadows_directional_mode.webp

為了控制PSSM, 暴露了許多參數:

../../_images/lights_and_shadows_directional_shadow_params.webp

每個分割距離都是相對於相機最遠處(或陰影 Max Distance(最大距離) , 如果大於零)控制的, 因此 0.0 是眼睛位置, 1.0 是陰影在一定距離處結束的位置. 分割介於兩者之間. 預設值通常效果很好, 但調整第一個分割數值是很常見的, 可以為近處物件提供更多細節(比如第三人稱遊戲中的角色).

始終確保根據場景需要設定陰影**最大距離**。較小的最大距離將導致更好看的陰影和更好的性能,因為陰影渲染中需要包含的物件更少。您也可以調整**淡入淡出**來控制遠處陰影淡出的強度。對於**最大距離**在任何給定攝影機位置完全覆蓋場景的場景,您可以將**淡入淡出**增加到``1.0``以防止陰影在一定距離處褪色。在 最大距離 未完全覆蓋場景的場景中不應執行此操作,因為陰影會看起來在遠處突然被切斷。

有時, 一個分割與下一個之間的過渡看起來很糟糕. 要解決此問題, 可以打開 "Blend Splits"(混合分割) 選項, 犧牲細節以換取更平滑的過渡:

../../_images/blend_splits.png

當物體垂直於光線時,"Normal Bias"(法線偏置) 參數可用於修復自陰影的特殊情況。唯一的缺點是它使陰影更薄。

最後,Pancake Size 是一個可以調整的屬性,可以在使用具有未細分網格的大型物件時修復遺失的陰影。僅當您發現與陰影偏移問題無關的陰影缺失時才更改此值。

全向光

全向光是一種點光源,可在所有方向上發射光,直至給定的半徑。

../../_images/light_omni.png

在現實生活中,光衰減是個和距離成反比的函式,這意味著全向光沒有半徑。這是一個問題,因為這意味著計算幾個全向光會變得很困難。

為了解決這個問題, 引入了 Range(範圍) 和衰減函式.

../../_images/light_omni_params.png

這兩個參數允許調整其在視覺上的工作方式, 以便找到美學上令人愉悅的結果.

../../_images/light_attenuation.png

OmniLight3D 中也提供 Size 參數。增加此值將使光線淡出速度變慢,遠離施法者時陰影會顯得更加模糊。這可以在一定程度上用於模擬區域光。這稱為“接觸硬化”陰影(也稱為 PCSS)。這種陰影很昂貴,因此如果在啟用陰影的燈光上將此值設為高於“0.0”,請檢查 PCSS 建議 中的建議。

../../_images/lights_and_shadows_pcss.webp

全向光陰影貼圖

全向光的陰影貼圖相對簡單。需要考慮的主要問題是用於渲染它的演算法。

全向光陰影可以渲染為 "Dual Paraboloid"(雙抛物面)或"Cube Mapped"(方形對應) . 前者渲染速度很快但會導致變形, 而後者更正確但成本更高.

../../_images/lights_and_shadows_dual_parabolid_vs_cubemap.webp

如果渲染的物件大部分是不規則的, 那麼Dual Paraboloid 通常就足夠了. 無論怎麼說, 由於這些陰影被快取在陰影合集中(後面會詳細講), 對於大多數場景而言, 它可能不會對性能產生影響.

啟用陰影的全向燈可以利用投影機。投影機紋理會將光的顏色乘以紋理上給定點的顏色。因此,一旦分配了投影機紋理,燈光通常會顯得更暗;您可以增加**能量**來彌補這一點。

全向光投影機紋理需要特殊的 360° 全景對應,類似於:ref:class_PanoramaSkyMaterial 紋理。

使用下面的投影機紋理,獲得以下結果:

../../_images/lights_and_shadows_omni_projector_example.webp ../../_images/lights_and_shadows_omni_projector.webp

小訣竅

如果您以立方體貼圖影像的形式獲得了全向投影儀,則可以使用「這個基於網路的轉換工具<https://danilw.github.io/GLSL-howto/cubemap_to_panorama_js/cubemap_to_panorama.html>」__ 來轉換它們到單一全景圖像。

聚光

聚光與全向光類似,但是它們只發光到錐形(或“截斷”)中。它們可用於模擬手電筒、車燈、反射器、聚光燈等。這種型別的光也會向其指向的相反方向衰減。

聚光和 OmniLight(全向光)**共用 **Range(範圍)**和 **Attenuation(衰減),並新增了兩個額外參數:

  • Angle(角度) : 光線的光圈角度。

  • Angle Attenuation(角度衰減) : 錐形衰減, 有助於軟化錐形邊界.

聚光燈陰影貼圖

聚光燈具有與用於陰影貼圖的泛光燈相同的參數。與泛光燈相比,渲染點陰影貼圖要快得多,因為只需要渲染一個陰影紋理(而不是渲染 6 個面,或在雙拋物面模式下渲染 2 個面)。

啟用陰影的聚光燈可以利用投影機。投影機紋理會將光的顏色乘以紋理上給定點的顏色。因此,一旦分配了投影機紋理,燈光通常會顯得更暗;您可以增加**能量**來彌補這一點。

與全光投影機不同,聚光燈投影機紋理不需要遵循特殊格式即可看起來正確。它將以類似於裝飾 <doc_using_decals>` 的方式進行對應。

使用下面的投影機紋理,獲得以下結果:

../../_images/lights_and_shadows_spot_projector_example.webp ../../_images/lights_and_shadows_spot_projector.webp

備註

廣角聚光燈的陰影品質比窄角度聚光燈低,因為陰影貼圖分佈在較大的表面上。當角度大於 89 度時,聚光燈陰影將完全停止工作。如果您需要更寬的燈光陰影,請使用泛光燈。

影子合集

與具有自己的陰影紋理的平行光不同,全向光和聚光被分配了陰影合集的槽位元。可以在“專案設定 -> 渲染 -> 品質 -> 陰影合集”中配置此合集。

這個解析度適用於整個陰影合集。該合集分為四個象限:

../../_images/lights_and_shadows_shadow_quadrants.webp

每個象限可以細分,分配任意數量的陰影貼圖。以下是預設細分方式:

../../_images/lights_and_shadows_shadow_quadrants2.webp

常見的使用情景如下:

  • 分配邏輯很簡單. 最大的陰影貼圖大小(當不使用細分時)表示一個螢幕大小(或更大)的光. 細分區塊(較小的貼圖)表示遠離視圖並且成比例地較小的光的陰影.

  • 分配邏輯很簡單. 最大的陰影貼圖大小(當不使用細分時)表示一個螢幕大小(或更大)的光. 細分區塊(較小的貼圖)表示遠離視圖並且成比例地較小的光的陰影.

每一影格, 以下過程被應用於所有光:

  1. 檢查燈光是否在正確大小的插槽上. 如果沒有, 重新渲染它並將其移動到更大/更小的插槽.

  2. 檢查影響陰影貼圖的任何物件是否已更改. 如果是的話, 重新渲染光線.

  3. 如果上述情況均未發生, 則不執行任何操作, 陰影保持不變.

如果一個象限中的槽位滿了, 光線會被推回到更小的槽位中, 取決於大小和距離.

預設陰影分配策略允許在相機視錐體中啟用陰影的情況下渲染最多 88 個燈光 (4 + 4 + 16 + 64):

  1. 第一個也是最詳細的象限可以儲存 4 個陰影。

  2. 第二象限可以儲存另外4個陰影。

  3. 第三象限可以儲存16個陰影,細節較少。

  4. 第四個也是最不詳細的象限可以儲存 64 個陰影,細節更少。

每個象限使用更多數量的陰影可以在啟用陰影的情況下支援更多數量的總燈光,同時還可以提高效能(因為每個燈光的陰影將以較低的解析度渲染)。然而,增加每個象限的陰影數量是以降低陰影品質為代價的。

此分配策略適用於大多數遊戲, 但在某些情況下你可能會想用一個單獨分開的貼圖(例如, 一個自上向下看的遊戲, 其中所有燈光大小大概相同, 所有象限的細分可能會具有相同大小).

平衡性能與品質

陰影渲染是 3D 渲染性能方面的重要議題。做出正確的選擇非常重要,這樣才能避免製造出瓶頸。

平行光的陰影品質設定可以在運作時調整,呼叫合適的 RenderingServer 方法即可。

位置光(全向燈/聚光燈)的陰影品質設定可以在運作時調整,設定根 Viewport 即可。

陰影對應:

高陰影解析度會產生更清晰的陰影,但會帶來顯著的效能成本。還應該注意的是,更清晰的陰影並不總是更真實。在大多數情況下,這應該保持在預設值“4096”,或者對於低端 GPU 減少到“2048”。

如果縮小陰影貼圖大小後位置陰影變得太模糊,您可以透過調整陰影合集 <doc_lights_and_shadows_shadow_atlas>` 象限以包含較少的陰影來抵銷這種情況。這將允許每個陰影以更高解析度渲染。

陰影篩選模式

可以在此處選擇多個陰影貼圖品質設定。對於具有詳細紋理的場景,預設的 Soft Low 可以在效能和品質之間取得良好的平衡,因為紋理細節將有助於使抖動圖案不那麼明顯。

However, in projects with less detailed textures, the shadow dithering pattern may be more visible. To hide this pattern, you can either enable 多取樣抗鋸齒 (MSAA)。, AMD FidelityFX Super Resolution 2.2 (FSR2), 多取樣抗鋸齒 (MSAA)。, or increase the shadow filter quality to Soft Medium or higher.

軟非常低**設定將自動減少陰影模糊,從而使低樣本數造成的偽影不那麼明顯。相反,**Soft HighSoft Ultra 設定將自動增加陰影模糊,以更好地利用增加的樣本數。

../../_images/lights_and_shadows_filter_quality.webp

16 位與 32 位

預設情況下,Godot 使用 16 位元深度紋理進行陰影貼圖渲染。在大多數情況下建議這樣做,因為它的性能更好,而且品質沒有明顯差異。

如果停用 16 位元,則將使用 32 位元深度紋理。這可以減少大場景和啟用陰影的大燈光中的偽影。然而,差異通常幾乎不可見,但這可能會產生顯著的效能成本。

燈光/陰影的距離淡出

OmniLight3D 和 SpotLight3D 提供了一些能夠隱藏遠距離燈光的屬性。如果是在大型場景中,並且存在幾十盞燈,就能夠顯著提升性能。

  • 啟用: 控制是否啟用距離淡入淡出(LOD(細節等級)的一種形式)。光線將在 Begin + Length 內淡出,之後它將被剔除並且根本不會發送到著色器。使用它可以減少場景中活動燈光的數量,從而提高效能。

  • 開始: 光線開始消失時距相機的距離(以 3D 單位表示)。

  • 陰影: 陰影開始消失時距相機的距離(以 3D 單位表示)。與光線相比,這可用於更快地淡出陰影,從而進一步提高性能。僅當為燈光啟用陰影時才可用。

  • 長度: 光線和陰影淡出的距離(以 3D 單位表示)。光線在這段距離內慢慢變得更透明,最後完全不可見。數值越高,淡出過渡越平滑,這在相機快速移動時更適合。

PCSS 建議

百分比接近軟陰影 (PCSS) 提供更真實的陰影貼圖外觀,半影大小會根據施法者與接收陰影的表面之間的距離而變化。這會帶來很高的性能成本,特別是對於定向燈而言。

為了避免性能問題,建議:

  • 在給定時間僅使用少量啟用了 PCSS 陰影的燈光。這種效果通常在大而明亮的燈光下最為明顯。較微弱的輔助光源通常不會從使用 PCSS 陰影中受益匪淺。

  • 為使用者提供禁用 PCSS 陰影的設定。在定向光源上,這可以透過在腳本中將 DirectionalLight3D 的「light_angle_distance」屬性設為「0.0」來完成。對於位置光源,這可以透過在腳本中將 OmniLight3D 或 SpotLight3D 的「light_size」屬性設為「0.0」來完成。

專案工作流程

投影機的渲染方式也會對效能產生影響。 渲染 > 紋理 > 燈光投影機 > 濾鏡 進階專案設定可讓您控制投影機紋理的篩選方式。 最近/線性**不使用 mipmap,這使得渲染速度更快。然而,投影機在遠處看起來會有顆粒感。 **最近/線性 Mipmap 在遠處看起來會更平滑,但從傾斜角度觀看時投影機看起來會模糊。這可以透過使用**最近/線性 Mipmap 各向異性**來解決,這是最高品質的模式,但也是最昂貴的。

如果您的專案具有像素藝術風格,請考慮將濾鏡設定為**最近**值之一,以便投影機使用最近鄰篩選。否則,請堅持**線性**。