基於Unity3D的大地形研究(2):資源序列化與材質載入
(先回答一下先前文章評論區的問題,首先本人是興趣使然的獨立開發者,普通學生,這一系列文章是全部開源的,並非為哪家大廠的項目開發,而且我也不認為目前國內哪個大廠可能會使用到這種大地形繪製技術,所以大家就當看個樂吧)
在上一篇文章中,我們已經實現了針對GPU Driven Rendering Pipeline的Cluster Scene Streaming load,然而在上一篇中卻並沒有提供出一套像樣的資源管理方案,那麼在本文中我們將介紹一套基於Unity Editor與.Net Framework的資源非同步載入,序列化反序列化的方案。
因為目前Unity並沒有理想的二進位載入方法,要麼非同步容易出現堵塞,要麼GC極高造成卡頓,因此我們將直接使用.Net Framework提供的載入方法在非同步線程載入二進位模型和貼圖文件。是的,這種方法聽起來非常的「反人類」,完全與Unity自帶的人性化資源管理背道而馳。然而現在我們的GPU Driven RP的渲染方法可以認為本身就是反人類的存在,強行拆分所有靜態模型,模型不再存在「物體」的概念,並且要求所有模型都使用統一的材質,最後所有模型還要暴力的塞到顯存中,等待渲染調用。因此,我們必須在引擎中通過成熟的工具鏈保證引擎既對開發設計人員友好,又不破壞GPU Driven RP的。
其實這篇文章拖了非常久,原因在於為了實現合理的貼圖材質載入和項目管理,本人也是嘗試許許多多的方案,最先考慮的是早期主機上使用的Virtual Texture方法,然而這個方法也是首先被斃掉了,並不是說這個方案不用了,在之後的平坦地形繪製中可能依然會使用到,只是在建築物中需要額外的CPU剔除和顯存回讀操作,之前的文章中介紹過,目前家用PC的主板IO速度非常令人窒息,所以實時的回讀操作基本是不被允許的。然而現在顯存容量卻基本達到了一個夠用的標準,6G-8G是一個比較普遍的理想的容量,部分旗艦級別的顯卡可能在10G到12G左右,大多數情況下顯存容量是絕對夠用的。同時,我們渲染時的貼圖量是不太可能太多的,因為這套管線依然是專註於繪製材質比較簡單重複量比較大的部分,比如岩石,地上的石子,一些背景房屋等等靜態部分,而遊戲中一些可能有互動的部分則依然依靠傳統的渲染管線來代替。
再來說項目管理方面,按照之前文章講過的,在開放大地形的搭建中,我們將會把場景拆分成Sub Scene/Sub Level,可能每個sub level只有幾百萬面,以此來保證流式載入的精確性,因此在本文中我們將會對Sub Level進行統一的管理,保證項目管理的效率。
正如之前所說,傳統的貼圖載入方法是無法滿足需求的,我們將使用二進位手動非同步讀取的方法完成載入。.Net提供給我們的API BinaryReader已經足夠使用了,BinaryReader支持使用相對路徑,這一點非常不錯,在打包時基本上只需要把儲存有項目二進位數據的文件夾複製到打包後的文件夾中即可,比如在現在的項目里這個文件夾被命名為BinaryData,那麼我們直接暴力讀取Assets/BinaryData/即可,在發布時也可以直接把該文件夾複製到發布的文件夾里,配合可視化的序列化工具,對項目管理非常友好。
首先,我們需要整理場景中的材質信息,把這套材質信息儲存到Scriptable Object中,因為材質信息相對輕量級,所以Scriptable Object足可以應付,數據結構大概是這樣的: