現在越來越多的AAA游戲中都實現了逼真的雪的效果,比如戰神4、地平線:黎明時分、荒野大鏢客:救贖2、古墓麗影:崛起等都實現了不錯的雪地效果。今天我們就來探究一下他們的實現方式。現在主流的實現方式都是通過硬件提供的細分功能來實現的。
Batman: Arkham Origins
這個游戲里面沒有地形,只有房頂和城市街道兩種,所以它的做法比較取巧,局限性比較大。
動態生成置換高度圖,主機使用視差映射,PC使用細分技術。
如何生成高度圖?
把會影響雪地效果的物體(有一部分在雪的表面下)使用一個踝關節高的正交相機渲染到一個rt里面。
- 把rt清除成黑色。
- 渲染物體為白色。
- 過濾並把渲染結果累積到另外一張紋理里面。
大體思路就是這樣的,它的優點就是實現簡單,但是也有一些局限就是它只適用於房頂以及平坦的城市街道。當然我們也可以對它進行相應的改進,以支持地形以及有坡度的物體。
Rise of the Tomb Raider
古墓麗影崛起的做法較通用,可以在地形上產生雪跡。在仔細介紹前先統一下術語。
Snow height:在未應用變形之前的雪的高度(vertex.z)
Deformation points:勞拉的腳以及其它產生變形的3D坐標。
Foot height:一個變形點的垂直高度(point.z)
Trail depression:雪跡被踩下去的比原本雪低的那部分。
Trail elevation:由於被踩下去導致雪隆起的那一部分。
Deformation heightmap:一張32位的紋理,1024x1024個像素,存儲變形信息。
Depression depth:abs(snow height – foot height)
Deformation shader:用於生成變形高度圖的compute shader。
Fill shader:用於模擬暴風雪后雪跡被慢慢填充的過程。
Snow shder:用於渲染雪的shader,這個shader會應用變形信息。
有了這些術語,我們接下來看看它是怎么做的。
從上圖可以看出它主要分為三個步驟:
- Deformation shader根據dynmaic_object的defomation point來計算影響的像素信息。
- Fill shader用於修改上面計算好的高度信息,模擬暴風雪將雪跡填平的過程。
- Snow shader用來應用變形高度圖配合細分來實現雪跡效果。
生成高度圖
觀察發現雪跡的形狀可以用一個二次曲線近似,通過把一些 動態物體近似成一些點,變形高度可以通過以下公式計算:
這些變形點累積到deformation heightmap中,deformation shader為每一個點分配一個組,每個組會寫入32x32的一個區域內,並且使用一個原子取最小操作,之所以需要這個是因為多個點的影響的區域 可能會重合。
生成隆起(elevation)部分
為了計算elevation,foot height也是需要的,主要是用來判斷是否能生成雪跡,因為elevation部分是高於雪未經變形的高度的。
為了計算elevation,我們需要知道elevation distance,它是elevation 開始的地方到當前渲染點的距離。如下圖所示:
為了計算elevation distance,我們引入了以下幾個變量:
- Depression distance:變形的中心到depression結束的距離
- Distance from root:變形的點心到當前渲染點的距離,注意它是depression distance和elevation distnce的和。
Elevation的值應該跟雪跡的深度成正比,雪跡越深,那么elevation應該越高。計算公式如下所示:
紋理選擇
為了給雪地一個更隨機真實的效果,三張紋理貼圖應用到了變形的不同部分,如下所示:
到這里,基本的雪的變形效果的實現已經講完了,一些優化細節我們這里就不仔細講解了,感覺興趣的同步可以參考GPU Pro7上的文章。現在我們來說下它的優缺點,優點是實現也比較簡單,支持任意坡度的網格,雪跡的形跡有隆起的部分,以及模擬暴風雪填平雪跡的效果。缺點是它把一個物體當成了一些點的集合,這樣就不容易做一個人死后躺在地上類似的效果,當然也不是不能做就是把一個成當成多個點來解決,但是總體效果會差一些。下面我們來看另外一個解決方案。
Creating Snow Trails in Unreal Engine 4
它的步驟如下所示:
- 使用一個Scene Capture從下向上拍攝一張地形的深度圖。
- 在上一個拍攝的基礎上使用Custom Depth拍攝影響雪跡深度。
- 根據這兩個深度的差值來決定哪些地方會產生雪的軌跡。
- 把上面的結果放到別個一個rt上用來做累積。
- 應用累積后的效果到雪的材質產生雪跡的效果。
從下往上拍攝
根據offset來生成灰度圖
當然這里有一些細節需要處理,我們這里略過不談,感興趣的可以看參考文章中的Create snow trails in ue4來了解細節。當然這個只是個demo實現,並不能應用到實際使用中,需要做很多的改動和優化,主要是借鑒下思路。最終效果如下所示:
現在我們來說下它的優缺點,優點是實現較簡單,適用於所有情況(適用於任意形狀的物體),缺點是這個只是個demo,如果要真正使用中還是有很多細節(坑)要去踩。當然也可以在這個算法上做些改進優化以達到更通用的支持,比如在地形之外的任何物體產生雪跡。
總結
上面列舉了幾個生成雪跡的方案,可以看到都用到了變形以及細分來做,如果硬件機能有限也可以把細分用視差映射來替代,通過分析它們的優缺點,讀者可以根據自己的游戲類型來選擇對應的方案。當然我們也可以在原來的基礎上擴展以及修改達到更好的支持,甚至超越市面上的AAA游戲。如果有其它的方案,也歡迎大家在留言中討論。
參考文章
- https://www.slideshare.net/colinbb/gdc2014-deformable-snow-rendering-in-batman-arkham-origins
- http://tombraider.tumblr.com/post/131825841425/dev-blog-snow-tech-and-houdini-simulations-mike
- GPU Pro 7 Deferred Snow Deformation in Rise Of The Tomb Raider
- https://www.raywenderlich.com/5760-creating-snow-trails-in-unreal-engine-4
- https://www.resetera.com/threads/gamingbolt-graphics-analysis-god-of-war-arguably-the-best-looking-game-of-all-time.35748/page-32