如何解析基于Unity3D的平坦四叉樹地形與Virtual Texture的分析,相信很多沒有經(jīng)驗的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。
創(chuàng)新互聯(lián)是一家專業(yè)提供平果企業(yè)網(wǎng)站建設(shè),專注與網(wǎng)站制作、網(wǎng)站建設(shè)、HTML5、小程序制作等業(yè)務(wù)。10年已為平果眾多企業(yè)、政府機構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)的建站公司優(yōu)惠進行中。
地形繪制有重復度高,高度控制自由,貼圖復雜度高且有連貫要求等特點。因此必須要使用特化的繪制方法才得以完成繪制。先前Ubisoft Far Cry 5分享的地形繪制方法,使用了QuadTree + Virtual Texture的方法。這樣的方法有很多優(yōu)勢,因為QuadTree提交的都是固定的面片,因此從剔除到提交都完全可以在GPU做,這和我們之前實現(xiàn)的GPU Driven Pipeline思路相仿,而Virtual Texture可以用來表示各種Geometry信息,如高度,漫反,法線,粗糙度等等…… 因此我們也決定使用這樣的技術(shù)來實現(xiàn)大地形的繪制和編輯。
四叉樹的實現(xiàn)對于算法能力扎實的朋友來說,并不算難事,所以這里直接就跳過四叉樹的基本算法原理,拿出部分代碼示例進行講解。因為Virtual Texture加持的原因,在構(gòu)建四叉樹時不需要準備諸如Material ID之類的額外信息,只需要保存當前區(qū)塊的位置坐標,LOD等級(用于切換LOD),以及緩存狀態(tài)(方便遞歸)等,數(shù)據(jù)結(jié)構(gòu)也會非常簡單:
有個小細節(jié)是,為提高內(nèi)存分配性能,四個子節(jié)點是同時分配的,這一點許多習慣C++高級特性的開發(fā)者很容易習慣性的漏掉,但是性能都是從這種小細節(jié)摳出來的,因此一定要注意:
因為使用了Unity提供的手動內(nèi)存分配,因此完全可以使用Burst Compiler提高CPU端計算速度:
準備完畢后直接提交到StructuredBuffer等Compute Shader用到時拿去做剔除繪制工作,渲染結(jié)果如下(Albedo貼圖為局部UV顯示):
Farcry 5提到的Procedural Virtual Texture分為兩部分,第一部分Procedural和Adaptive,基本占了99%的工作量,主要工作量在于各種自動化生成,手動高性能編輯的工具,以及隨玩家移動進行動態(tài)加載卸載的游戲邏輯;第二部分為Virtual Texture,基本占了不到1%工作量,本著柿子先挑軟的捏的精神我們先把Virtual Texture部分簡單實現(xiàn)以下。
所謂Adaptive Virtual Texture一句話總結(jié)就是:存貼圖的對象池。首先,開一張Render Texture作為Index map,存儲一個Scale Offset,也就是一個指向Atlas位置的索引。同時開一張Atlas,當?shù)匦渭虞d到這一部分時,從硬盤加載貼圖到Atlas的某個部分,并將新加載的部分的位置放到Index map中,也就是說使用Index map作為一張?zhí)?。而渲染地形時,直接把當前地形的世界坐標當做UV讀取Index map即可,相當于整個地形使用了一張碩大無比的貼圖,只不過這個貼圖中間大部分地方都是沒加載的,讀取貼圖的偽代碼大致如下:
Texture2D_IndexMap;Texture2DArray _Atlas; SamplerState sampler_Atlas;float4 _IndexMap_TexelSize;//Indexmap 的物理大小float4 TexVT(float2 uv){//將傳入UV轉(zhuǎn)換到Index map的絕對坐標。 uv *= _IndexMap_TexelSize.zw;//讀取Index Map,XYZW四個通道意義分別為:大小比例,橫向偏移,縱向偏移,數(shù)組索引 float4 scaleOffset = _IndexMap[(uint2)uv];//獲取絕對UV的小數(shù)點后部分,得到局部UV偏移 float2 localUV = frac(uv); localUV = localUV * scaleOffset.x + scaleOffset.yz;//使用換算出的UV讀取Atlas float4 value = _Atlas.SampleLevel(sampler_Atlas, float3(localUV, scaleOffset.w), 0); return value;}
這一點在PPT中講的也比較清楚了:
這樣靈活的空間分配和復用方式,可以使用視錐體只加載視野內(nèi)的貼圖,若內(nèi)存和性能充裕且玩家常有高速轉(zhuǎn)動鏡頭的需求,也可以使用攝像機坐標來加載相機四周的貼圖。
同時PPT分享中也指出,由于所有世界空間中緊挨在一起的圖片在IndexMap中也是緊挨的,因此在進行LOD降級時,只需要將四塊區(qū)域的圖片四合一放到另一塊區(qū)域即可,順水推舟,幾乎沒有額外消耗。
這里我們給出一套完整的API:
軟柿子輕而易舉捏完。就只剩硬柿子了。當然,由于工作量巨大,可能需要本人開發(fā)數(shù)月或數(shù)年才能搭建一套有完整工具流程的Virtual Texture,所以這里只給出一個設(shè)想性質(zhì)的原型用作學習探討用途。
從上方的實現(xiàn)不難看出,Virtual Texture的實現(xiàn)過程全部是實時投射的Render Texture,實時加載,實時卸載,實時合并,因此在設(shè)計儲存的數(shù)據(jù)格式時,我們也沒必要儲存一整張繪制好的貼圖,因為這樣會導致游戲的包體完全無法控制,我們只需要提供繪制所需的“種子”即可。
此類種子一般是示例貼圖,Blend Mask貼圖,貼花模型等,這些種子可以大量復用,并且可以使用程序化DCC工具生成,比如這里的RT就是由多張已經(jīng)準備好的貼圖按順序混合,其中每張貼圖都有不同的Tiling密度:
雖然Tilling密集,但由于使用的Mask不同且混合均勻,并沒有出現(xiàn)明顯的重復感:
只用Mask做混合顯然是不夠的,諸如石子,土路,苔蘚等不規(guī)則物,在生產(chǎn)時往往是依賴貼花實現(xiàn)。貼花的實現(xiàn)思想也比較簡單粗暴,直接在面片上方構(gòu)建一個正交投影矩陣,并把模型的Geometry信息“拍扁”到貼圖上:
最終有貼花的貼圖豐富程度更高了:
看完上述內(nèi)容,你們掌握如何解析基于Unity3D的平坦四叉樹地形與Virtual Texture的分析的方法了嗎?如果還想學到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!