基于頂點(diǎn)紋理的無限大海水仿真
最近手上有了一塊7800的顯卡,因此就想利用這塊強(qiáng)大的顯卡做點(diǎn)東西出來?;陧旤c(diǎn)紋理的無限大面積海水的算法在腦子想了很久了,但一直苦于沒有支持頂點(diǎn)紋理的顯卡而無法實(shí)現(xiàn)。
拿到顯卡以后,就開始三下五除二的寫程序。下面是最終的效果圖。
效果圖1
效果圖2
效果圖3
主要的方法是,使用一個(gè)與視相關(guān)的自適應(yīng)網(wǎng)格(1),使用tessendorf的基于2DFFT的海水仿真算法(2)生成動(dòng)態(tài)的海水高度場(chǎng),并將高度場(chǎng)存入到頂點(diǎn)紋理當(dāng)中,然后在頂點(diǎn)著色器中通過取頂點(diǎn)紋理的值對(duì)自適應(yīng)網(wǎng)格進(jìn)行擾動(dòng),形成動(dòng)態(tài)的海水效果。
這個(gè)思路雖然簡(jiǎn)單,但是在目前的顯卡中,不支持浮點(diǎn)紋理的雙線性濾波,只支持最近點(diǎn)采樣的方式,如果使用最近點(diǎn)采樣的方式你會(huì)發(fā)現(xiàn)整個(gè)波動(dòng)效果會(huì)有很明顯的塊狀效果(非常討厭),因此,必須通過shader自己來寫一個(gè)雙線性濾波的函數(shù),另外在我這個(gè)算法中還要求根據(jù)高度場(chǎng)計(jì)算出法線場(chǎng),由于取頂點(diǎn)紋理是一個(gè)非常耗時(shí)的操作,如果把這些計(jì)算都放在頂點(diǎn)著色器里面進(jìn)行的話,頂點(diǎn)著色器會(huì)成為整個(gè)繪制過程的一個(gè)大瓶頸。
最終我采用的是多次繪制的方法。首先在一個(gè)PS里面進(jìn)行高度場(chǎng)的濾波,并且計(jì)算對(duì)應(yīng)的法線,并且把這個(gè)結(jié)果渲染到一張浮點(diǎn)紋理中(在PS中做這些操作要比在VS中做這些操作要快很多),然后再利用這張經(jīng)過濾波處理和法線預(yù)計(jì)算的浮點(diǎn)紋理作為頂點(diǎn)著色器中的高度場(chǎng)和法線紋理進(jìn)行高度擾動(dòng),以及取法線。
另外。在光照處理方面,海水著色方面參考了(3)。
于是就有了以上的渲染效果圖。
最后,我還是要打擊一下自己,下面這張是用3dmax加dreamscape插件渲染的海水效果圖。看來效果差距還是有的。當(dāng)然我可以用1/65秒渲染一幀,而它卻需要65秒來渲染一幀。
3dsmax海水效果圖
(1)http://www-evasion.imag.fr/Publications/2002/HNC02/wavesSCA.pdf
這是法國人寫的論文,這個(gè)網(wǎng)格構(gòu)造的思路確實(shí)巧妙,值得去研究下。
(2)Simulating Ocean Water, Jerry Tessendorf
這個(gè)經(jīng)典的海水仿真算法我就不解釋了,不過這里面最近更新了一個(gè)交互海水的算法,也是很值得研究。
(3)http://graphics.cs.lth.se/theses/projects/projgrid/
一個(gè)英國人的碩士論文,用到了投影網(wǎng)格概念,不過他的水面效果是使用perlin noise生成#p#page_title#e#
波長(zhǎng)為空間周期的n分之一
前提條件和一維時(shí)候的情況基本相同:
b:使用多個(gè)Gestner-Wave的疊加來合成出整個(gè)波動(dòng)效果。
(15)
(16)
在后面的章節(jié)里,將要介紹使用海洋統(tǒng)計(jì)學(xué)頻譜結(jié)合上述使用傅立葉變換描述的海水波動(dòng)計(jì)算公式來進(jìn)行海水模擬