1、NVIDIA在游戲中實現光線追蹤百萬光源歐陽耀斌NVIDIA開發者技術工程師,2020年12月#page#光追帶來新光源突破光柵化在光照上的限制#page#什么樣的限制?看一個例子現實世界包含了:大量有形光源(而非無限小或無限遠光源所有光源都會帶來復雜的陰影(可見性判斷)#page#什么樣的限制?看一個例子現實世界包含了:大量有形光源(而非無限小或無限遠光源所有光源都會帶來復雜的陰影(可見性判斷)動態光照;開啟/關閉,改變顏色#page#什么樣的限制?看一個例子現實世界包含了:大量有形光源(而非無限小或無限遠光源所有光源都會帶來復雜的陰影(可見性判斷動態光照;開啟/關閉,改變顏色光源可具有任意
2、形狀,帶有任意紋理#page#什么樣的限制?看一個例子現實世界包含了:大量有形光源(而非無限小或無限遠光源所有光源都會帶來復雜的陰影(可見性判斷動態光照;開啟/關閉,改變顏色光源可具有任意形狀,帶有任意紋理多個連通區域,各自具有不同的光光源#page#什么樣的限制?看一個例子現實世界包含了:大量有形光源(而非無限小或無限遠光源所有光源都會帶來復雜的陰影(可見性判斷)動態光照;開啟/關閉,改變顏色光源可具有任意形狀,帶有任意紋理多個連通區域,各自具有不同的光源陰影不僅影響漫射,還會影響高光#page#什么樣的限制?看一個例子現實世界包含了:大量有形光源(而非無限小或無限遠光源所有光源都會帶來復雜
3、的陰影(可見性判斷)動態光照;開啟/關閉,改變顏色光源可具有任意形狀,帶有任意紋理多個連通區域,各自具有不同的光源陰影不僅影響漫射,還會影響高光實時光追可以處理所有這些情況全動態#page#實時光照的現狀光柵化:為一系列像素計算光照每光源一張陰影貼圖(shadowmap)重要的光源通常會被預先標出#page#實時光照的現狀光線追蹤光柵化:每光線可獨立計算光照為一系列像素計算光照每光線可獨立查詢光源的可見性每光源一張陰影貼圖(shadowmap)重要的光源可在運行時動態決定重要的光源通常會被預先標出性能優化的方式:重用:三角形,模型,圖像,屏幕分塊,啟動設法攤平開銷:更多像素查詢一張shadow
4、map#page#實時光照的現狀光線追蹤光柵化:每光線可獨立計算光照為一系列像素計算光照每光線可獨立查詢光源的可見性每光源一張陰影貼圖(shadowmap)重要的光源可在運行時動態決定重要的光源通常會被預先標出性能優化的方式:性能優化的方式:.應該怎樣優化?重用:三角形,模型,圖像,屏幕分塊,啟動設法攤平開銷:更多像素查詢一張shadowmap#page#高性能光線追蹤為何光追會比光柵化更快#page#高性能光線追蹤為何光追會比光柵化更快簡單:獨立的可見性查詢按需使用;不多不少優化方向:如何盡量“少采樣”“少用光線”#page#一個思想實驗為何光追會比光柵化更快想象用光柵化繪制一張shadow
5、map#page#一個思想實驗為何光追會比光柵化更快想象用光柵化繪制一張shadowmap分辨率從12到40962,開銷是線性增加的嗎?并不是。店#page#一個思想實驗為何光追會比光柵化更快想象用光柵化繪制一張shadowmap分辨率從12到40962,開銷是線性增加的嗎?并不是。店12的開銷并不是40962的1/40962也許是1/16.如果只有一個像素需要查詢該光源的可見性,那將浪費許多計算#page#一個思想實驗為何光追會比光柵化更快想象用光柵化繪制一張shadowmap分辨率從12到40962,開銷是線性增加的嗎?并不是。一旦我們要處理10,000個光源,不需要給每個光源配置4096
6、2辯率的shadowmap光源的可見性查詢也不會在光源視角上均勻分布使用shadowmaps需要使用復雜的過采樣以及過濾技術來避免瑕癥#page#一個思想實驗為何光追會比光柵化更快想象用光柵化方法處理大量光源的陰影需要分配大量的shadermap,每張光源一個大部分光源影響范圍不大,每張shadowmap分辨率應該降低降低分辯率帶來的提升不足以抵消shadowmap增多帶來的開銷生成每張shadowmap都需要單獨的光柵化流程大幅增加drawcall#page#另一個考慮為何光追會比光柵化更快?優化的關鍵原則:讓常見的情況更快#page#另一個考慮為何光追會比光柵化更快?優化的關鍵原則:讓常見
7、的情況更快對于陰影,常見的情況包括:大塊全光照的區域大塊全陰影的區域#page#另一個考慮為何光追會比光柵化更快?優化的關鍵原則:讓常見的情況更快對于陰影,常見的情況包括:大塊全光照的區域大塊全陰影的區域少見的情況包括:陰影高頻變化的區域#page#另一個考慮為何光追會比光柵化更快?優化的關鍵原則:讓常見的情況更快對于陰影,常見的情況包括:大塊全光照的區域大塊全陰影的區域少見的情況包括:陰影高頻變化的區域使用shadowmap時,所有區域的開銷都一樣高控折:無法讓全光照的區域更快#page#光線追蹤有何幫助?單次遮擋查詢:每次開銷更大,但查詢總量明顯更低這個場景中含有數百個光源#page#光線
8、追蹤有何幫助?單次遮擋查詢:每次開銷更大,但查詢總量明顯更低這個場景中含有數百個光源這塊區域里包含了多少個陰影?這里總共需要多少陰影射線?臨近的像素都需要各自發射陰影射線嗎?#page#光線追蹤有何幫助?單次遮擋查詢:每次開銷更大,但查詢總量明顯更低這個場景中含有數百個光源這塊區域里包含了多少個陰影?這里總共需要多少陰影射線臨近的像素都需要各自發射陰影射線嗎就這一處而言,答案相對簡單兩個,或者三個明顯的陰影#page#光線追蹤有何幫助?單次遮擋查詢:每次開銷更大,但查詢總量明顯更低這個場景中含有數百個光源這塊區域里包含了多少個陰影?這里總共需要多少陰影射線臨近的像素都需要各自發射陰影射線嗎就這
9、一處而言,答案相對簡單兩個,或者三個明顯的陰影問題:對每個像素而言,可見陰影的數量上限#page#光柵化VS光線跟蹤陰影查詢隨機發射可見性光線Shadow Map光線跟蹤光柵化#page#什么是重要性采樣?常見的數學方法:把采樣集中放到重要區域均勻采樣重要性采樣#page#什么是重要性采樣?常見的數學方法:把采樣集中放到重要區域蒙特卡洛積分的重要性采樣o#page#什么是重要性采樣?常見的數學方法:把采樣集中放到重要區域蒙特卡洛積分的重要性采樣1o更好的選取p(x)可以利用更少的采樣達到收斂對于實時環境下最小化采樣數量至關重要#page#什么是重要性采樣?常見的數學方法:把采樣集中放到重要區域
10、蒙特卡洛積分的重要性采樣1o更好的選取p(x)可以利用更少的采樣達到收斂對于實時環境下最小化采樣數量至關重要通常,f(x)是染方程,p(x)是概率密度函數(PDF):隨機光源采樣,采樣更大的光源,采樣更亮的光源,采樣BRDF的指向范圍#page#什么是重要性采樣常見的數學方法:把采樣集中放到重要區域蒙特卡洛積分的重要性采樣理想情況:目標完美的重要性采樣,讓p(x)f(x)。此時只需一個采樣。怎樣才能做到完美采樣精確已知C=f(x)dx但有一種近似方法:重(ch6ng)采樣重要性采樣(resampledimportancesampliing,RIS)#page#什么是RIS?曾被叫做“重要性重采
11、樣(importanceresampling)”重用樣本丟棄無效樣本遮擋導致重用失敗初始采樣樣本重用“mportanceResamplingforGlobalilumination”,EGSR2005#page#什么是RIS?曾被叫做“重要性重采樣(importanceresampling)完美的RIS需要知道C=jf(x)dx我們需要使用逼近的方法,不妨使用C這看起來是在兜圈子,實則不然#page#什么是RIS?曾被叫做“重要性重采樣(importanceresampling)完美的RIS需要知道C=jf(x)dx我們需要使用逼近的方法,不妨使用C這看起來是在兜圈子,實則不然把上式代入原有表
12、達式,得到RIS估值器的通用形式o上式中,若令(x)三f(x),可得完美的重要性采樣#page#太長不看版重要性采樣與RIS的區別#page#太長不看版重要性采樣與RIS的區別RIS:蒙特卡洛重要性采樣:f(xip(x)f(x)dxomp(x更好的采樣=用更好的p(x)來選擇樣本把M個來自p(x)的較差采樣,轉換為N個來自(x)的較好采樣通常需要設計更好的采樣算法統計性重采樣的魔術只能通過設計p(x)來控制采樣(x)可任意選擇;也可進行優化來獲得更好效果p(x)可以非常粗糙,但一定要高效#page#太長不看版重要性采樣與RIS的區別RIS:蒙特卡洛重要性采樣:f(xip(x)f(x)dxomp
13、(x更好的采樣=用更好的p(x)來選擇樣本把M個來自p(x)的較差采樣,轉換為N個來自(x)的較好采樣通常需要設計更好的采樣算法統計性重采樣的魔術只能通過設計p(x)來控制采樣f(x)可任意選擇;也可進行優化來獲得更好效果p(x)可以非常粗糙,但一定要高效你可能已經在使用重采樣但沒有意識到!Mipmaps,光照探針(lightprobe),超采樣(upsampling),降采樣(downsampling),多級分辯率泣染(multi-scalerendering)#page#怎樣使用RIS?在重采樣的過程中加入時空數據可以提高陰影射線的質量#page#怎樣使用RIS?圖解舉例設想:每像素從32
14、個光源中隨機選取1個進行查詢發射一條陰影射線到這個光源“Spatiotemporalreservoirresompling forreal-timeraytracingwithdynamiic direct lichting”byBitterlietal#page#怎樣使用RIS?圖解舉例設想:每像素從32個光源中隨機選取1個進行查詢在5x5相鄰像素的查詢結果中搜尋重要光源,進行重采樣依然每像素1條陰影射線;但效果已有大幅增強“Spatiotemporalreservoirresompling forreal-timeraytracingwithdynamiic direct lichting
15、”byBitterlietal#page#怎樣使用RIS?圖解舉例設想:每像素從32個光源中隨機選取1個進行查詢在5x5相鄰像素的查詢結果中搜尋重要光源,進行重采樣如果上一與當前頓相似,將上一頓的像素也包含進來搜尋依然每像素1條陰影射線.“Spatiotemporalreservoirresompling forreal-timeraytracingwithdynamiic direct lichting”byBitterlietal#page#怎樣使用RIS?圖解舉例設想:每像素從32個光源中隨機選取1個進行查詢在5x5相鄰像素的查詢結果中搜尋重要光源,進行重采樣如果上一與當前頓相似,將上一
16、的像素也包含進來搜尋可以結合之前很多頓的像素平均下來依然是每像素1條陰影射線.這個場景中包含了340萬自發光三角形每一步都是重要性重采樣的一次送代“Spatiotemporal reservoirresampling forreal-timeray tracing with dynamicdirect lightingby Bitterlietal#page#基本ReSTIR算法ReSTIR: Reservoir Spatio-Temporal Importance Resampling時間樣本庫像素i-1新樣本時間樣本庫空間樣本庫用此樣本計算光照像素i新樣本重用上頓樣本時間樣本庫像素i+1新
17、樣本Foradeeper look,alsosee HPG 2020 talk“Reframing Lisht Transport for Real-time#page#基本ReSTIR算法ReSTIR: Reservoir Spatio-Temporal Importance Resampling對每一像素:使用重要性重采樣來選擇a)隨機選取32個候選光源(根據p(x);選擇一個Foradeeperlook,alsosee HPG 2020talk“Reframing Lisht Transport forReal-time”#page#基本ReSTIR算法ReSTIR: Reservoir
18、 Spatio-Temporal Importance Resampling不算最優:對早期的原型系統來說算是個好選擇預處理:根據光源的亮度創建一張別名采樣表(aliastable),以此來作為初始概率密度p(x)對每一像素a)隨機選取32個候選光源(根據p(x);選擇一個Foradeeperlook,alsosee HPG 2020talk“Reframing Lisht Transport forReal-time”#page#基本ReSTIR算法ReSTIR: Reservoir Spatio-Temporal Importance Resampling預處理:根據光源的亮度創建一張別名
19、采樣表(aliastable),以此來作為初始概率密度p(x)對每一像素a)隨機選取32個候選光源(根據p(x);選擇一個使用重要性重采樣來選擇b)查看上一頓選擇的光源;在這個光源和步驟a所選光源中二選一Foradeeperlook,alsoseeHPG2020 tolk“Reframing Liht Transport for Real-time#page#基本ReSTIR算法ReSTIR: Reservoir Spatio-Temporal Importance Resampling預處理:根據光源的亮度創建一張別名采樣表(aliastable),以此來作為初始概率密度p(x)對每一像素a
20、)隨機選取32個候選光源(根據p(x);選擇一個b)查看上一頓選擇的光源;在這個光源和步驟a所選光源中二選一C)隨機選取鄰近數個像素,查看它們選擇的光源;在這些光源和步驟b所選光源中選擇一個使用重要性重采樣來選擇Foradeeperlook,alsoseeHPG2020 tolk“Reframing Liht Transport for Real-time#page#基本ReSTIR算法ReSTIR: Reservoir Spatio-Temporal Importance Resampling預處理:根據光源的亮度創建一張別名采樣表(aliastable),以此來作為初始概率密度p(x)對每
21、一像素a)隨機選取32個候選光源(根據p(x);選擇一個b)查看上一頓選擇的光源;在這個光源和步驟a所選光源中二選一C)隨機選取鄰近數個像素,查看它們選擇的光源;在這些光源和步驟b所選光源中選擇一個計算光照;對每一像素只用一條射線:但是向步驟c所選光源發射陰影射線,光強計算結果根據RIS加權和來進行歸一化這條射線經過了仔細地挑選#page#基本ReSTIR算法ReSTIR: Reservoir Spatio-Temporal Importance Resampling預處理:根據光源的亮度創建一張別名采樣表(aliastable),以此來作為初始概率密度p(x)對每一像素在重用之前,多發射一條
22、射線a)隨機選取32個候選光源(根據p(x);選擇一個共用可見性;畫質大幅提升b)向步驟a所選光源發射一條陰影射線;如果不可見,丟棄c)查看上一頓選擇的光源;在這個光源和步驟b所選光源中二選一北一中米來心來限以是量“心(P計算光照;對每一像素向步驟d所選光源發射陰影射線,光強計算結果根據RIS加權和來進行歸一化#page#改進:基于BSDF采樣的ReSTIR重用樣本丟棄無效樣本遮擋導致重用失敗初始采樣樣本重用“ImportanceResampling forGlobat jtlumination”,EGSR2005#page#改進:基于BSDF采樣的ReSTIR算法預處理;根據光源的亮度創建一
23、張別名采樣表(aliastable),以此來作為初始概率密度p(x)對每一像素不再需要預處理a)隨機發射光線b)若交點自發光,更新時間樣本庫c)用附近像素樣本庫更新空間樣本庫計算光照;對每一像素向步驟c所選樣本發射陰影射線,若沒有遮擋,累加光照Fora deeper look,also see HPG 2020 talk“Reframing Lisht Transport for Real-time”#page#算法與實現到這里,我們已經創建了一個簡單、強大的算法,用于選擇高質量的陰影射線還有許多要完善的地方缺少產品化所需的特性存在靈活性、強壯性等問題#page#光源重采樣的實踐#page#我
24、們制作了一些演示.使用了ReSTIR研究時的實現代碼用SVGF降噪器來降噪叫做“ReLAX”(這個名字沒什么實際意義)制作和發布了ReSTIR視頻(2020年5月)https:/youtu.be/Hisexy6eoy8之后在0mniverse中開始實現ReSTIR來獲取更豐富的內容遇到了一些實際問題#page#“紀念品”場景原型WORKIN PROGRESS DEMO FOOTAGE#page#實際問題#1:動態發光模型我們想讓這些發光粒子飄動,然后分散成更小的粒子.#page#動態發光模型1/4原有ReSTIR實現:1.將發光模型分成三角形2.預計算自發光貼圖在加載時做一次3.在CPU上創建
25、別名采樣表(aliastable)不適合在GPU上做4.把aliastable上傳至GPU登薪森藥藥藥查5.用aliastable來選擇初始采樣6.應用時空重采樣全#page#動態發光模型2/4解決方案1:不使用aliastable1.將發光模型分成三角形2.預計算自發光貼圖3.把所有發光三角形計入一張全局CDF(累積概率密易于在GPU上實現度)表中二分法查找-log(N)4.用CDF的逆函數來選擇初始采樣在像素級別上開銷太大5.應用時空重采樣#page#動態發光模型3/4解決方案2:不逐像素使用CDF的逆函數,而是預先計算好采樣1.將發光模型分成三角形2.預計算自發光貼圖3.把所有發光三角形
26、計入一張全局CDF表中4.用CDF的逆函數創建一個光源ID數組,各光源在數組中出現的次數正比于其光強5.對每個像素,用這個光源數組來選擇初始采樣緩存性能差6.應用時空重采樣#page#動態發光模型4/4解決方案3:預采樣的光源分成小組,一光源小組用于一個像素塊1.將發光模型分成三角形2.預計算自發光貼圖3.把所有發光三角形計入一張全局CDF表中4.用CDF的逆函數創建一個光源小組的數組,各光源在數組中的數量正比于其光強5.對每一像素塊(1616像素),隨機選擇一個光源小組適用于所有像素6.用光源小組來選擇初始采樣7.應用時空重采樣nVIDI#page#實際問題#2:光源的描述各向均勻發光真實L
27、ED光源真實LED光源描述#page#模型光源vs.圖元光源模型光源靈活的形狀和貼圖公告牌、霓虹燈、日光燈管使用自發光材質來計算發光圖元光源靈活的光強描述文件(比如IES光域網)(球體、方形,等等)手電筒、街燈、帶燈罩的光源單一的固定形狀(不需要大量的三角形來表示)高效、低噪的采樣ZnVDIA#page#模型光源vs.圖元光源(未使用重采樣燈泡模型光源帶IES的圖元光源對一個明亮但被遮擋光源進行采樣#page#模型光源vS.圖元光源(ReSTIR)帶IES的圖元光源燈泡模型光源#page#模型光源vS.圖元光源(ReSTIR+降噪燈泡模型光源帶IES的圖元光源#page#圖元光源與ReSTIR
28、struct LightSample上ReSTIR可以與圖元光源無縫對接float3 positionfloat3normal;需要一個描述光源的通用接口float3 radiance;float solidAnglePdf;05interface IPolymorphicLight實現中需要不同的前端代碼來采集光照數據Lightsample Calcsamplefloat2randomuv,模型和圖元光源分別進行初始采樣float3 receiverPos);IPolymorphicLight Load(PackedLightInfo info)D5重采樣過程中,混合使用所有光源類型nVID
29、#page#實際問題#3:噪點Lnst TheoremBH1spp1spp + ReSTIR325PPnVIDL#page#把ReSTIR用作信號放大器一般的極好的ReSTIR采樣采樣糟糕的普通的ReSTIR采樣采樣nVIDI#page#糟糕和一般質量的初始采樣1Initial Sample#page#糟糕初始采樣的例子太多分離的房間光源照射到高光表面光源靠近物體表面使用光源剔除的算法(比如PVS增加初始采樣的數量在對BRDF采樣時增加MISnVIOL#page#時空重采樣偏差盲目重用來自其它表面的樣本會造成偏差在被遮擋的區域或運動區域,產生可見的變暗需要根據原有環境重新估算樣本的權值物體表面
30、的坐標和材質光源的位置與亮度潛在的遮光物體需要添加額外的陰影射線通??梢蕴^這一步=帶來些許的重采樣偏差#page#空間重采樣偏差初始/最終+時間可見性測試:僅初始/最終采樣初始/最終+空間初始/最終+時間+空間累積結果最終采樣有偏無偏nVDI#page#時間重采樣偏差(可見性)要做到完全正確,需要對上一頓的物體數據進行可見性測試實際當中這樣做很困難,需要保留上一的數據:TLAS形變物體的BLAS貼圖坐標數據過程材質的參數No ResamplingVisiibility#page#ReSTIR性能旋轉木馬55,940自發光三角形+環境貼圖24+8初始采樣4空間采樣有偏重采樣:7.4ms,TIT
31、ANRTX4.6ms,RTX3090無偏重采樣:14.4ms,TITANRTX8.2ms,RTX309019201080初始到最終采樣#page#ReSTIR性能桌面彈球夜景581,562自發光三角形131圖元光源2+2初始采樣4空間采樣有偏重采樣:10.1ms,TITANRTX6.1ms,RTX3090無偏重采樣:13.1ms,TITANRTX7.5ms,RTX309019201080初始到最終采樣#page#RTX DI SDK我們正在開發RTXDirectIlluminationSDK所有光源都投射動態陰影實時染數百萬動態光源可取代所有其它的陰影計算為ReSTIR算法專門優化Beta版:https:/