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