ETH官方钱包

前往
大廳
主題 達人專欄

【光追Shader學習筆記】使用RayMarch實做光追原理

%%鼠 拒收病婿 | 2022-08-22 00:00:10 | 巴幣 2342 | 人氣 820

前言:
參考此教學系列,順便畫圖表、整理一下重點與補充。

文章一樣有放在個人網站


 

視覺化視錐體

建構Matrix4x4資料以紀錄相機視錐,使用方向向量逐漸推出視錐體四個頂點方位。
用goUp和goRight向量去推出far plane的上下左右四個頂點。
使用GL函式庫直接渲染一個覆蓋畫面之平面。

_rmMaterial之著色器腳本:

結果:

距離場 (Signed Distance Field ,SDF)

如何用數學公式畫出一個3D的球體?  為甚麼它可以這樣運作?  就得先了解隱函式:
找出所有符合隱函式 f(x,y,z)=0 的點可以畫出一圖形,而隱含式的好的好處在於任一座標帶入隱函式子的結果若<0,則代表在圖形內;等於0表示在圖形(表面)上,>0表示在圖形外。缺點是隱函式不直覺,顯函式比較好懂,例如比起x^2+y^2+z^2,用cos和sin畫圓會更直覺。
*cos和sin無法透過分離變數找到奇異解。
 

定義圓的公式

回傳距離圓表面的最短距離。

定義SDF

輸入 任意點p到球體原點(暫定為 0,0,0)的距離 與 球體半徑。

假設世界座標為(0,0,-10),則此函數會回傳8。

定義Ray march函數


結果:

SDF自發光渲染

我們知道渲染的基本光源有: 自發光(Albedo)、漫射光(Diffuse)、高反射光(Specular )與環境光(Ambient)。但我們的這個"球體"並沒有真正的幾何,該如何補足它的幾何資訊呢?

建立法線



結果:
 

打光

之後就跟以前算幾何體的方法差不多。

 

結合場景

修改成讓使用者能從C#那邊設定球體的座標。
有個問題是沒有深度檢測,導致錯誤渲染在最上層。
 

深度檢測

將深度值投影在該ray的方向向量上,可得到相對的長度,與目前已行走的距離作比較即可。


無限延伸

透過mod的操作讓SDF值不斷在一定範圍內循環。


 
 

影子

硬陰影

從目前座標向光(這裡是世界光)的方向發射出Ray,若該Ray行進路上會打到SDF表面,代表該座標處於陰影處。





軟陰影

這邊採用penumbra shadow (半影)作法,使用離表面的距離與目前移動的距離之比例做為陰影強度係數,即不需要採用Blur作法就能有不錯的混合感。

Ray移動三次,對陰影強度係數變化之示意圖。

光追 (Ray Trace)

Ray March是實現光追的一種做法,搭配SDF去做"理論上"的Ray的碰撞檢測。實際不規則形狀之遊戲場景要如何做ray的碰撞檢測才是難題。這邊仍繼續使用SDF做檢測,並搭配上回之動態環境貼圖作法讓反射更豐富。
以下影片示範從Ray彈跳次數0提升到10的變化過程:
 
將RayMarch返回值改成布林值:

測試時發現TEXCUBE若sample多餘一次就會出現error,所以只有在ray第一次打到表面時採樣場景顏色,其餘之後皆只是採樣光亮程度,不斷的複寫在本身的像素上,因此看起來像是素模。



總結:

送禮物贊助創作者 !
0
留言

創作回應

??求出處學術用??
2022-08-22 04:40:35
%%鼠 拒收病婿
也多虧社群大佬願意釋出教學,我才能學到[e38]
2022-08-25 20:44:37
虛鹿
怕,感覺好難
2022-08-23 19:26:54
%%鼠 拒收病婿
這是用SDF架設出理論上的場景應用,但我想真正的難題是如何在真正的場景中計算ray每個hit表面的顏色 hmmmm
2022-08-25 20:45:55
%%鼠 拒收病婿
抱歉,發現影片連結跑掉了,補:
https://youtu.be/K8LhLOpVpXs
2022-11-22 00:04:37
追蹤 創作集

作者相關創作

相關創作

更多創作