Procedure Cloud

遊戲內雲層的渲染在之前大多採用"貼圖+模型"或者"Matt Paint"的方式:

左側的體積雲效果實際是特別的shader模擬光照+模型擺拍,

這種方式非常的不靈活, 跟Guerrilla做KILLZONE時候的方法差不多:

背景雲層也是固定做好的, KILLZONE

, 這種方式做出來的效果相對固定, 當然美術也更可控一些. 但是當我們想要打造更加真實隨機的天氣環境時, 之前的做法就顯得不夠順手了. 畫面效果優秀的Horizon Zero Dawn 提出了一種方法可以巧妙的製作隨機的天氣環境, 讓雲層的渲染可以更加真實.

Cloud Rendering in Horizon Zero Dawn,Guerrilla

Guerrilla的Schneider[1]使用了fBm和Volume Rendering來完成這項任務.由於上篇文章[2]也剛好對Ray Marching做了介紹,所以本篇可以看做是Ray Marching的一個實際應用.

fBm

fBm全稱是Fractal Brownian Motion[3], fBm是一種常用的生成雜訊圖的方法, 其本身的數學特性可以生成很多有意思的圖形. 又由於它本身的分形特性,所以如果對fBm進行Domain Wrap[4]操作,可以生成很多精美的圖像:

Inigo Quiles (2002)

雖然完全使用fBm來做雲層渲染沒問題,但是為了節省計算量,Guerrilla是把一組fBm存儲在3D Texture里,而我試驗用的是UE4,暫時沒有3D Texture,所以我用的是多通道貼圖. 每個貼圖分成多個子塊,使用Z值索引每個子塊:

2D Tile 模擬 3D texture

另外我沒有使用Worley Noise + PerlinNoise,直接用的UE4內置的Noise節點裡的Voronoi Noise:

Worley + Perlin

Voronoi

不是3D texture,每個通道存儲一種Noise

使用RayMarching採樣上述數據,得到一個density值. 接著我們利用這個值計算光照和通透程度.

Lighting

雲團的散射是需要模擬的重點, 根據Beers Law可以近似計算光線經過均勻介質後的耗損:

T = e^{-t} 	ag{1}

另外還需要描述一種光線經過雲團的物理現象: 散射. 雲對光線的散射是各向異性的:

截圖來自Andrew,GDC 2015

Henyey-Greenstein模型在1941年誕生,起初用來解決天文學家計算星系間光的傳播問題. 後來被拿來用於計算雲的各向異性散射特性. 我們可以在公式(1)的基礎上增加進這個計算模型:

HG=frac{1}{4pi}cdotfrac{1-g^{2}}{(1+g^{2}-2gcdot cos(	heta))^frac{3}{2}} 	ag{2}

Energy = T * HG 	ag{3}

基本的光照模型就是如此,Guerrilla那個PPT里還有很多細節優化,有興趣可以深入讀下. 目前我只是簡單的試了下基本框架:

根據Cover值控制雲層濃密

https://www.zhihu.com/video/960240983070445568

加一些擾動可以增加雲的變換,為了明顯點看到特意加快了速度。

https://www.zhihu.com/video/960241393650798592

經過調整後的截圖:


[1]Andrew Schneider, GDC2015, Real-time Volumetric Cloudscapes of Horizon: Zero Dawn, 2015.

[2]Ray Marching 101

[3]Fractional Brownian motion

[4]Inigo Quiles, Domain Warping, 2002.


推薦閱讀:

[UE4]Indirect Lighting Cache(間接光照緩存)
steam發布篇---2
真良心大廠EPIC,頁游廣告又有新素材了!

TAG:計算機圖形學 | 虛幻引擎 | 遊戲開發 |