視差貼圖 Parallax Occlusion Mapping (下稱POM)
大家都很清楚的做法了,別於直接讓地形在vertex shader有所起伏
視差貼圖於pixel shader進行計算,透過ray-height-field追蹤出高低起伏
計算是發生在貼圖裡面的,來讓物件看起來很有立體感的方法
缺點當然就是效能,要讓結果越好,光追過程中的搜尋次數就要提高
很慶幸地,以前有人提出了Cone Step Mapping這個方法,嘗試降低搜尋次數
影片為POM vs RCSM (Relaxed Cone Stepping Mapping)的結果比較
POM的搜尋次數為64次 (UE4是使用線性搜尋)
RCSM我則是用了32次Cone Stepping + 8次Binary Search
可以看到RCSM以較少的搜尋數得到了更清晰銳利的結果
另一個較低視角的比較:
POM的線性搜尋總是給了點噪噪的感覺...
Binary與線性Step的問題
這篇文章開頭就敘述了這兩種方法的問題 (如圖)
上面的二元搜尋確實是快,但很有可能會錯過真正想要的終點 (想要P卻得到Q)
而線性搜尋雖然能減少這個問題,但有可能會錯過太薄的地形
於是一個叫Dummer的人在2006提出了Cone Step Mapping (CSM)
先是透過Cone Stepping來找到正確的終點,再去執行二元搜尋
確保二元搜尋擊中我們比較想要的位置,實在是...!!
不知道作者嗑了什麼想出來的方法,為什麼要錐形為什麼不是其他形狀
這同時也說明了,CSM是需要前處理的做法,需要先產生一張Cone Map
Relaxed Cone Step Mapping
但是CSM也是有一些瑕疵狀況有可能存在 (詳情請見引用網址的原文)
簡單來說就是CSM算出來的終點,可能在真正進入表面之前就停止了
導致二元搜尋還是擊中不了我們要的終點
因此NVIDIA改良了這個方法,主張應該使用Relaxe CSM
由上圖可知,RCSM算出來的錐形會更加寬敞
實作
第一部分為前處理,一張圖會被打成8x8的區塊來處理,所以256x256要算(256/8)*(256/8)=1024個區塊,而每個區塊又會位移Ray 64次..算一張256x256的就要65535次
...實在不是什麼小數目,原版的source code抓下來執行,一張256的也要算好幾分鐘
但這跟它的實作方式有關,有點笨,它1個frame只作了一次渲染指令,所以過了65535個frame才算完,如果是要在Unity或Unreal重製,是可以1個frame多下幾次渲染指令的
還有高解析度圖一定要divide and conquer! 重製後發現2K貼圖一跑下去就直接畫面凍結 - 吃了GPU Timeout,後來除了它本身分成8x8的作法,我又以256x256為一個單位來跑圖,解決了timeout問題
第二部分就是實際使用這張RSCM,簡單多了,做ray tracing的時候先做CSM找出終點
再得到終點後,就有足夠的資訊做二元搜尋,因為這個方法是假設終點已經穿透過表面了
所以得出來的位置應該要十分滿意
輸入的height map是上排右邊那張,輸出的RCSM為下排的(c)
總結
就是減少搜尋次數又不失品質(甚至更好)的方法
一些大作也有使用,像是Forza Horizon 5
缺點就是需要前處理,生成RCSM那張圖,開放世界素材全上的話,空間堪憂..
選擇重點物件來做就可以了~
一方面也很是佩服他們怎麼想出這些方法的..期許自己哪天也能成為設計公式的人