大家好~這三個月以來,我一直在學習和實現“基於WebGPU的混合光線追蹤實時渲染”的技術,使用了Ray Tracing管線(如.rgen、.rmiss等着色器)。
現在與大家分享和介紹我目前的學習成果,希望對大家有所幫助!謝謝!
通過國外的開源項目,可在WebGPU中使用Ray Tracing管線
這三個月我對Ray Tracing的研究有了質的突破,主要歸功於我發現的WebGPU Node開源項目!
該作者首先在dawn-ray-tracing開源項目中對“dawn項目:Chrome對WebGPU的實現”進行了擴展,加入了光追的API;
然後在WebGPU Node開源項目中,底層封裝了Vulkan SDK,上層使用了dawn-ray-tracing項目,提供了WebGPU API,實現了在Nodejs環境中使用WebGPU API和Ray Tracing管線來實現硬件加速的光線追蹤(電腦需要使用nvdia的RTX顯卡)!
相關介紹參見:
Real-Time Ray-Tracing in WebGPU
搭建運行環境
有兩種方法來搭建運行環境:
1、給Chrome瀏覽器打補丁,使其與下載DXR驅動(DirectX Raytracing)關聯,從而在該瀏覽器中運行
詳見該作者最近寫的開源項目:chromium-ray-tracing
(我沒有測試過,不知道是否能使用)
2、編譯dawn-ray-tracing和WebGPU Node項目,從而在Nodejs環境中運行
我使用的是這個方法(不過我使用的WebGPU Node項目是今年3月份時的代碼,最新的代碼我還沒有編譯成功)。
我的操作系統是win7,顯卡是RTX 2060s,vulkan sdk是1.1.126.0版本
/* 最新代碼我還沒有編譯成功哈哈!請先不要進行下面的編譯操作!
編譯的步驟為(需要使用VPN翻牆):
# 編譯dawn-ray-tracing項目
## Clone the repo as "dawn-ray-tracing"
git clone https://github.com/maierfelix/dawn-ray-tracing
cd dawn-ray-tracing
## Bootstrap the gclient configuration
cp scripts/standalone.gclient .gclient
## Fetch external dependencies and toolchains with gclient
gclient sync
set DEPOT_TOOLS_WIN_TOOLCHAIN=0
npm install --global --production windows-build-tools
gn gen out/Shared --ide=vs --target_cpu="x64" --args="is_component_build=true is_debug=false is_clang=false"
ninja -C out/Shared
# 編譯webgpu node項目
npm install webgpu
在webgpu node的根目錄中創建名為“PATH_TO_DAWN”的文件,在其中指定dawn-ray-tracing項目的絕對路徑,如:
D:/Github/dawn-ray-tracing
在webgpu node的根目錄中執行:
npm run all --dawnversion=0.0.1
(
這裏要注意的是,需要先安裝Vulkan SDK和python;
可以通過“npm config set python C:\depot_tools\python.bat”來設置python路徑,或者指定python路徑:
npm run all --dawnversion=0.0.1 --python="C:\Users\Administrator\Downloads\depot_tools\bootstrap-3_8_0_chromium_8_bin\python\bin\python.exe"
)
# 在nodejs中運行ray tracing示例,驗證是否成功
進入webgpu node的根目錄
cd examples & cd ..
node --experimental-modules examples/ray-tracing/index.mjs
*/
應用場景
考慮到WebGPU還沒有正式發布,並且可能在三年內瀏覽器都不會支持Ray Tracing管線,所以我把渲染放到雲端,這樣就可以在雲端自行搭建環境(如使用WebGPU Node開源項目),然後通過網絡傳輸將渲染結果傳輸到客戶端,從而在客戶端瀏覽器不支持的情況下仍能显示光追渲染的畫面。
因此,我的應用場景為:
1、雲渲染
2、雲遊戲
這兩個應用場景有不同的需求:
“雲渲染”屬於離線渲染,我們關心的是:
因此:
- 每幀可採樣多次,即n spp(n >= 30)
- 支持多種渲染效果,如“焦射”(causicts)等
- 全局光照可使用n次bounce(n >= 2)
“雲遊戲”屬於實時渲染,我們關心的是:
因此:
- 每幀只採樣一次,即1 spp
- 全局光照只使用一次或兩次bounce
- 對“焦射”(causicts)等場景用性能好的方案達到接近的渲染效果,通過犧牲畫質來減少渲染時間
介紹我目前的實現方案
主要技術框架是“實時混合光線追蹤”,主要包含下面的pass:
1、gbuffer pass
創建gbuffer
2、ray tracing pass
直接從gbuffer中獲取world position、diffuse等數據,用來計算直接光照,從而減少了每個像素髮射的光線數量;
每個像素髮射1個shadow ray,用來計算直接光照的陰影;
如果只用1個bounce來計算全局光照的話,每個像素髮射1個indirect ray+1個shadow ray,用來計算間接光照。
3、denoise pass
基於BMFR算法來實現降噪,具體可參考本文後面的“實現降噪Denoise”部分。
4、taa pass
使用taa來抗鋸齒
相關代碼可見我的開源項目:
WebGPU-RTX
介紹我學習的整個流程,分享相關資料
了解光線追蹤的相關領域
我通過下面的文章進行了初步的了解:
一篇光線追蹤的入門
光線追蹤與實時渲染的未來
實時光線追蹤技術:業界發展近況與未來挑戰
Introduction to NVIDIA RTX and DirectX Ray Tracing
如何評價微軟的 DXR(DirectX Raytracing)?
實現第一個光追的Demo
通過學習下面的資料:
Ray Tracing in One Weekend
Ray Tracing: The Next Week
Ray Tracing in One Weekend和Ray Tracing: The Next Week的詳解
基於OpenGL的GPU光線追蹤
我參考資料中的代碼,用WebGL 2實現一個Demo:
該場景的紅圈中是一個球,附近有一個球形光源和一個矩形光源
因為沒有進行降噪,所以噪點太多了哈哈!
相關代碼可見我的開源項目:
Wonder-RayTrace
學習和實現Ray Tracing管線
通過學習NVIDIA Vulkan Ray Tracing Tutorial教程,我用 js語言+WebGPU Node開源項目 基於Ray Tracing管線依次實現了陰影、反射等基礎渲染效果。
該教程使用了VK_KHR_ray_tracing擴展,而WebGPU Node開源項目也使用了該擴展(Vulkan SDK),因此該教程的shader代碼幾乎可以直接用到該開源項目中。
教程代碼
用Reason重寫
我用Reason語言重寫了示例代碼,提煉了一個基礎架構。
學習GBuffer+Ray Tracing混合管線
因為我希望優先減少渲染時間,所以我要通過混合管線來進行實時渲染。
我通過A Gentle Introduction To DirectX Raytracing教程來學習和實現。
教程代碼下載
我學習了該教程的第一篇到第11篇,分別實現了創建GBuffer、使用Lambertian材質渲染、多光源的陰影等內容。
實現降噪Denoise
教程的第9篇通過每個像素對每個光源發射一個shadow ray,最後累加並計算平均值,實現了多光源的陰影。
教程的第11篇對第9篇進行了改進:為了減少每個像素髮射的shadow ray的數量,每個像素只隨機向一個光源發射一個shadow ray。
這樣會導致噪點,如下圖所示:
我們可以通過累計採樣數來不斷逼近無噪點的圖片(如該教程的第6篇一樣),但這樣需要經過長時間后才會收斂,所以只適合“雲渲染”這種離線渲染的應用場景。
累加一定幀數后,結果如下圖所示:
實現taa
降噪算法通常需要先實現“幀間的數據復用”,而TAA抗鋸齒也需要實現“幀間數據復用”的技術;而且降噪算法會使用TAA作為最後一個pass來抗鋸齒。所以我決定先實現taa,將其作為實現降噪算法的鋪墊。
我參考了下面的資料來實現taa:
DX12渲染管線(2) – 時間性抗鋸齒(TAA)、 相關代碼
Unity Temporal AA的改進與提高、 相關代碼
unit Temporal Anti-Aliasing
實現BMFR降噪算法
為了能應用於“雲遊戲”這種實時渲染的應用場景,我們需要快速降噪。因此我實現了BMFR算法來降噪。
降噪前場景:
降噪后場景:
我參考了下面的資料:
BLOCKWISE MULTI-ORDER FEATURE REGRESSION FOR REAL-TIME PATH TRACING RECONSTRUCTION
參考代碼
學習蒙特卡羅積分(monte carlo)的理論
教程的第11篇隨機向一個光源發射一個shadow ray,這其實已經使用了蒙特卡羅積分的理論。
我們可以通過下面的資料深入學習該理論,了解概率密度函數(pdf)、重要性採樣等相關概念,為我們後面實現全局光照打下理論基礎:
【RAY TRACING THE REST OF YOUR LIFE 超詳解】 光線追蹤 3-1 蒙特卡羅 (一) 到 【RAY TRACING THE REST OF YOUR LIFE 超詳解】 光線追蹤 3-7 混合概率密
光線追蹤器Ray Tracer:進階篇
實現全局光照
通過學習教程的第12篇,我實現了one bounce的全局光照。
更多參考資料:
Global Illumination and Path Tracing
Global Illumination and Monte Carlo
這裏我遇到的問題主要是處理indirect specular noise:噪點不穩定,導致降噪后不穩定(高光周圍有明顯波動)。
我首先以為是pdf寫錯了,結果修改了pdf后還是沒有改進;
然後希望通過clamp等方法移除這些高光的fireflies噪點,結果影響到了畫質;
最後採用了“採樣indirect specular/diffuse多次”來穩定噪點。這適用於“雲渲染”的離線渲染,但不適用於“雲遊戲”的實時渲染。
基於GGX模型,實現disney BRDF
通過學習教程的第14篇,我引入了pbr材質,實現了GGX模型,加入了多bounce的全局光照。
我對教程代碼進行了改進:
在.rgen着色器中使用for循環而不是遞歸來實現的多bounce;
實現了disney BRDF,在pbr材質中有diffuse、roughness、metallic、specular這幾個參數。
更多參考資料:
基於物理着色(二)- Microfacet材質和多層材質
基於物理着色(三)- Disney和UE4的實現
基於物理的渲染(PBR)白皮書 | 迪士尼原則的BRDF與BSDF相關總結
WebGPU-Path-Tracer 實現了disney BRDF
目前的渲染效果
我目前的實現需要改進的地方
在Ray Tracing pass中支持紋理
使用bindless texture或者virtual texture來實現
擴展disney BRDF,實現BSDF,支持透明、折射效果
增加后處理
如gamma矯正等
在雲端環境下多線程渲染
雲端天然具有并行的優勢,因此可將渲染任務分配到多個顯卡/服務器中執行。
改進降噪效果
BMFR對高光specular處理得不好。
為了應用在“雲渲染”中,需要提高畫質。因此可考慮:
- 改進BMFR對specular的處理
BMFR論文中已有相關的討論
- 使用專門對多個spp採樣進行降噪的降噪器來替代BMFR
因為BMFR主要是針對1 spp採樣,所以需要使用針對蒙托卡羅積分路徑追蹤的降噪器來替代
改進indirect specular/diffuse noise
現在我通過增加spp來增加噪點的穩定性,這在“雲遊戲”中行不通,因為只能有1 spp。因此可考慮:
- 使用blue noise
可參考: http://psgraphics.blogspot.com/2018/10/flavors-of-sampling-in-ray-tracing.html
https://hal.archives-ouvertes.fr/hal-02158423/file/blueNoiseTemporal2019_slides.pdf
https://belcour.github.io/blog/research/2019/06/18/animation-bluenoise.html
https://zhuanlan.zhihu.com/p/90017623
- 對GGX模型使用VNDF來代替NDF採樣
- 對多bounce的indirect specular noise進行優化
可能的解決方案:
使用reflection denoise filter;
adaptive multiple bounce;
- 使用photon mapping來降低噪點
本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】
※網頁設計公司推薦不同的風格,搶佔消費者視覺第一線
※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益
※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面
※南投搬家公司費用需注意的眉眉角角,別等搬了再說!
※新北清潔公司,居家、辦公、裝潢細清專業服務