GPU Gems1 - 7 无数波动草叶的渲染
本文部分參照該文章https://zhuanlan.zhihu.com/p/35974789
1.引言
本章介紹了一種靈活的,廣泛應用的草模擬。該方案渲染的草不僅生長得自然,也能夠逼真地在風中舞動,而且性能很高。
2.概述
首先,需要意識到,對單個草葉的細節建模意義不大,因為那樣大片草地需要的多邊形數目會太多。所以,我們必須建立一個符合以下條件的簡單而有用的替代方案:
- 許多草的葉片必須由少數多邊形表示。
- 草地必須從不同的視線看起來顯得密集。
而要做到讓場景不依賴于攝像機的位置和方向,可以把一些草葉組合起來,表示在一個紋理中,并將多個紋理組合起來,且在結果中單個的多邊形不應該引起注意。當觀察者四處活動時,通過將草體加入混合操作或者移除混合操作,以在距離范圍內增加或刪去草體,來保證整個草地的渲染效果具有穩定的視覺質量。
3.草體的準備
? ? 3.1 草的紋理
草的紋理,應該是一些一簇一簇聚集叢生的草,否則,會出現大片的透明區域。需在透明的alpha通道上畫實體草莖。在彩色通道中,用深淺不同的綠色和黃色,來較好地區別各個單獨的葉片,也應該模擬不同情況的草葉:長得好的和長得差的、老的和嫩的,甚至區別葉片的前面與后面。
下圖是一個草地紋理的示例。
? ? 3.2 草體
對于線性排布,如果從垂直于多邊形的方向觀看場景,就會立刻穿幫,看出草地多邊形的結構是線性排布的。另外這種情況下草地會看起來非常稀疏。只有在攝像機自動導航,或者渲染無法到達的遠距離草地時,才會考慮這樣的排布。為了保證獨立于當前視線的良好視覺質量,我們必須交叉地排布草地多邊形。已證明,使用星型結構是非常好的。下圖給出了“草體”可能的兩種變體。
他們由3個相交的方塊構成。我們必須禁用背面剔除來渲染多邊形,以保證雙面都可見。為了得到合適的照明度,應該讓所有頂點的法線方向與多邊形的垂直邊平行。這保證了位于斜坡上的所有草體都可以得到正確的光照,不會因為地形的亮度而出現差異。
如果把這些草地物體彼此相當靠近地設置在一個大的區域里,如下圖。在運行期間把它們從后向前進行排序,使用alpha混合,并啟用DrawCall中的z-testing/writing,那么就會得到自然而茂密的草地渲染效果。
4.草地的動畫
關于草地的動畫,基本思想是以三角函數(尤其是正弦和余弦)為基礎進行計算,且計算應該考慮到移動的位置和當前時間、風向和強度。我們的每種技術都只移動草體較高的定點。在一個頂點shader中,通過檢查紋理坐標,區別較高的頂點和較低的頂點是很容易的。對草紋理而言,所有的上面頂點應該有相同的v坐標。本文首先實現一個頂點shader的框架,在所有的3種動畫技術實現方案中都使用該框架,只有純動畫的部分有差別。
頂點shader框架如下:
?
?
動畫部分實現起來有幾種方法:
1)每草叢草體的動畫(Animation per Cluster of Grass Objects)。
對一叢靠近的草體,上面的多邊形頂點統一地發生移動。動畫的平移矢量由cpu計算,若在cpu上使用更費時的算法,還可以讓我們利用非常復雜的風模擬。因為每叢草體由它自己的平移矢量來支持,所以必須針對每叢草體來改變這個常量,因此不得不經常地打斷對整個草地的渲染,而且為每叢草體使用獨立的繪圖調用。
優點:
- 復雜的動畫計算基于cpu算法進行
- 因為一個多邊形上頂點的距離是固定的,所以不發生變形。
缺點:
- 需要許多的draw call
- 由于整個草叢的所有頂點同步動畫,可能出現聚集成簇的現象。
算法:
2)每頂點的動畫(Animation per Vertex)
為了減少繪圖調用,我們需要把動畫計算移進頂點shader內,shader能夠相對于它的位置分別的移動每個頂點。如下圖所示:
因為對每個頂點的移動是分別計算的,各頂點移動的距離不再是常數,所以可見的變形會出現,但是通常這些失真不易覺察。
?
優點:
- drawcall很少,甚至僅僅1個
- 在頂點的shader中改變頂點位置,產生連續的風吹草地引起的波動蕩漾
- 不會看出個別的草叢。
缺點:
- 出現變形
- 由于缺少了局部的無序,動畫可能顯得過于均勻
- 動畫計算的復雜性受到限制
算法:
3)每草體的動畫(Animation per Grass Object)
吸取前兩個方法的各自優點,我們可以計算動畫不是基于每個頂點的位置,而是基于草體的中心位置。因為附近的草體現在有不同的動畫,我們能表現那種要求的局部混亂,每個草體內的頂點移動相同,又避免了變形。為了做到這一點,每個頂點必須知道它所在草體的中心位置。因為頂點shader必須讀取這個值,所以這個信息所需要的草體位置矢量必須在頂點格式中。
優點:
- drawcall很少,甚至僅僅1個
- 沒有變形
- 局部多變,畫面更自然
缺點:
- 因為每個頂點也包含它的草體的中心位置值,所以在頂點格式中需要附加數據
- 動畫計算的復雜性受到限制
算法:
?
【核心要點總結】
1)草的紋理,應選取一簇一簇聚集叢生的草。在透明的alpha通道上畫實體草莖。在彩色通道中,用深淺不同的綠色和黃色,區別各個單獨的葉片。
2)草體的渲染,適合進行交叉排布,從后向前進行排序,使用alpha混合,并啟用Draw
Call中的z-testing/writing,便能得到自然而茂密的草地渲染效果。
3)草地的動畫,以三角函數(尤其是正弦和余弦)為基礎,且應該考慮到移動的位置和當前時間、風向和強度。實現起來有三種方法:
總結
以上是生活随笔為你收集整理的GPU Gems1 - 7 无数波动草叶的渲染的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: GPU Gems1 - 5 改良的Per
- 下一篇: GPU Gems1 - 8 衍射的模拟