Unity Lighting
想要在unity中實作好的渲染效果,對引擎光照的了解是必不可少的。下圖是官方給出的Lighting pipeline 流程圖,針對圖中各點進行總結,但沒有太過詳細,具體可深入查閱相關資料。
Render Pipelines 渲染管線
- Build-in 内置管線,又可分為:
- Forward 前向渲染
- Deferred 延遲渲染
-
Lightweight Render Pipeline(LWRP) 輕量級渲染管線,2019.3版本中改名為Universal Render Pipeline(URP)
快速單通道正向渲染,是專為移動平台、平闆電腦和XR等實時照明要求較低的裝置設計的。
-
HDRP
綜合了Deferred/Forward、Tile/Cluster 渲染方式,提供高品質渲染效果,适合PC和主機平台。
如何選擇需要結合項目實際需求,可參考下圖:
Global Illumination 全局光照
全局照明(GI)是一個模拟光如何從表面反彈到其他表面的系統(間接光),而不僅僅局限于光源(直接光)直接照射到表面的光。精确模拟全局光照,計算消耗昂貴,是以遊戲一般采用預計算方式實作。在Unity中有兩個全局照明系統,可以在Window > Rendering > Lighting Settings中設定。
-
Precomputed Realtime GI Lighting 預計算實時全局光照
互動式更新場景光照資訊,也就是說能實時響應光照條件的變化。為了保證遊戲運作時的幀率,需要将這些冗長的資料處理從一個實時過程轉變為一個“預先計算”的過程。
GI系統希望存儲的是場景中的間接光,這種顔色通常比較柔和,不會有高頻變化。unity的預計算實時GI利用了這種漫反射特性。假設不捕捉光照細節如清晰的陰影,大大降低全局光照解決方案的分辨率,有效減少了遊戲運作期間更新GI照明所需的計算次數。
該系統完全依賴于第三方照明中間件Enlighten。在Unity的預計算過程中,Enlighten先後經過兩個階段,包括:叢集化和光傳輸。第一階段将場景分解簡化為以“叢集(clusters)”為機關進行組織的集合,在第二階段計算叢集與叢集之間的可見性。預計算後的資料在運作時用于互動性地生成場景的間接照明。通過将世界簡化成一個關系網絡,無需在遊戲運作中進行昂貴的光線追蹤計算。 Enlighten的優勢在于能夠實時改變間接照明效果,因為預計算的資料依賴于叢集之間的關系。但是,與其他光照貼圖技術一樣,改變場景中的靜态幾何體将觸發新的預計算。
-
Baked GI Lighting 烘焙全局光照
計算光照對場景中靜态物體的影響,照明資訊被烘焙到光照貼圖和光照探頭中。
這些光照貼圖可以既包括直接照射到表面的光,也包括從場景中其他物體或表面反射回來的“間接”光。可以與物體材質的“着色器”中的顔色和法線等表面資訊一起使用。
烘焙光照不能在遊戲運作時改變,是以被稱為靜态。實時光可以被覆寫和疊加到被光照映射的場景中,但是不能互動式改變LightMap本身。
烘焙GI 系統可以使用以下兩種技術之一
- Enlighten (Unity 2021.1将完全移除Enlighten)
- Progressive Lightmapper
Enlighten和Progressive Lightmapper 使用了不同的技術計算光照,是以兩者産生的光照效果會有不同。
無論使用哪種全局照明系統,Unity 都隻會考慮标記為“Lightmap Static”的遊戲對象。動态遊戲對象需要借助場景中放置的光照探頭來接收間接照明。(unity2019.2版本開始使用Contribute Global Illumination标志)
由于全局光照計算是一個相對緩慢的過程,是以隻有具有明顯光照變化的大型複雜資源才需要應标記為“Lightmap Static”。接收均勻光照的較小網格可保持為動态設定,然後通過使用 Light Probes 為其提供近似效果的間接照明效果。較大的動态遊戲對象可以使用 Light Probe Proxy Volume(LPPV),以便在局部接收更好的間接照明。限制場景中靜态遊戲對象的數量對于提高烘焙時間同時保持足夠照明品質至關重要。
在Unity中可以同時使用烘焙和實時GI技術,但是必須注意,同時使用會大大增加烘焙時間和程式運作時的記憶體消耗,因為這兩個系統不使用相同的資料,同時渲染兩個系統的性能成本正好是它們的總和。不僅要存儲兩組光映射,而且還要在着色器中解碼處理。此外,間接照明在運作時的互動式更新将給CPU帶來額外的壓力,并且在視覺上,烘焙和實時GI提供的間接照明效果會有差異,因為它們使用了不同的技術來模拟間接照明,并且通常在完全不同的分辨率下執行。若同時使用這兩種技術,建議将使用範圍限制在高端平台或具有可預測性能成本且嚴格把控場景的項目中,同時,建議由對所有照明設定有很好了解的團隊成員負責,因為管理這兩個系統相對複雜。
是以,對于大多數項目而言,盡量避免同時使用兩種GI技術,選擇其一是相對比較穩妥的做法。采取哪種方法的決定必須根據特定項目的性質和期望的目标平台進行評估。在針對一系列不同的硬體時,通常是性能最差的部分決定了需要哪種方法。
預設情況下,兩種方案在Unity的照明面闆(Lighting>Scene)中都啟用。然後可以由每個燈單獨控制(Inspector>Light>Mode)。可以通過取消其中一種方案來覆寫燈光設定。
Light Mode
-
Realtime Lighting
實時光照是對物體進行照明最基本的方式,對于照亮移動物體非常有用。但是它們本身的光線并不反彈。要使用全局照明技術建立更真實的場景,需要啟用unity的預計算照明解決方案。directional,spot,point預設狀态下是Realtime mode的。
預設模式是“Realtime”意味着選擇的光線仍然會直接作用于你的場景,而間接光線則由Unity的預先計算的實時GI系統處理。
如果不使用任何GI技術,或者僅使用實時GI,那麼所有Baked和Mixed模式的燈光都将被作為Realtime進行處理(此時,mixed和baked不可選)。
- 優點
- 可互動,燈光修改即時回報
- 可産生動态陰影
- 物體表面有高光
- 缺點
- 開銷很大
- 隻使用Baked GI時不産生間接光照
- 優點
-
Baked
該模式下直接光和間接光資訊都将被烘焙成光照貼圖,不能在遊戲運作過程中改變。烘焙這些資訊十分耗時,好處是沒有運作時成本來處理這些光照,但光照映射到場景有一個小的成本。
- 優點
- 高性能
- 靜态物體生成間接光照和陰影
- 缺點
- 不能運作時修改燈光屬性,修改後需要重新烘焙
- 物體表面沒有高光
- 烘焙精度決定烘焙品質,越高越耗時
- 優點
-
Mixed
選擇Mixed模式,标記為靜态的GameObjects會在其烘焙的GI光照圖中包含此光照資訊。然而與标記為baked的燈光不同,混合燈光仍然可以實時、直接地照亮場景中的非靜态遊戲對象。可用于在靜态環境中使用了光照貼圖,但仍希望角色也被這些光線影響,進而将實時陰影投射到光照貼圖的幾何體上。
- 優點
- 可産生動态陰影
- 物體表面有高光
- 缺點
- 開銷較大
- 烘焙耗時
- 優點
Light Mode 對應 Lighting 設定
Mixed Lighting Mode
- Baked Indirect 烘焙間接光
- Substractive 烘焙直接光照、間接光照和陰影
- Shadowmask 烘焙間接光照和陰影
- Shadowmask Mode可以在Edit > Preferences > Quality設定
- Shadowmask 使用Lightmap_shadowmask上的烘焙陰影
- Distance Shadowmask 根據設定的Shadow Distance參數對實時陰影和烘焙陰影進行融合
如何選擇Light Mode
Light Sources
- Directional 平行光
-
Spot 聚光燈
聚光燈目前不支援間接陰影,在使用預計算實時GI時。這意味着由聚光燈産生的光将穿過幾何圖形并在另一邊反彈。是以,需要仔細考慮設定問題。
-
Point 點光
為點光源啟用陰影開銷昂貴,是以必須謹慎使用。點光源要求陰影必須在6個世界方向上渲染6次,在較慢的硬體上這可能是一個無法接受的性能代價。
它也不支援間接反彈光的陰影。這意味着由點光源産生的光将繼續穿過物體并在另一側反彈,除非被範圍衰減。這可能導緻光線通過牆壁和地闆,是以必須小心地放置燈光以避免此類問題。使用烘焙GI時沒有這個問題。
-
Area(baked only) 區域光
區域光隻在烘焙GI中可用,在整個表面上均勻發光。區域光範圍不能手動控制,但是強度随着距光源距離的平方成反比減小。可以用在希望建立柔和的燈光效果時,常用來作為天花闆燈光或背光。
區域光計算時從世界上的每個lightmap texel向光發射大量射線,以确定是否可以看到光線。這意味着區域燈光在計算上非常昂貴,并且會增加烘焙時間。然而,如果使用得當,它們可以為場景照明增加很大的真實感,這種額外的預計算是合理的,因為他們隻是烘焙,遊戲運作性能不受影響。
-
Emission 自發光
雖然區域燈不支援預計算實時GI,想達到類似軟照明效果可以使用自發光材質。就像區域燈一樣,自發光材質通過其表面區域發射光線。他們能貢獻場景中的反射光線,如顔色和強度可以在遊戲過程中改變。
自發光材質沒有具體距離,但是發出的光将以平方的速度衰減。隻有标記為static或Lightmap static的物體才會接受自發光材質的産生影響。同樣,沒有标記為靜态的自發光材質不會影響場景光照。
不過自發光值大于0的材質仍然會在螢幕上顯示出明亮的光芒,即使它們對于場景照明沒有貢獻。
自發光材質隻會直接影響場景中的靜态幾何體。如果需要動态的或者非靜态的幾何體,例如角色,為了從自發光中擷取光,必須使用Light Probes。在遊戲中改變發射值将會互動式地更新光照探頭,任何目前從這些探針接收到光的物體上可以看到改變後結果。
除了以上的光源外,還需注意Ambient Lighting的影響。它影響場景整體顯示效果和亮度的環境照明,可以被認為是一個全局光照,從各個方向影響場景中的物體。在Lighting>Scene>Environment Lighting設定
根據選擇的藝術風格,環境光可以起到很大作用。比如想要一個明亮的卡通風格,黑暗的陰影可能是不受歡迎的,或者照明可能是手繪成紋理的。如果需要增加一個場景的整體亮度,而不調整個别燈,環境光也能起到調節作用(天空盒不受影響)。
沒有使用Unity的預計算照明解決方案,環境光将不會被遮擋,是以不會是實體上準确的。然而,如果在場景中啟用了烘焙GI或預計算實時GI,那麼這個“天光”将會被你的場景中的對象所阻擋,進而産生更真實的效果。
使用環境光的一個重要優點是它的渲染成本很低,是以對于移動應用程式特别有用,在移動應用程式中,可能需要盡量減少場景中的燈光數量。
請注意,改變環境光源的顔色并不影響可見的天空盒,它隻影響場景中照明的顔色。
Reflection Probes
Unity場景預設使用天空盒來進行反射計算。在許多情況下,物體可能被遮擋。它們可能在室内,也可能在橋梁或隧道等建築下方。為了建立更精确的反射,我們需要使用反射探針來采樣對象所看到的東西。這些探測器從它們在三維空間中的位置繪制世界,并将結果寫入cubemap。這可以被附近的物體使用,給人一種反映周圍世界的印象。
GameObject>Light>Reflection Probe建立一個反射探針。實時反射探針性能消耗很大,因為會為每個反射探針額外渲染6次場景。是以一般使用性能較好的烘焙反射探針。使用烘焙反射探針需要将想要烘焙的物體勾選static。
Light Probes
lightmaps存儲關于光到達場景表面的照明資訊,而light probes存儲關于光通過場景中的空白空間的資訊。主要有兩點用途:
- 為場景中移動的物體提供高品質的照明(包括間接反射光)。
- 在靜态場景使用Unity的LOD系統時,為靜态場景提供照明資訊。
隻有靜态對象才能使用unity的烘焙或預計算實時GI系統。為了讓動态對象,如互動元素、角色能夠接收到靜态幾何體所接收的一些豐富的反彈光,unity将這些資訊記錄成一種格式,以便在遊戲過程中快速讀取并用于照明方程。
unity通過在世界上放置樣本點,然後從各個方向捕捉光線來做到這一點。這些點記錄的顔色資訊被編碼成一組值(或“系數”),這些值可以在遊戲過程中快速計算。在Unity中,稱這些采樣點為“光照探針”。
為了得到更好的計算結果,在照明變化的區域(例如陰影或顔色過渡)周圍以更大的密度放置這些采樣點。
光照探針允許移動的物體響應複雜的反彈照明,無論使用烘焙GI或預計算實時GI。一個對象的網格渲染器将尋找周圍的光照探針的位置和混合他們的值。這是通過尋找由光照探針的位置組成的四面體,然後決定物體的支點落在哪個四面體上來實作的。這讓我們可以在場景中放置移動的角色,并讓它們适當地融合在一起。如果沒有光照探針,動态對象就不會接收GI。
預設情況下,場景中沒有光照探針,是以需要自己建立(GameObjects>Light>Light Probe Group)。
如果勾選了自動烘焙,每當改變場景照明或靜态幾何時會自動更新光照探頭。否則當單擊Build按鈕時才被更新。
Light Probe Proxy Volume
LPPV 可以為大型動态遊戲對象(不能使用烘焙的光照貼圖的對象)使用更多的照明資訊,例如粒子系統或蒙皮網格。為受光照探針影響的遊戲對象提供了一個空間梯度。
标準着色器(Standard Shader)支援該特性。如果想将該特性添加到自定義着色器中,需要使用 ShadeSHPerPixel 函數(該函數位于UnityStandardUtils.cginc)
Unity Lighting Modes Reference Card
參考資料
https://docs.unity3d.com/Manual/BestPracticeLightingPipelines.html
https://docs.unity3d.com/Manual/LightingInUnity.html
https://docs.unity3d.com/Manual/GlobalIllumination.html
https://docs.unity3d.com/Manual/LightModes.html