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