由于現(xiàn)在我們已經(jīng)從光照預(yù)計(jì)算中排除了合適的對(duì)象物體,我們可以進(jìn)行減少剩余光照?qǐng)D表數(shù)量的工作了。
因?yàn)樯晒庹請(qǐng)D表(Charts)是為了包裹靜態(tài)網(wǎng)格渲染器(Static Mesh Renderer)的光照貼圖的UV坐標(biāo),所以一個(gè)對(duì)象所需要光照?qǐng)D表的數(shù)量很大程度上取決于物體需要展開的UV Shell(一些片)數(shù)量。這就涉及到UV展開的問題,它需要保持幾何面上貼圖紋素扭曲度與所需足夠覆蓋貼圖Shell數(shù)量之間的平衡。
Unity沒有我們的介入,它復(fù)雜的展開算法也將經(jīng)常會(huì)得到很好的結(jié)果;然而有些時(shí)候需要提供給我們一點(diǎn)指導(dǎo),這對(duì)于我們理解自動(dòng)展開算法背后的理論過程是很重要的。
考慮下面的闡述:
在上面的圖片中,我們展示了三個(gè)不同的例子關(guān)于一個(gè)對(duì)象物體上的UV是怎么被映射或展開的。
在第一張圖片中,我們可以看到一個(gè)大部分沒有扭曲變形的結(jié)果。我們所使用的帶有格子圖案的紋理貼圖以這種方式被映射:貼圖的每一塊在它所在的那一面都保持正方的形狀。試想一下這個(gè)棋盤紋理貼圖是一個(gè)光照貼圖(一個(gè)光照應(yīng)用于對(duì)象物體的圖片),我們將會(huì)得到一個(gè)看上去視覺上正確并且沒有扭曲的結(jié)果。然而,我們需要6個(gè)UV shell 去得到這個(gè)覆蓋范圍。結(jié)論就是,通過使用Unity的PRGI系統(tǒng),我們將會(huì)得到六張光照?qǐng)D表。不管對(duì)象物體的尺寸大小,每個(gè)光照?qǐng)D表將會(huì)需要一個(gè)4*4的最小紋素,這意味著不管分辨率是多少這個(gè)對(duì)象物體都將會(huì)使用至少96個(gè)紋素。
在第二張圖片中,我們有了一個(gè)不同的問題。對(duì)象物體的UV紋理坐標(biāo)已經(jīng)被映射,以及至于我們有了一個(gè)完整的覆蓋所有面的UV shell。盡管就需要覆蓋對(duì)象物體的光照?qǐng)D表的數(shù)量而言這將會(huì)是最佳的形式,但是它視覺上的效果已經(jīng)被嚴(yán)重的扭曲了。我們很可能看到應(yīng)用到物體表面的紋理貼圖是扭曲的,對(duì)象物體上的各個(gè)表面在UV紋理空間也是重疊的 - 意味著如果我們引用了一張光照貼圖,對(duì)象物體一面的光照可能會(huì)錯(cuò)誤投射到相反面上。這種展開對(duì)象物體UV的方法明顯將不會(huì)給我們一個(gè)可以接受的結(jié)果。
第三張圖片展示了一種展開UV理想的例子。我們有一個(gè)沒有扭曲的結(jié)果:我們的棋盤紋理貼圖的每一片在它所在的那一面都保持著正方的形狀。我們還成功地用一張UV Shell覆蓋了對(duì)象物體的所有面。這是通過連接或縫合在模型上對(duì)應(yīng)的鄰近的幾何邊緣相匹配的UV邊緣來實(shí)現(xiàn)的。
我們?nèi)绻麖木幊痰慕嵌人伎歼@個(gè)問題,在獲得一個(gè)理想的展開UV過程中,我們都做了些什么。首先,為了在對(duì)象物體上生成獨(dú)立的Shell,我們通過正交投影(Orthogonal Projection)讓UV貼圖在物體上。然后分析哪些Shell和物體的邊緣有相連關(guān)系。一旦找到這些邊緣,就把UV Shell的內(nèi)容移進(jìn)去并與相鄰的Shell縫合起來。這就是Unity用靜態(tài)幾何自動(dòng)地展開UV的算法所做的事情。
將光照?qǐng)D表可視化(Visualising Charts)
在優(yōu)化我們的UV展開方式以及光照貼圖的圖表之前,我們需要一種將它們?cè)贓ditor中可視化的方法。光照?qǐng)D表產(chǎn)生于mesh導(dǎo)入管線的UV展開階段。對(duì)于PRGI來說,這些光照?qǐng)D表之后會(huì)在預(yù)計(jì)算過程的幾何階段被打包進(jìn)atlasses圖集中。這時(shí)為了確保它們不會(huì)重疊。一旦預(yù)計(jì)算的幾何階段完成并且可視化數(shù)據(jù)被保存后,我們就能預(yù)覽我們的光照?qǐng)D表了。
如果你是一個(gè)團(tuán)隊(duì)的一部分,使用版本控制(Version Control)進(jìn)行工作,請(qǐng)注意光照?qǐng)D表的信息只會(huì)在本地進(jìn)行緩存。這意味著在各種診斷繪制模式可用之前,在你的機(jī)器上必須要執(zhí)行一次預(yù)計(jì)算。
一種快速地顯示你的光照?qǐng)D表的方法是在Scene視圖下使用UV Charts 繪制模式。
*?在Scene 視圖的左上角,使用 Draw Mode下來菜單去選擇UV Charts選項(xiàng)。
通過使用這種模式,光照?qǐng)D表能夠以不同顏色區(qū)域覆蓋顯示在一個(gè)代表著對(duì)應(yīng)光照貼圖分辨率的棋盤網(wǎng)格紋理貼圖上。如果你想開啟Auto 模式(Window>Lighting>Auto), 改變UV展開參數(shù)將會(huì)被自動(dòng)地計(jì)算并且Scene 視圖將會(huì)隨著結(jié)果而更新。
場(chǎng)景較為復(fù)雜時(shí),從場(chǎng)景視圖中有可能會(huì)漏看光照?qǐng)D表。這時(shí)候我們可以在Lighting視圖中使用預(yù)覽模式查看單個(gè)物體使用的所有光照?qǐng)D表。這樣可以幫我們更精確地評(píng)估這些物體的UV展開結(jié)果,有助于降低光照?qǐng)D表的數(shù)量。具體操作如下:
* 打開Lighting界面(Window > Lighting),選擇Object標(biāo)簽頁
* 從層級(jí)視圖(Hierarchy)中選擇要查看的對(duì)象。
* 查看Lighting界面的預(yù)覽視圖,從最上方的下拉列表中選擇Charting模式。
對(duì)象使用的光照?qǐng)D數(shù)量會(huì)以不同顏色的方塊疊放在對(duì)應(yīng)的淺藍(lán)色UV坐標(biāo)上。
UV展開參數(shù)說明
下面我們一起來看一下幾個(gè)有助于優(yōu)化UV展開的設(shè)置,所有的設(shè)置都是針對(duì)單一對(duì)象,具體設(shè)置方法如下:
* 打開Lighting窗口(Window>Lighting)并選擇Object標(biāo)簽頁.
* 在Hierarchy窗口選擇我們想要看到的物體。
自動(dòng)最大UV距離(Auto UV Max Distance)
Unity的UV展開算法嘗試通過移動(dòng)shell以及縫合UV邊緣這兩種方式一起來簡(jiǎn)化光照貼圖的UV。如果shell在由 Auto UV Max Distance 屬性定義的距離范圍內(nèi),那么UV shell 才會(huì)被考慮。這個(gè)經(jīng)歷范圍是在Unity世界空間單位下所定義的。請(qǐng)記住在我們的教學(xué)場(chǎng)景中,我們假設(shè)一個(gè)單位等于1米。
在許多情況下,默認(rèn)值為0.5個(gè)單位長(zhǎng)度將會(huì)產(chǎn)生比較好的效果。尤其對(duì)于面比較大的大型對(duì)象物體來說,提高這個(gè)值得設(shè)置是很有必要的。這是為了防止本來應(yīng)該被縫合的UV被UV縫合算法排除在外。
增加Auto UV Max Distance這個(gè)值將會(huì)減少所選對(duì)象物體所需的光照?qǐng)D表的數(shù)量。在有明顯的光照貼圖紋素被拉伸的情況下,以及需要生成更多的光照?qǐng)D表進(jìn)行覆蓋的情況下,降低這個(gè)值是很有用的。在UV Charts場(chǎng)景繪制模式通過使用覆蓋的棋盤網(wǎng)格圖,這些改變的結(jié)果很容易被評(píng)估。尋找到合適的平衡點(diǎn)通常需要一些嘗試。
自動(dòng)最大UV角度(Auto UV Max Angle)
光照UV shell 縫合的計(jì)算會(huì)以相應(yīng)mesh鄰面之間的角度為基礎(chǔ)。Auto UV Max Angle定義共享一個(gè)UV邊緣的面之間允許的最大角度,并使用內(nèi)角計(jì)算。如果背面之間的角度大于此值,這些UV shell將不會(huì)被縫合。
提高這個(gè)值將更有可能促使Unity的UV展開算法合并了光照UV圖。因此調(diào)節(jié)Auto UV Max Angle 這個(gè)值對(duì)于減少所選物體需要的光照?qǐng)D表的數(shù)量是一種很好的方式。然而,如果設(shè)得太大,有時(shí)會(huì)出現(xiàn)貼圖被拉伸的情況。降低 Auto UV Max Angle 這個(gè)值將會(huì)使得UV展開算法合并UV邊緣的可能性變小,將會(huì)生成更多的光照?qǐng)D表但是拉伸的情況會(huì)減少。再一次說明,在UV Charts場(chǎng)景繪制模式通過使用覆蓋的棋盤網(wǎng)格圖,對(duì)于評(píng)估我們所使用的合適的值是一種很好的方法。
預(yù)存儲(chǔ)UV(Preserve UVs)
在一些情況下,通過使用auto unwrapper不太可能獲得一種理想的展開效果。我們可能會(huì)得到這樣的結(jié)果:過多的光照?qǐng)D表或者在我們的光照貼圖上產(chǎn)生了嚴(yán)重的扭曲(當(dāng)在GI Charts繪制模式下進(jìn)行可視化拉伸檢查)。在這些情況下,在我們的模型文件中的UV01通道中去手動(dòng)地創(chuàng)建UV可能是很有必要的。這必須要在其它工具中完成。
如果出現(xiàn)這種情況,可以在Preserve UVs選項(xiàng)讓Unity的UV展開算法強(qiáng)制預(yù)存模型UV01通道定義的UV Shell。
要注意的是,這些Shell會(huì)被重新打包以節(jié)省光照貼圖空間,它們會(huì)被單獨(dú)解開并預(yù)存儲(chǔ),而非僅僅記錄光照貼圖內(nèi)的坐標(biāo)信息。
使用這個(gè)功能時(shí)必須小心,當(dāng)指定的光照UV貼圖包含大量的UV Shell時(shí),這個(gè)功能可能會(huì)讓預(yù)計(jì)算的時(shí)間加長(zhǎng),這時(shí)因?yàn)樘^了由Unity 中 auto unwrapper 提供的UV合并步驟,并且我們手動(dòng)的UV布局會(huì)被預(yù)存儲(chǔ)。記住最好的結(jié)果是盡可能的降低UV Shell,因此這樣會(huì)減少光照?qǐng)D表的數(shù)量,同時(shí)將UV貼圖保持在可接受的拉伸范圍內(nèi)。
忽略法線(Ignore Normals)
在某些情況下,網(wǎng)格導(dǎo)入器可能會(huì)拆分幾何體,這也會(huì)影響到光照?qǐng)D表的數(shù)量。例如,如果某個(gè)網(wǎng)格有非常多的三角面,Unity可以為了性能將它分割成幾個(gè)獨(dú)立的子網(wǎng)格。通常這么做是為了符合特定的硬件需求,比如為了減少每個(gè)Draw Call中的三角面數(shù)量。拆分通常發(fā)生在相鄰的網(wǎng)格面之間法向角度有較大變化的區(qū)域,比如銳角邊(Hard Edges)。這樣拆分網(wǎng)格的方式會(huì)在模型導(dǎo)入流程中執(zhí)行。在此過程中,光照?qǐng)D表可能會(huì)被拆分,因?yàn)楣庹請(qǐng)D表中的邊可能會(huì)被分開,導(dǎo)致生成多個(gè)shell,而這又會(huì)產(chǎn)生額外的光照?qǐng)D表。
有時(shí)通過這種方式對(duì)光照?qǐng)D進(jìn)行拆分并不理想,得到的結(jié)果會(huì)增加光照?qǐng)D數(shù)量并加長(zhǎng)預(yù)計(jì)算的時(shí)間,還有可能在照明的接縫處造成不必要的視覺假象。在這種情況下,啟用Ignore Normals選項(xiàng)有助于防止光照?qǐng)D在預(yù)計(jì)算的時(shí)候被拆分開來。
請(qǐng)注意,這個(gè)選項(xiàng)僅對(duì)預(yù)計(jì)算實(shí)時(shí)光照(PRGI)有影響,物件被拆分的網(wǎng)格仍然會(huì)被保留以用于其它用途。
大場(chǎng)景迅速迭代(Faster iteration in larger Scenes)
復(fù)雜的場(chǎng)景可以包含成百甚至上千的靜態(tài)對(duì)象物體。為這些對(duì)象物體生成光照?qǐng)D表atlases圖集可導(dǎo)致光照預(yù)計(jì)算變得緩慢并且會(huì)對(duì)我們的場(chǎng)景迭代速度產(chǎn)生負(fù)面的影響。
當(dāng)對(duì)物體進(jìn)行UV展開實(shí)驗(yàn)時(shí),將你想要實(shí)驗(yàn)的對(duì)象物體隔離到一個(gè)空?qǐng)鼍爸?,這樣我們可以用最短的預(yù)計(jì)算時(shí)間來快速地迭代。當(dāng)我們所決定使用的UV展開設(shè)置之后就可以被回收并且可應(yīng)用于我們?cè)瓉韴?chǎng)景中同類型的其他對(duì)象物體。當(dāng)為一個(gè)場(chǎng)景準(zhǔn)備光照時(shí)以這種方式開展工作可以大大節(jié)省時(shí)間。具體操作如下:
* 打開包含在例子工程中的LightingTutorialStart場(chǎng)景。
*?在Hierarchy窗口中選擇其中一個(gè)叫做HouseBig02的對(duì)象物體。這些對(duì)象物體在Environment>Structures>Houses下已經(jīng)被分組。
* 通過按下Ctrl+C(Cmd+C?on Mac)粘貼這個(gè)對(duì)象物體到剪切板.
* 通過按下Ctrl+N創(chuàng)建一個(gè)新的場(chǎng)景(Cmd+N?on Mac)。
*?如果提示你保存你的更改,如果你對(duì)你當(dāng)前的場(chǎng)景進(jìn)展比較滿意選擇Yes,如果你不想保存,選擇No
* 在先創(chuàng)建的場(chǎng)景中,通過按下Ctrl+V(Cmd+V?on Mac) 從剪切板中粘貼 HouseBig02。
* 打開 Lighting 窗口 (Window>Lighting)然后選擇Scene標(biāo)簽頁。
* 通過開啟Auto選項(xiàng)框來啟動(dòng)自動(dòng)預(yù)計(jì)算模式。
* 現(xiàn)在選擇?Object 標(biāo)簽頁。
*在左上角的Object標(biāo)簽頁,從下拉菜單選擇 Charting。
* 拉大預(yù)覽視圖區(qū)域來查看對(duì)象UV是怎么被展開的。