《孤岛惊魂5》游戏中的地形渲染技术-网格生成
育碧作為一個年貨大廠,在PCG這方面肯定有很深的積累,在GDC2018的這次分享中,其詳細的介紹了地形在純GPU管線上的實現方式,使得最終能夠得到一個擁有大片懸崖峭壁的真實地形。
本文是筆者看完FarCry5的分享后寫的個人理解,初次學習GPU管線,難免有理解錯誤的地方,希望大佬指正
?
本次分享依次介紹了以下內容
1.GPU Pipeline實現
2.地形渲染
3.懸崖渲染
4.高度圖之外的技術
5.基于屏幕空間的渲染
6.其他地形相關
GPU Pipeline實現
首先說一下單個平面的實現
?
先渲染一個毫無起伏的純平面Mesh
?
在頂點著色器中,根據InstanceID和vertexId可以得到在高度圖上的對應位置,依據此位置去對頂點進行偏移
?
配合貼圖可得到以上效果
?
之后介紹了如何將四叉樹的分化邏輯移到GPU,四叉樹的CPU實現已經介紹過了,這里不再細講
https://zhuanlan.zhihu.com/p/88646346
?
按2km*2km對地形劃分為多個樹結構
分化到最大的地形塊邊長為64米,被稱為一個Sector,總共有160*160個sector,也就是如果所有樹分化到最大,會存在160*160個lod最大的地形塊
正常游戲中會加載大概500個地形塊(包含任意lod等級)
?
正常游戲中,地形一共存在6個lod等級
每一個樹結構都對應一個mipmap,mipmap的層級和lod層級相同
每一個Node的信息都保存在對應Mip等級mipmap的一個像素中
?
像素值是一個16位的Index,根據這個index,可以去Buffer,也就是一個數組中去拿到節點的詳細信息,包括高度范圍,lod信息,貼圖位置信息
如果這個節點是不存在的(地形不是一個標準正方形),則會把一個特殊值賦給index
四叉樹是一個遞歸的結構,但遞歸難以在GPU上實現,所以這里采用該算法的循環形式
一共存在3個存儲節點信息的buffer
首先把根節點放入bufferA,遍歷其中每個節點
?
如果不可分化,則將該節點加入FinalBuffer
?
如果可分化,則將子節點放入bufferB
?
當根節點分化完畢,會互換AB兩個buffer的作用,清空BufferA,然后遍歷bufferB,將子節點加入bufferA。直到處理完所有lod
?
同時也會將每個lod的節點有多少記錄下來
?
這里還說了一個優化買游戲賬號平臺,但筆者沒用過computershader,所以也沒看懂~
同時會生成一個LODMap,每個Sector都會被賦予一個LOD值,用于解決裂縫問題。
?
LOD的值能夠根據FinalBuffer輕松獲取
?
每一個Node會被分為64個Patch,Patch即可視為一個具體的vertex
為16*16的Mesh,經過一系列cull,最終把可視的Patch放到一個RenderLst.
?
遮擋剔除采用的Hiz,主機上會采用純Gpu實現,Hiz的算法知乎上有很多文章,之后有時間我也會按自己的理解寫一下。
而PC則會把CPU上產生的深度圖上傳到GPU(這里我的理解是cpu上有剔除邏輯,會把中間生成的深度圖傳至gpu進一步剔除,但是ppt沒講為什么這么搞)
On console platforms we use a GPU best occluder pass to prime the depth buffer and extracttheHTile.
On PC we have a software rasterized occlusion buffer that we already use for CPU visibility which we upload to atexture.
?
背面剔除,針對每一個Patch,會離線為其生成一個圓錐體,這個圓錐體Patch內所有頂點法線組成的最小圓錐。之后會把信息存到一個Tex中。
?
運行時直接如上計算可以判斷是否需要剔除
?
每一個patch都會存儲它周圍節點的lod信息,如上圖,當前節點lod為3,通過周圍節點的lod可以得到一個值。根據此值對頂點進行干預以解決裂縫問題
?
地洞渲染的思路是地形上開兩個洞,中間的管道采用單獨的mesh渲染
?
這里用到了一個小技巧,如果是洞穴口,則讓坐標除0得到NaN,如果一個頂點坐標為NaN,則用到此頂點的面片都會被discard掉。
總結
以上是生活随笔為你收集整理的《孤岛惊魂5》游戏中的地形渲染技术-网格生成的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 游戏中子弹的工作原理
- 下一篇: 全境封锁UI游戏设计指南