ETH官方钱包

切換
舊版
前往
大廳
主題

Screen Space Reflections (2)

Lumi | 2015-12-16 18:28:17 | 巴幣 2 | 人氣 1568

上一篇提到傳統的射線若是每一步的前進距離太長,有可能會跳過某些物體,就像上一篇的附圖一樣。缺點還不只這一個,若每一步的距離太短,或是射線幾乎和視線平行時,射線投影在螢幕上後可能根本沒移動到隔壁的像素。檢測碰撞時可能會大量使用depth map同一個像素,效能就浪費在這些重複的計算上。因此Morgan McGuire認為不要在view space(3D)中計算射線的前進距離,而是在screen space(2D)中計算,從前進了幾格像素來推得view space中射線的新位置。

我們要怎麼將射線從一個像素移動到另一個像素呢? 這問題帶領我們回到圖學中的經典老問題上:如何在螢幕上畫出一條線? 說個題外話,不曉得有沒有人曾經在修圖學課的時候納悶為什麼要從畫線開始學? 有的時候你當時覺得根本沒用的東西就是會突然冒出來打你的臉...

每次只前進一個像素實在很費時間,尤其是畫面解析度越高的時候,要移動更長的距離才能找到碰撞點,於是設定成一次橫跨十個像素…

▲可見階梯狀瑕疵,反射部分也不甚準確(見大腿上的帶子變成鋸齒狀)

我們先解決反射不準確的部分,對那些碰撞成功的反射使用binary search可以增加準確度。在上一篇我弄錯了,階梯狀瑕疵是由於碰撞失敗引起的,一開始就沒碰撞成功的話自然也不會啟動binary search,也就談不上解決階梯狀瑕疵。
此處實作我參考了kode80,增加額外四個碰撞檢測的結果如下:

▲經過binary search後,大腿上的帶子連接起來了

最後鋸齒問題就交由jitter解決,此jitter值用於減少每次前進的距離,減低碰撞失敗的機會。jitter可以每次都隨機設定成[0, 1]區間的值,也可以固定pattern循環的方式。下圖是用每四個像素循環的pattern設定jitter:

▲binary search加上jitter後,總算獲得能看的反射

此篇只專注在SSR的搜尋演算法上,離實用還是有段距離。許多部份都因為不想再對OpenGL程式修改而擱置,例如碰撞失敗時改用cubemap的結果,處理粗糙表面反射等。SSR比原先想像中要麻煩很多呢…

創作回應

相關創作

更多創作