寫給美術看的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的設定外,還需要對物體進行相應設定。 場景中的物體的MeshRenderer元件也具有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全域性光照技術(理論篇)
作者:Kerry
專欄地址:https://zhuanlan.zhihu.com/p/126370177
相關文章
- 寫給美術看的Unity全域性光照技術(理論篇)Unity
- Axios 請求配置引數詳解以及全域性配置示例iOS
- GDC 2019《戰神4》開發解讀:全域性光照
- Unite 2019|Unity的光照烘焙技術(上)Unity
- 寫給大忙人看的死鎖全詳解
- Python 關鍵字global全域性變數詳解Python變數
- 「技美之路 第08篇」圖形 2.4 傳統經驗光照模型詳解模型
- SpringBoot Validation優雅的全域性引數校驗Spring Boot
- 分散式架構篇|一文詳解 OceanBase 2.0 的“全域性索引”功能分散式架構索引
- 寫給前端工程師看的Docker教程-基礎篇前端工程師Docker
- 寫給前端工程師看的Docker教程-實戰篇前端工程師Docker
- 寫給前端工程師看的Docker教程-中級篇前端工程師Docker
- OpenGL 基礎光照詳解
- 常用的 wget 引數詳解wget
- find 命令的引數詳解
- 表單驗證,為避免全域性汙染,少定義全域性變數寫法變數
- OGG引數詳解
- ajax 引數詳解
- flutter 裡面的全域性變數(給web開發者)Flutter變數Web
- 共模電感引數解決方案還是看這篇
- 資料庫大牛李海翔詳解全域性讀一致性技術資料庫
- 一文詳解 OceanBase 2.0 的“全域性索引”功能索引
- apache伺服器全域性配置詳解(全)Apache伺服器
- 電腦顯示器引數詳解 看完秒懂! 顯示器引數怎麼看?
- 全域性變數變數
- Unity的Forward+ FPTL光照剔除解析(四)UnityForward
- Unity的Forward+ FPTL光照剔除解析(一)UnityForward
- Unity的Forward+ FPTL光照剔除解析(三)UnityForward
- 寫給自己看的找素材
- 寫給自己看的Typescript起步TypeScript
- lsblk命令引數詳解
- tar命令引數詳解
- Dockerfile - 引數與詳解Docker
- 函式引數詳解函式
- Flink Checkpoint 引數詳解
- 寫了個全域性變數的bug,被同事們打臉!!!變數
- 怎樣看電腦顯示器的各種引數?常見的電腦顯示器引數詳解
- vue定義全域性變數和全域性方法Vue變數