写给美术看的Unity全局光照详解
Unity到2019,GI系統相比已經有了很大改進,可能你會覺得文章已經過時。對于舊知識看法,本人認為還是有重要的學習價值的。如果你熟悉一種技術的發展歷程,你會知道技術中的一些細節為什么要這樣實現,這是有利于充分掌握這種技術的。
好了,不想多說廢話了。
讀完“理論篇”內容,希望你們能夠理解GI的核心思想:Light Bounced光線彈射。光線從光源出發,擊中物體表面隨即反射進攝像機,我們把這一部分照明就做直接照明;若光線在各個表面彈射,最終到達攝像機的部分叫做間接照明。
在基于物理渲染的思想中,還需要考慮表面材質對光線的反射率(Albedo)的影響。通俗地理解:即,要考慮光線能量有多少被吸收,導致被反射出去的光線呈現怎樣的強度和顏色。表面的反射率(Albedo)一般用RGB表示。
實現GI有兩種方案Realtime GI和Baked GI,對應的最終實現的形式為Dynamic Lightmap動態光照貼圖和Lightmap光照貼圖。以下全文將主要圍繞:控制Dynamic Lightmap和Lightmap的效果的參數展開。
如果對上面的概念還不太清楚,建議先認真看一遍“理論篇”內容會更好。
我們對GI的概念有了一個大致的認識后,下面我們要學習的是:Unity 的GI程序到底做了哪些工作,以及我們要如何控制GI程序的。如果有不理解的地方,可以暫且跳過。在烘焙教程章節重點講解。
GI Process
在Unity中,烘焙/預計算程序默認是自動處理(Auto Generate)的,也可以手動啟動, 在這兩種情況下,并不會影響編輯器的其他操作,因為這些過程在后臺運行的。為了方便描述,以下全文把烘焙/預計算這個過程統一稱作GI程序(GI Process)。
當GI程序正在運行時,編輯器右下方將出現一個藍色的進度條。 根據是否啟用了Baked GI或Precomputed Realtime GI,需要完成不同的階段。 關于當前進程的信息顯示在進度條的頂部。
進度條顯示Unity GI程序的當前狀態
在上面的例子中,我們可以看到我們處于5/11的進度中,即Clustering階段,并且仍剩余108個jobs才能夠進入下一個階段6中。各個階段如下所示:
以上階段從左到右,從上到下一步步執行。 需要注意的是:僅開啟Precomputed Realtime GI的話,Baked GI的所有階段將不會執行。 如果僅開啟Baked GI的話,GI程序會執行所有流程(包括Precomputed Realtime GI),這是因為Precomputed Realtime GI階段的處理并不只是為Realtime GI設計,它構建了間接光照所需要的計算環境。**
所以下文中,僅開啟Baked GI的情況下,一些專屬于Realtime GI的參數依然會生效,就是上述這個原因。
如果想要進一步了解GI程序各個階段做了什么,產生了哪些數據,可查看可視化GI數據內容,會有部分相應的描述。
GI參數設置
Lighting Window(menu: Window > Lighting > Settings)是Unity全局照明(GI)功能的主要控制面板。通過Lighting窗口,你可以調整GI進程中的各個方面,根據需要來自定義場景或優化質量,性能和存儲空間。 這個窗口還包括環境光,霧效、光暈等設置。 Lighting窗口有三個選項卡:Scene、Global maps 、Object maps。我們重點要看的是Scene窗口。
Environment
環境照明部分包含天空盒(Skybox),環境光(Environment Lighting)和環境反射(Environment Refletions)的設置。
Skybox Unity中的Skybox有三個Shader可以選擇:
其中Procedural是Unity默認的skybox,由程序控制,無法自定義效果,配合Sun Source綁定一個平行光可以實現晝夜變化的天空效果。6 Sided和Cubemap是傳統的Skybox做法,Sun Source無效。
Environment Lighting 該項控制Ambient Light:為物體提供環境光漫反射光照。顏色來源可以是上面設定的Skybox材質球,可以使固定的顏色或漸變色。具體看“概念篇”內容介紹。
Environment Reflections 該項控制主環境反射設置,本質上是一張所有物體都可以使用的Cubemap。
環境反射與Ambient Light的區別在于,它提供的是逼真的環境光鏡面反射效果,是基于物理的渲染(PBR)中重要的照明效果。
Unity提供Refletion Probe技術,用于捕捉周圍場景的圖像,并將其儲存為立方體貼圖Cubemap。所以Refletion Probe的內容載體是Cubemap。
反射源屬性Source可以設定主環境反射的來源。如果Source為skybox,需要烘焙/預計算后才有效果,過程中生成一個Refletion Probe供所有對象使用,并捕捉當前Skybox圖像,將其保存為一個Cubemap。若是Custom,需要手動指定一個Cubemap,可以立即看到效果。
反射強度Intensity Multiplier:控制主反射源的反射強度。
Bounces屬性會影響場景中所有Refletion Probe的烘焙效果。如果場景布置了多個交錯重疊的Refletion Probe,該屬性決定了Refletion Probe捕捉的圖像中是否包含其他Refletion Probe的反射。默認是1,則Unity僅考慮初始反射(從反射源屬性中指定的天空盒或立方體貼圖)。
場景Lightmapping Settings
通過Lightmapping Setting面板,可以總體地控制場景的GI各項參數。
Realtime GI
Indirect Resolution間接光分辨率:物體單位表面積占Dynamic Lightmap的像素數量。 增加此值可提高間接光的視覺質量,但也增加了烘烤光照貼圖所需的時間。此值對烘焙時間的影響最為嚴重, 想要快速預覽效果可降低此值。默認是2,一般建議戶外大場景0.5~1,室內場景2~3。
Directional Mode:默認為Directional,會額外烘焙一張directional map,儲存物體表面上每個點上的的主導入射光的信息。配合烘焙的lightmap,起到加強凹凸感的作用。Realtime GI和Baked GI都可開啟,但實際作用并不大,實時光照帶來的凹凸效果更明顯。
Indirect Intensity:控制所有間接光強度的一個總控參數,數值介于0和5之間。大于1的值會增加間接光的強度,而小于1的值會降低間接光的強度。 默認值是1。注意:對于Mixed Lighting,烘焙后再調節該參數是無效的,因為間接光已經烘焙在lightmap上了。
Albedo Boost:調節此值可控制表面之間反射的光線量,增強場景中材質的反照率。此值越大,材質的Albedo越趨向于白色。默認值1是物理上準確的。
Albedo描述了光線擊中表面后會呈現一種怎樣的狀態,比如,在PBR材質中,完全光滑的金屬會吸收所有光線,所以任何光線擊中表面都不會被反射出去,也就不會有間接光照的效果。又比如,藍色的光線擊中Albedo為黃色的表面,發射出去的光線會呈綠色。
Baked GI
接下來了解Baked GI的參數:
lightmapper:使用此選項指定要使用哪個內部光照計算軟件來計算場景中的光照貼圖。 選項是Enlighten和Progressive。 默認值是Enlighten。Progressive漸進式光照系統是用來快速預覽效果的,但該功能仍處于試驗階段,可暫時忽略。
Lightmap Resolution :物體單位表面積占lightmap的像素數量。 增加此值可提高Lightmap的質量,但也增加了烘烤時間。 默認值是40。此值最后還要跟每個物體上的Scale In Lightmap換算,才是能確定該物體最終占用的lightmap像素是多少。
Lightmap Padding:lightmap上儲存的是不同物體的光照信息,物體的像素塊之間需要隔開一些像素,防止紋理采樣時發成錯誤。這個padding就是物體隔開的像素數量。
Lightmap Size: 每張lightmap最大的尺寸值。如果Lightmap Resolution越高,而Lightmap Size的尺寸不足以“裝下”這么多的像素,就最烘焙成好幾張Lightmap。在項目中,除了lightmap的大小需要控制外,還要盡量減少lightmap的數量,因為這會影響網格的合并。此值最大不能超過2048。
Compress Lightmaps: 勾選了此選項,將會對烘焙好的Lightmap進行壓縮,大大減少了圖片內存大小,但質量也會降低,需要視實際情況而定,做最優的選擇。一般建議是要勾選的,若效果不滿意,可以考慮提高Lightmap Resolution和Lightmap Size。如果非得要去掉勾選,不進行壓縮,建議得把Lightmap Resolution和Lightmap Size降低到合適的范圍以減少內存大小。
Ambient Occlusion:當勾選時,開啟表面間的環境光遮蔽效果。這僅適用于由GI系統計算的間接照明。 此設置是默認啟用的。
Final Gather: 啟用Final Gather時, 會提高lightmap的視覺質量,比如消除噪點等,但是會增加額外的烘焙時間為代價。具體原理我也沒搞懂。。
Lightmap Parameters:除了Lighting窗口的GI參數,Unity還提供了一組常規參數來進一步地控制GI程序, 菜單中有做好的預設值可供選擇,一般來說使用這些預設就足夠了,默認是Default-Medium。但您也可以新建一個Lightmap Parameters文件來自定義你的設置。 有關更多詳細信息見下文。
物體Lightmapping Settings
除了在Lighting Window面板全局地控制場景的GI參數外,有些參數還可以針對個別物體進行設置。 選中GameObject的Mesh Renderer組件,開啟lightmap Static,便會展開Lightmap Settings欄,這里面的參數會結合Lighting Window的場景GI參數,最終決定該物體以怎樣的GI參數參與到GI程序中去。
Scale In Lightmap:默認是1,對應Lighting Window中的Lightmap Resolution。
假如Lightmap Resolution為40,物體的Scale In Lightmap為2,假設物體是1x1x1米的立方體(6個面),那么最終該物體占用的lightmap像素為:40x2x6 = 480個像素。
Proprotize Illumination:選中此框可指示Unity始終在光照計算中包含此對象。 用于強烈發射的物體,以確保其他物體將被該物體照亮。
Lightmap Parameters可以分配給Lighting Windows的場景設置,也可以應用于場景中的單個GameObject實例。
Lightmap Parameters用于存儲控制GI功能的參數的一組值, 定義和保存GI的不同參數值,以便在不同情況下使用。 在創建時,它們存儲在Project文件夾中,可以通過Project窗口進行訪問。
通過創建Lightmap Parameters,針對不同類型的GameObjects,或針對不同平臺和不同場景類型(例如,室內或室外場景)優化的預設,一般來說,使用Unity做好的幾組預設便能應付大多數情況。
其參數過于復雜,不作解析,有興趣可以去官網查看。
其它渲染相關的參數設置
Light Inspector
只介紹與烘焙有關的部分參數:
Mode:用于指定該燈光以什么方式進行照明,有Realtime、Mixed、Baked三種。對應的要看Lighting Window開啟的是哪種光照方案。
Intensity:燈光光照強度,Directional light 默認值為0.5, Point, Spot or Area light 為1。
Indirect Multiplier:間接光強度,不多解析。 應用:當處于陰暗環境(例如洞穴內部)需要更亮的間接光才能使細節可見時,這是非常有用的。 或者,如果要使用“Realtime GI”,但要限制單個實時燈以使其僅發射直射光,可將Indirect Multiplier設置為0。
Cull Mask:可以有選擇地排除不受燈光影響的對象。注意:該特性只適用于實時光照,烘焙過程是不會考慮該選項的。
Shadow Type:設置這個燈光是否投射硬陰影(Hard Shadows),軟陰影(Soft Shadows)或根本沒有陰影(No Shadows)。該設置對于烘焙來效果同樣適用。Hard Shadows會產生邊緣生硬的陰影。與Soft Shadows相比,硬陰影并不特別真實,但是計算較為簡單,使用條件限制相對較低。
當燈光為Baked模式,Shadow Type設置為軟陰影時,將會烘焙出柔和的陰影到Lightmap中。 Baked/Mixed 燈光下的Soft Shadows有Baked Shadow Radius參數可以調整,該值越大,烘焙的陰影越柔。
若燈光為Realtime,則是實時陰影計算,請注意,實時陰影的計算非常耗性能,開軟陰影的代價會非常高,而且好需要看項目的質量控制設置(QualitySettings)是否允許這樣做,所以一般啟用得是Hard Shadows。
Shadow
要對物體投射陰影,除了要Light的設置外,還需要對物體進行相應設置。 場景中的物體的Mesh Renderer組件也具有Cast Shadows和Receive Shadows屬性,必須根據需要啟用它們。
主要注意的是,Unity烘焙的陰影都是根據“雙面”的方式生成的,所以上面所謂“單面”“雙面”的情況只適用于實時陰影。 如果你發現烘焙前和烘焙后的陰影差別很大,檢查是不是因為這個原因。
還有,烘焙并不能控制mesh是否接受投影,所有參與烘焙的物體會接受陰影。
技巧:Shadows only 模式適用于:可以用一些物體來投射出想要的陰影效果,但并不需要渲染他們。需要強調的是,實時陰影模式下,他們都是“單面”投影的。
Scene窗口的可視化GI數據
Scene 窗口有許多繪圖模式來幫助您可視化不同方面的場景內容。 其中包括一組模式,讓你看到GI是如何影響你的場景。
默認的是Shaded模式,也就是正常渲染的效果,此外常用的還有Overdraw,Mipmaps等,但不在本文討論范圍,有興趣可以自己試試。 與GI有關的模式是分為三類: Global Illumination:顯示GI程序的一些必要數據以及Dynamic Lightmap的分辨率:Systems、Clustering、Lit Clustering Realtime GI:顯示Realtime GI的數據以及Dynamic Lightmap的分辨率。 Baked GI:顯示Baked GI的數據以及Lightmap的分辨率。
最下方Show Lightmap Resolution復選框控制是否顯示lightmap的分辨率,其作為棋盤格的形式與相應的數據混合顯示。 比如你選擇的是Realtime GI的Indirect模式,并勾選了此選項,就會顯示Indirect數據以及Dynamic Lightmap的棋盤格。 通常來說,該選項是這里面最有用的功能,實時查看lightmap的分辨率,有利于我們對光照效果精度的把控。
需要再次強調,Baked GI會執行GI程序的所有流程,所以Realtime GI的數據也是可以看到,但反過來僅開啟Realtime GI,就看不到Baked GI的數據。 想要查看相應的可視化數據,需要確保GI程序已經完成了該步驟的計算。例如你要看可視化的Clustering數據,需要等待GI Process中5/11步驟執行完畢。具體見上文GI Process。
當你關掉Unity重開,想要再看這些數據,需要重新執行GI程序,因為這些數據緩沖已經被清除。 你可以打開Auto Generate開關,并在GI程序執行過程中,切換到這些GI視圖模式,可以看到他們是怎么生成的。
下面來主要介紹幾個常用的模式:
Shaded
System
GI進程中3/11Create Systems階段,將根據物體的接近度和光照貼圖參數自動將場景細分為多個System,換句話說,System即是共享相同的Realtime Lightmap的對象組。 這是為了在更新間接照明時,實現多線程和優化性能。 上圖的可視化顯示了不同顏色的System。
UV Charts
這顯示了在Realtime GI進程的4/11Create Atlas階段時使用的優化的UV布局。 Enlighten會自動生成物體的第三套UV用作生成Dynamic Lightmap,UV Charts表示其實就是lightmap中屬于物體自身的一小塊紋理區域,詳細可見官方教程,優化UV Charts的布局有利于減少dynamic lightmap的大小,從而提高計算速度,是Realtim GI的重要優化策略。 UV Charts場景視圖模式可幫助您識別需要UV或縮放比例調整的幾何圖形(使用“Lightmap Parameters”中的“Resulotion”參數更改比例,或者更改Indirect Resolution來全局調整)。 此視圖在調整Realtime Lightmap分辨率時也很有用。 每個UV Charts都有不同的顏色。
Clustering
這顯示的是Enlighten從Lightmap Static物體中生成的Clustering。 Enlighten在5/11Clustering階段生成Clustering,被用于計算間接照明。Clustering的數量由Lightmapping Settings的Indirect Resolution和Lightmap Parameters中的Cluster Resolution參數控制。這個過程非常耗費內存和烘焙時間,如果您看到高內存使用甚至報錯或烘烤時間過長,這可能是因為場景中的靜態幾何體被切割成比實際需要的更多的Clustering。你可以通過使用更低級別的Lightmap Parameters,或者適當降低Indirect Resolution來解決該問題。
Baked Lightmap
這顯示了應用于場景物體的烘焙光照貼圖。 棋盤格顯示烘焙的Lightmap分辨率。該視圖可以幫我們看到場景各物體占用的lightmap像素,通過調整場景的Lightmap Resolution和物體的Scale In Lightmap來優化Baked GI的效果,這是Baked GI重要的優化策略。重要的光效明顯的地方,我們應該分配更多的像素,而像一些小的物體,照明不明顯的物體,要減少其分辨率,以最大程度地利用Lightmap的空間。有時,我們還可以選中物體,在Lighting窗口的Object maps欄中可以檢查該物體的Baked Charting,看是否充分利用其空間,有必要時可導回3D MAX等軟件重展第二套UV。
關于Chart,上文已經提過。可以理解成,Chart就是物體在lightmap中屬于自己的那一部分四方形區域。
Light Overlap(Shadowmask Overlap)
還記得Shadowmask模式有一個限制嗎?一張Shadowmask貼圖最多支持記錄4個燈光的陰影遮蔽信息。超出的部分將會被烘焙到lightmap中。
這種模式可以讓你看到所有的靜態燈是否已經被烘焙到了Shadowmask上。 如果一個區域被四個以上的靜態燈點亮,則超出的燈將退回到完全烘烤狀態并顯示為紅色。下面屏幕截圖中,最右邊的聚光燈就是多出的,其陰影信息將被烘焙到lightmap中去。
后記
全局光照的庫存文章到這里結束了,自從進了某廠就沒怎么碰過Unity,不過如果大家有興趣進一步學習,可以留言給我,大家一起進步。
總結
以上是生活随笔為你收集整理的写给美术看的Unity全局光照详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Podfile 文件写法
- 下一篇: dism /online /get-pa