前言
在Unity的5.6版本之前的5.x中,主要使用了Geomerics公司的Enlighten【1】來提供實(shí)時(shí)全局照明以及烘焙全局照明,在5.6之后Unity引入了新的Lightmapper——Progressive來提供烘焙全局照明并且提供了更多的混合光照模式,但是Enlighten仍然是Unity中全局照明的主要提供者。
所以,本文就來聊聊Unity5.6以及Unity2017中和Enlighten、混合光照相關(guān)的話題吧。
直接光和間接光
大家都知道在Unity中,我們可以在場(chǎng)景中布置方向光、點(diǎn)光、聚光等類型的光源。但如果只有這些光,則場(chǎng)景內(nèi)只會(huì)受到直接光的影響,而所謂的直接光簡(jiǎn)單理解就是從光源發(fā)出的直接影響物體的光。如果只考慮直接光的影響,則會(huì)缺乏很多光影細(xì)節(jié),導(dǎo)致視覺效果很“平”。而間接光則描述了光子在物體表面之間的反彈,能夠用來增加細(xì)節(jié)以及真實(shí)感。
例如上圖中,位于天花板燈直射光線之外的區(qū)域缺乏光照效果。表現(xiàn)為四壁上沒有明暗細(xì)節(jié),相反此時(shí)直接光范圍之外都是均勻的黑色,而整個(gè)空間同樣也顯得十分平。
而增加了間接光之后進(jìn)行渲染,可以看到光被物體表面反彈,彩色光從一個(gè)表面轉(zhuǎn)移到另一個(gè)表面。表現(xiàn)為紅色墻壁和綠色墻壁(在右側(cè)和紅墻相對(duì),沒在畫面內(nèi))的顏色反映到了場(chǎng)景中的其他表面上,四壁也不再是均勻的黑色,而有了層次感。
全局照明和渲染方程
正如前文所說,在Unity中使用直接光是無法模擬光子在物體表面反彈的效果的,因此Unity使用了Enlighten所提供的全局照明(Global illumination)來提供間接光效果。
所謂的全局照明(縮寫為GI)是3D計(jì)算機(jī)圖形中使用的一組算法的通用名稱,旨在為3D場(chǎng)景添加更逼真的照明。這樣的算法不僅考慮直接來自光源的光(直接光),而且還考慮隨后來自相同源的光線被場(chǎng)景中的其他表面反射的情況,即間接光。
而全局照明可以用一個(gè)稱為渲染方程【2】的復(fù)雜方程來描述:
渲染方程定義了光線是如何離開表面上某個(gè)點(diǎn)的。但是各位也可以看到,這個(gè)積分方程太復(fù)雜以至于無法快速的計(jì)算結(jié)果。因此在具體的實(shí)現(xiàn)上,往往采用了一些近似的方法。
Unity中所使用的Enlighten采用的近似方法是輻射度算法,即假設(shè)存在一組有限的靜態(tài)元素和僅有漫射光傳輸來簡(jiǎn)化計(jì)算。上面的渲染方程就可以簡(jiǎn)化為下面這樣:
這樣,我們就可以將積分計(jì)算變?yōu)橛?jì)算求其他元素的輻射度之和。
其中Bi指的是在i點(diǎn)最終的光,Le是i點(diǎn)本身的光,而兩個(gè)點(diǎn)之前有多少比例的光會(huì)被反彈,則有“form factor”來定義,即公式中的Fij,Lj是J點(diǎn)的光。而pi(輸入法問題,先寫成p)則是一個(gè)和i的材質(zhì)屬性相關(guān)的參數(shù)。
這樣,這個(gè)方程就比較好理解了,同時(shí)計(jì)算相比之前的渲染方程也簡(jiǎn)單了很多。
而有了簡(jiǎn)化的方程之后,Enlighten在計(jì)算全局光照時(shí),會(huì)將場(chǎng)景分組到便于并行處理的system中。接下來,每個(gè)system被切割成離散的cluster。
在計(jì)算光照時(shí),Enlighten將場(chǎng)景視為一組cluster。而場(chǎng)景內(nèi)的cluster則會(huì)以一種層級(jí)關(guān)聯(lián)的結(jié)構(gòu)來組織,并且會(huì)對(duì)其映射的靜態(tài)幾何體的albedo進(jìn)行采樣,之后在Light Transport階段計(jì)算cluster之間的關(guān)系以使得光在cluster之間進(jìn)行傳遞。
這樣看上去全局照明方案已經(jīng)完美的解決了間接光的問題,但是預(yù)計(jì)算實(shí)時(shí)GI的代價(jià)仍然很高,針對(duì)移動(dòng)平臺(tái)這樣相對(duì)比較低端的設(shè)備,就需要有更加優(yōu)化的解決方案。所以將靜態(tài)對(duì)象的光照信息烘焙到lightmap上,同時(shí)保持對(duì)動(dòng)態(tài)對(duì)象使用實(shí)時(shí)光就變成了一個(gè)不錯(cuò)的方案。而這就是我們下文中要說的混合光照。
混合光照
使用混合光照和直接使用烘焙的lightmap有什么區(qū)別呢?簡(jiǎn)單來說,選擇“混合”烘焙模式,會(huì)將標(biāo)記為靜態(tài)的GameObject受到的來自混合光源的光照信息保存為L(zhǎng)ightmap。 然而,與標(biāo)記為“烘焙”的燈光不同,混合光源也會(huì)為場(chǎng)景中的非靜態(tài)(動(dòng)態(tài))GameObject提供實(shí)時(shí)的直接光照。
在Unity5.x的版本中,光源就已經(jīng)有了混合模式的選擇。但是直到Unity5.6版本,混合模式又變成了4種子模式。而到了Unity2017版本,則變成了3種子模式——shadowmask的兩種模式的設(shè)置被放到了Quality Setting內(nèi)的Shadow下。如下圖所示,分別來自Unity5.5、Unity5.6以及Unity2017.3三個(gè)版本的Lighting窗口截圖。
可以看到Unity5.6之后的版本,混合光照的模式增加了Baked Indirect、Distance Shadowmask、Shadowmask、Subtractive這些子模式(2017版本后Distance Shadowmask的設(shè)置放到了Quality Setting中)。
首先我們可以先來看看Subtractive模式,因?yàn)镾ubtractive模式也是5.6之前Unity所使用的混合光照模式。
例如在Unity5.5中,我們?nèi)绻麑⒐庠丛O(shè)置為mixed來開啟混合光照,和在5.6之后選擇Subtractive模式開啟混合光照是一樣的。
那么現(xiàn)在就可以安心的使用混合光照了嗎?
我們可以來看看一個(gè)在這種模式下常見的問題:
即使用點(diǎn)光開啟mixed模式時(shí),左下角的動(dòng)態(tài)對(duì)象cube并沒有產(chǎn)生由點(diǎn)光產(chǎn)生的實(shí)時(shí)陰影。
這個(gè)聽上去并不符合預(yù)期,因?yàn)閙ixed光照模式下對(duì)動(dòng)態(tài)對(duì)象顯然要提供實(shí)時(shí)的光照效果,也就是預(yù)期應(yīng)該是像下圖這樣產(chǎn)生點(diǎn)光造成的陰影。
那么這是為什么呢?這其實(shí)是因?yàn)樵?.6之前的混合光照,以及5.6之后使用subtractive模式的混合光照只能在"只有"一個(gè)方向光(Directional light)的時(shí)候才能正常工作。
subtractive模式的另一個(gè)問題就是烘焙的結(jié)果中沒有高光,這是因?yàn)檫@種模式不僅僅烘焙了間接光,而且它還會(huì)烘焙直接光,因此也就無法提供高光效果了。所以可以看到在上面的截圖中,并沒有高光的效果。
正是由于這種混合光照模式的不足,所以Unity5.6之后又引入了更多的混合光照模式,以滿足大家的需求。
但是,作為開銷最小的一種混合光照模式,subtractive模式仍然有被保留的必要。在一些對(duì)性能要求高過對(duì)效果的要求時(shí),subtractive模式仍然不失為一個(gè)不錯(cuò)的選擇。
混合光照新模式-Shadowmask
Unity的新的混合光照機(jī)制的一個(gè)重要功能便是對(duì)Shadowmask【3】的支持了。混合光照開啟shadowmask模式的情況下,Unity會(huì)額外生成一套shadowmask貼圖,它每個(gè)紋素的4個(gè)通道可以分別用來保存4盞不同的光源。
如圖,這張shadowmask保存了2盞光源的信息,一個(gè)主方向光和一個(gè)點(diǎn)光。
Shadowmask的主要功能本質(zhì)上十分容易理解,它解決了之前subtractive模式下無法完成的事情。Shadowmask不僅僅可以處理方向光,而且還可以正確的處理點(diǎn)光和聚光在混合光照條件下的表現(xiàn)。
可以看到左下角的動(dòng)態(tài)對(duì)象cube產(chǎn)生了由mixed模式下的點(diǎn)光產(chǎn)生的實(shí)時(shí)陰影。
同時(shí),由于沒有對(duì)直接光進(jìn)行烘焙,因此能夠在運(yùn)行時(shí)提供正確的高光效果。
而有些朋友如果打開Mixed Lighting的子mode選擇菜單的話,在5.6版本中還會(huì)看到另一個(gè)和shadowmask類似的選項(xiàng)——Distance Shadowmask。
那么Distance Shadowmask和Shadowmask又有什么區(qū)別呢?
這就和陰影距離(Shadow Distance)以及混合光照下陰影是如何產(chǎn)生的有關(guān)了。
我們?cè)贓dit->Project Settings->Quality設(shè)置中可以找到Shadow Distance的設(shè)置,在實(shí)時(shí)光模式下,只有在Shadow Distance范圍內(nèi)的物體才會(huì)有陰影的影響。
而在混合光照-Shadowmask模式下,靜態(tài)物體和靜態(tài)物體之間的陰影是通過shadowmask貼圖來產(chǎn)生的。而對(duì)于靜態(tài)物體接收的動(dòng)態(tài)物體產(chǎn)生的陰影,則只有在shadow distance范圍內(nèi)動(dòng)態(tài)物體才會(huì)產(chǎn)生實(shí)時(shí)的shadow map陰影。而動(dòng)態(tài)物體之間的陰影,同樣需要在Shadow Distance范圍內(nèi)來產(chǎn)生。至于動(dòng)態(tài)物體如果要接收靜態(tài)物體的陰影,則需要借助light probe的幫助。
如上圖所示,在靜態(tài)的墻和地面之間,由shadowmask提供了陰影。
至于那三個(gè)動(dòng)態(tài)物體cube,在沒有l(wèi)ight probe的情況下,左下角的cube無法接受到靜態(tài)墻體的陰影。而右邊的兩個(gè)cube之間則有實(shí)時(shí)的shadow map陰影,并且它們也在靜態(tài)墻壁上投下了實(shí)時(shí)的shadow map陰影。
而如果使用Distance Shadowmask模式的話,各位猜猜哪一種陰影產(chǎn)生的方式會(huì)發(fā)生變化呢?
答案其實(shí)很簡(jiǎn)單,首先肯定和Shadow Distance相關(guān),其次肯定是和實(shí)時(shí)的shadow map和烘焙好的shadowmask之間的切換相關(guān)。嗯,答案呼之欲出——在distance shadowmask模式下,處于shadow distance范圍內(nèi)的靜態(tài)物體也會(huì)實(shí)時(shí)的產(chǎn)生shadow map陰影,這一點(diǎn)和動(dòng)態(tài)物體一樣,因此無論是靜態(tài)物體之間還是靜態(tài)物體和動(dòng)態(tài)物體之間都會(huì)產(chǎn)生實(shí)時(shí)的shadow map陰影。而一旦超出了shadow distance的范圍,則靜態(tài)物體的陰影會(huì)從shadowmask中獲取。
如上圖所示,可以看到靜態(tài)的墻和地面之間的陰影邊緣銳利了,不像之前從Shadowmask獲取的陰影,由于分辨率的原因可能會(huì)更加模糊,此時(shí)已經(jīng)是實(shí)時(shí)的Shadow Map陰影了,因此邊緣更加清晰銳利。而且左下角的cube已經(jīng)可以接受到靜態(tài)墻體的實(shí)時(shí)陰影了。
不過正如我剛才提到的,Distance Shadowmask和Shadow Distance以及兩種陰影產(chǎn)生的方式有關(guān),那么就有可能會(huì)出現(xiàn)一種瑕疵~即在Shadow Distance的內(nèi)外,會(huì)有兩種不同的陰影,而Shadowmask產(chǎn)生的陰影由于分辨率的原因往往更加模糊,例如下面這樣:
可以看到墻壁產(chǎn)生了兩種不同的陰影。因此這個(gè)問題各位在開發(fā)過程中可能也要關(guān)注一下。
另外,Distance Shadowmask和Shadowmask相比,性能上的開銷顯然要更大一些,這也不難想象,畢竟還有很多靜態(tài)物體也會(huì)產(chǎn)生實(shí)時(shí)陰影嘛。那么我們可以簡(jiǎn)單的對(duì)比一下兩者在Draw Call上的開銷:
可以看到,右側(cè)的Distance Shadowmask的drawcall開銷要遠(yuǎn)遠(yuǎn)高于shadowmask。因此,在移動(dòng)設(shè)備上采用shadowmask而不是開銷更高的Distance Shadowmask對(duì)于追求性能的情況更加適用。當(dāng)然,Unity2017之后,Distance Shadowmask和Shadowmask的設(shè)置已經(jīng)移到了Quality Setting中了,這意味著我們可以在運(yùn)行時(shí)動(dòng)態(tài)的切換這兩種模式了。
void OnTriggerEnter(Collider other) { if(QualitySettings.shadowmaskMode == ShadowmaskMode.Shadowmask) { QualitySettings.shadowmaskMode = ShadowmaskMode.DistanceShadowmask; }else { QualitySettings.shadowmaskMode = ShadowmaskMode.Shadowmask; } }
當(dāng)然,無論是Distance Shadowmask還是Shadowmask,它們都可以在Shadow Distance之外提供來自Shadowmask的陰影,雖然較之實(shí)時(shí)陰影要模糊一些。因此,對(duì)于需要遠(yuǎn)方也要產(chǎn)生陰影效果的項(xiàng)目,Shadowmask模式是一個(gè)很好的選擇。
混合光照新模式-Baked Indirect
下面還剩下最后一個(gè)混合光照模式——Baked Indirect【4】。事實(shí)上這個(gè)混合模式的名字就已經(jīng)十分直白了——它只烘焙間接光,其他的全部是實(shí)時(shí)的。Shadowmask貼圖?不存在的。
因此我們有了實(shí)時(shí)光、實(shí)時(shí)陰影等等。所以,在Shadow Distance的范圍之內(nèi)和實(shí)時(shí)光下效果一樣,陰影是實(shí)時(shí)的shadow map,并且在shadow distance之外不會(huì)有陰影產(chǎn)生——哪怕是分辨率比較低的模糊陰影也沒有。
可以看到在Shadow Distance范圍內(nèi)的墻的陰影十分清晰,但是在范圍之外則已經(jīng)沒有陰影了。同時(shí),這種混合模式的開銷也很大,因?yàn)樗缓姹毫碎g接光,其他的全部是實(shí)時(shí)的。
總結(jié)
ok,讓我們對(duì)這幾種混合模式做一個(gè)小的總結(jié)吧~可以簡(jiǎn)單的歸納為下面這個(gè)表格【5】。
評(píng)論
查看更多