unity如何往下挖地形_Unreal Engine地形系统辨析(一)
Unreal Engine的地形系統(tǒng)稱之為Landscape,每個(gè)level里面可以存放多個(gè)Landscape的Actor(但不能對(duì)它們進(jìn)行連續(xù)編輯,也就是說相鄰兩個(gè)landscape是不能被同一個(gè)brush修改的)。地形被均勻的切割成多個(gè)小的地塊,這些地塊名為Landscape Component,每個(gè)Component可以持有最多2x2個(gè)SubSection。而每一個(gè)SubSection是由多個(gè)quad組成的,這些quad是地形topology的最小單位。由于地形mesh的頂點(diǎn)信息記錄在heightmap里,也就是頂點(diǎn)紋理中,所以它的分辨率盡量是二的指數(shù)冪。因此quad行和列的數(shù)量肯定是一個(gè)奇數(shù),例如31x31,63x63等,對(duì)應(yīng)的頂點(diǎn)數(shù)量為32x32個(gè)和64x64個(gè)。
相鄰兩個(gè)Component的邊界處的頂點(diǎn)信息是一致的,它可以保證在渲染時(shí)不會(huì)產(chǎn)生crack,當(dāng)然vertex shader中還有相應(yīng)的stitch算法能夠消除由于鄰接的patch使用不同lod而導(dǎo)致的t-junction現(xiàn)象。根據(jù)地形的視覺誤差計(jì)算結(jié)果,每個(gè)LandscapeComponent會(huì)自動(dòng)的選擇對(duì)應(yīng)的lod,高等級(jí)的lod會(huì)比低一個(gè)等級(jí)的lod所對(duì)應(yīng)mesh少一半的quad。所以63x63的quad,只會(huì)有6個(gè)lod(63x63,31x31,15x15,7x7,3x3,1x1),如果想增加lod的數(shù)量,只能去增加subsection的quad數(shù)量,換句說每個(gè)Component最多只能退化成2x2個(gè)quad。這對(duì)于比較大的地形來說drawcall數(shù)量就可能變得很多,因?yàn)榈匦蝐ulling的最小單位是Component,如果是一個(gè)subsection的quad數(shù)量為63x63,且有2x2個(gè)subsection的component,假設(shè)一個(gè)quad是1m的大小,那么一個(gè)component最多可以覆蓋126米的范圍。隨著lod的升高,mesh會(huì)越來越稀疏(即三角形數(shù)量變少),當(dāng)使用最高等級(jí)的lod時(shí),126米的區(qū)域會(huì)用4個(gè)quad來表示。當(dāng)前component如果可見,最多會(huì)形成4個(gè)drawcall(如果這四個(gè)subsection的screen size差異不是很大,它會(huì)自動(dòng)合并成一個(gè)drawcall)。在視錐內(nèi)且不沒有被遮擋的Component一旦很多,那么相應(yīng)的drawcall也會(huì)暴漲。通過調(diào)高subsection的quad的數(shù)量來減少drawcall似乎不是一個(gè)好的辦法,因?yàn)槿绻鹀ulling粒度太大,會(huì)降低culling的效率,導(dǎo)致很多不在視錐內(nèi)或者被遮擋的三角形依然會(huì)被處理。而且由于不同的lod,它對(duì)應(yīng)的mesh的稀疏程度不同,導(dǎo)致drawcall里面處理的頂點(diǎn)數(shù)量也不盡相同。
ue4的實(shí)現(xiàn)是基于金字塔狀的geometry mipmapping的平鋪結(jié)構(gòu),而unity的地形是基于quadtree的層級(jí)結(jié)構(gòu),它們各有各的優(yōu)勢(shì)。首先ue4的地形塊之間數(shù)據(jù)耦合度很小(每個(gè)component擁有自己的weightmap和heightmap,這些數(shù)據(jù)不需要跨component進(jìn)行讀取),它可以為每個(gè)component計(jì)算當(dāng)前幀的lod值,互相比較獨(dú)立,完全能夠并行處理,只是收尾階段要獲取四個(gè)鄰居的lod值,把它們傳給shader用來做stitch。但是unity的實(shí)現(xiàn)需要從根部開始遍歷這顆四叉樹,如果當(dāng)前的等級(jí)滿足要求就不再往下遞歸,直接把當(dāng)前等級(jí)的頂點(diǎn)信息提取出來,應(yīng)用到一個(gè)固定的17x17個(gè)頂點(diǎn)的topology上。這樣就保證了每個(gè)drawcall處理的頂點(diǎn)數(shù)量都是一樣的,只是由于鄰居的lod可能與自身的lod不同,需要選取不同的indexbuffer而已。為了減少topology的模式緩存數(shù)量,lod算法要保證相鄰兩個(gè)patch之間的lod差不能超過一,否則就會(huì)出現(xiàn)crack。而ue4的stitch算法似乎沒有這些顧慮,彈性也因此更大。
由于unity的地形patch是用quadtree管理的,所以為了并行化視錐culling,它需要把quadtree遍歷階段的結(jié)果先緩存起來,放入到一個(gè)線性數(shù)組中,等到后面再與其他的renderer一起處理。反觀ue4的地形,雖然每個(gè)component單獨(dú)管理一個(gè)patch比較靈活,但是drawcall的數(shù)量會(huì)相對(duì)較多,尤其是那些較為平坦的地塊,或者是距離攝像機(jī)較遠(yuǎn)的地塊,基于quadtree的方法可能就只會(huì)使用到一個(gè)16x16quads的patch去表達(dá),而ue4的方案如前所述,由于component覆蓋的區(qū)域面積是固定的,所以它會(huì)生成更多的drawcall,甚至要處理更多的三角形。不僅如此,由于mesh退化程度有限,遠(yuǎn)處的mesh在光柵化后可能會(huì)出現(xiàn)overshading。
現(xiàn)代的桌面顯卡和圖形api對(duì)于drawcall和頂點(diǎn)處理似乎不那么敏感了,但是像素的處理由于量級(jí)太大,所以很難忽略它對(duì)性能的影響,尤其是紋理的采樣和overdraw。ue4方案利用shader的static permutation的功能,有效的降低了材質(zhì)中紋理的采樣數(shù)量。不過如果unity能早日祭出virtual texture(不需要運(yùn)行時(shí)混合多層的紋理)這一利器就另當(dāng)別論了。
總結(jié)
以上是生活随笔為你收集整理的unity如何往下挖地形_Unreal Engine地形系统辨析(一)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 像借呗一样的正规渠道
- 下一篇: pe没有浏览器怎么上网 没有浏览器,如何