用Microsoft DirectX光线跟踪改善渲染质量
用Microsoft DirectX光線跟蹤改善渲染質量
Implementing Stochastic Levels of Detail with Microsoft DirectX Raytracing
細節層次(LOD)是指在細節可能不重要的情況下,用較低分辨率的網格替換遠處的高分辨率網格。這種技術有助于減少內存占用和幾何混疊。最重要的是,長期以來一直被用于提高游戲中的光柵化性能。但這是否同樣適用于光線跟蹤?
光柵化的渲染時間為O(N),其中N是三角形的數量,而光線跟蹤的渲染時間明顯優于O(logn)。因此,可能希望LOD對光線跟蹤不那么重要,但仍然可以提供有價值的性能改進。
在這篇文章中,將探討這個問題。此外,還演示了使用Microsoft DirectX光線跟蹤(DXR)API實現隨機詳細等級的一種可能方法。假設對DXR有基本的了解。有關更多信息,請參閱以下參考資料:
· Introduction to NVIDIA RTX and DirectX Ray Tracing
· DX12 Ray Tracing Tutorial Part 1
· DirectX Raytracing (DXR) Functional Spec (Microsoft)
· D3D12 Raytracing Samples (Microsoft)
Figure 1. Screenshot from the DXR sample provided with this post. LODs are beneficial in open scenes like this with large depth ranges. Color indicates the LOD level. The most distant models are rendered with 128 times fewer triangles than the closest ones (eight LODs, 2x reduction in triangle count between each level).
Stochastic LODs
隨機LOD是游戲用來在LOD之間創建更平滑過渡的主要技術。例如,在虛幻引擎4中,隨機LOD稱為抖動LOD轉換。如果沒有隨機技術,lod之間的突然、離散轉換可能會導致分散注意力的“彈出”偽影,即對象在外觀上突然移動。隨機LOD通過將像素隨機分配給更近或更遠的LOD,在LOD級別之間創建交叉融合(圖2)。有關更多信息,請參見查找下一代:CryEngine
2。《三維圖形與游戲課程中的SIGGRAPH高級實時渲染》,97-121頁。
Figure 2. Stochastic LOD with eight steps of transition with color encoding (top row) and without (bottom row). The transition has been exaggerated (64x reduction in triangle count) for this figure to make it easier to see the transition. Click image to enlarge.
LOD in DXR
為了實現離散的LOD轉換,根據每個對象到相機的距離,為其選擇一個LOD。距離較遠的對象使用較低分辨率的網格,距離較近的對象使用較高分辨率的網格。
在示例中,使用對象在相機空間中的深度來計算LOD參數,l在深度z_n處從0持續變化到深度z_f處的l,其中l是對象的LOD數。z_n和z_f是根據給定場景的特征選擇的,很像光柵化中深度緩沖區的近距離和遠距離。有關計算LOD參數的詳細信息,請參見示例代碼中的ChooseLod函數。然后直接使用給定對象的LOD參數選擇其網格。
由于LOD參數隨相機或對象的移動而變化,因此必須為每幀的每個對象重新計算LOD參數。然后,使用指向正確網格lod的更新指針重建頂級加速結構(TLAS)。游戲通常會在每幀重建TLAS來處理動態對象,因此這種重建不會產生任何額外的開銷。
Secondary rays and LOD
大多數支持光線跟蹤的游戲使用前面描述的離散LOD方法,因為既簡單又有效。關鍵的是,還匹配許多混合渲染器中光柵化過程的LOD選擇行為。混合渲染是游戲中常見的一種方法,其中帶有主要命中數據的G緩沖區是使用傳統的光柵方法生成的,而隨后的光線跟蹤過程則使用該數據作為計算反射或陰影等次要效果的起點。
無論主要命中是通過光柵化過程還是通過光線跟蹤生成的,這都是需要記住的一件重要事情:任何從主要命中開始的次要光線都必須“看到”與主要光線(或光柵化器)相同的對象lod。如果不能保證這一點,則意味著由于主光線和次光線之間的場景表示不匹配,次光線可能會錯過交點或找到虛假的命中(圖3)。這反過來又會導致視覺偽影,如光線泄漏、反射中的對象消失或陰影區域不正確。
主光線和次光線在被主光線擊中的對象的LOD級別上達成一致是不夠的。其不相關的對象可能離主要攻擊點很近,也會導致前面提到的健壯性問題,因此這些對象也必須是一致的。這個問題也不限于從主光線到次光線的過渡。也適用于更高級別的反彈,例如反射的反射、多反彈全局照明等。
Figure 3. Spurious shadows resulting from using a higher LOD for primary rays (LOD0) and lower LOD for secondary rays (LOD1).
也就是說,在某些情況下,如果應用程序故意違反一條路徑上的所有光線都應看到相同的lod的原則,則可能是有益和可接受的。例如,可以想象根據場景的高細節表示來跟蹤一條較短、因而相對便宜的次光線。如果短光線未命中,則可以從第一條光線的終點開始跟蹤另一條較長的光線,但該光線的細節要低得多。
根據不同的因素,比如短射線和長射線之間的閾值距離以及場景細節的差異,這種方法可能會在性能上獲得回報。但是,由于場景lod在短光線和長光線之間變化,應用程序必須接受無效或錯過交點的可能性。因此,這種想法只有在某些誤差可以接受的情況下才可行,例如非常漫反射效果或更高級別的光反彈。并沒有在這篇文章中探索這條道路,而是想強調是進一步實驗的起點。
Stochastic LOD transitions
對于隨機LOD轉換,對象可以處于兩個LOD之間的中間狀態轉換。在TLAS中包含兩個lod,但是需要一種方法來選擇兩個lod中的哪一個與每個像素相交。此外,該選擇需要獨立于每個對象進行,因為不同的對象可能位于LOD轉換中的不同點上。
DXR支持在TLAS構建時指定一個8位實例掩碼,然后將該掩碼與每射線掩碼組合,以確定是否應測試實例的交集或忽略實例。具體來說,這兩個面具是安第斯在一起。如果結果為零,則忽略實例。使用此實例掩碼功能在兩個相鄰的lod之間隨機選擇。
Transition interval
k_a=\min(0,lfloor l\rfloor)和k_b=\max(\lceil l\rceil,l-1)給出了過渡兩邊lod的索引,l的小數部分f=l-\lfloor l\rfloor給出了之間的過渡程度。
實際上,可能希望在較短的時間間隔內進行轉換。如果在[0,1]中用t參數化轉換間隔,其中0表示沒有轉換間隔,只是從一個級別到下一個級別的離散步驟,1表示轉換發生在一個LOD的整個范圍內,則可以將f修改為f’=\mathrm{clamp}((f-0.5)/t+0.5,0,1)。
圖4顯示了不同t值的f’。
Figure 4. Remapping the fractional part of the LOD parameter to shorten the duration of the transition, , from one LOD to the next.
Setting the instance masks
初始化了實例面罩,以便在每個光線面罩中設置一個隨機位會產生所需的交叉溶解效果。對于每個對象,需要兩個實例,一個用于LOD k_a,另一個用于k_b。將k_b的實例掩碼中的位數(總共8位)設置為與轉換度f’成比例。k_a的躍遷度是1-f’。通過補充k_b的掩碼來設置k_a的實例掩碼。
代碼如下所示:
maskB = (1 << int((8 + 1)*f_prime) ) - 1;
maskA = (~maskB) & 0xFF;
在光線生成著色器中調用TraceRay時,將8位光線面罩設置為單個均勻隨機位。這將根據各自的轉換程度選擇k_a或k_b。因為相鄰光線可能使用不同的隨機光線面罩,所以這會產生所需的隨機過渡效果。
沿路徑傳播光線面罩
如前所述,當跟蹤具有多個反彈的路徑時,路徑中的后續光線看到相同的lod是很重要的。為了使用隨機方法實現這一點,對路徑上的每條光線使用相同的光線面罩。DXR無法查詢當前光線面罩,因此使用光線負載將其傳播到最近的命中著色器。
Limitations
隨機LOD實現在NVIDIA RTX GPUs上是完全硬件加速的,但是有一些限制。一個限制是實例和光線面罩僅由8位組成,這意味著對于隨機LOD轉換,只能得到8個級別(圖2)。這一點越明顯,移動越慢,lod之間的過渡間隔越寬。
另一個限制是,將實例和光線面罩用于隨機詳細等級會使無法用于其用途,例如啟用或禁用某些幾何體組。有時可以劃分掩碼位以適應不同的用例,但這進一步減少了轉換級別的數量。
與離散LOD相比,隨機LOD也會受到一些性能損失。通常,隨機LOD會由于相鄰像素對不同對象的跟蹤而增加GPU的扭曲散度。實現的隨機LOD還使TLAS中的實例數量增加了一倍,這稍微增加了TLAS的構建時間。
Stochastic LOD example
圖1顯示了本文中包含的示例代碼的屏幕截圖。實現了光線跟蹤反射、陰影和環境光遮擋。
場景中的對象根據其LOD著色,最高LOD為紅色,最低LOD為藍色。場景本身由幾個實例armadillo模型組成。為模型的每個LOD建立一個底層加速結構(BLAS)。TLA是根據隨機旋轉的實例構建的,這些實例引用所選LOD的BLAS。
可以使用多個設置調整LOD參數。LOD范圍(z_n和z_f)以標準化坐標表示,其中值1表示整個場景的半徑。LOD偏移將偏移計算的LOD參數。
當相機靜止時,幀累積到輸出中以提供抗鋸齒。每個子幀都有自己的隨機種子。在多個幀上,隨機LOD的累積產生兩個LOD之間的混合。為了更好地看到隨機LOD的效果,請暫停子幀。若要查看各個過渡級別,請將“過渡間隔”擴展到1并緩慢移動“細節層次偏移”滑塊。這就是創建圖2的方式。
示例中使用的LOD網格是使用QSlim生成的,QSlim是一個命令行實用程序,將OBJ格式的輸入網格減少為指定數量的三角形。可能想用QSlim來試驗自己的模型。
實施細節
大多數示例代碼都是直接的DirectX 12。從DX12光線跟蹤教程第1部分開始編寫代碼,但只保留了幾個用于著色器綁定表布局和為光線跟蹤管道創建狀態對象的助手類。
LOD選擇步驟在GPU上執行。為了簡單起見,使用光線生成著色器而不是計算著色器來實現。這避免了設置另一個管道狀態對象的需要。由于LOD選擇和渲染之間共享了一些參數,因此將所有參數放在一個公共的常量緩沖區中。
LOD selection明暗器填充設備上的實例描述符數組,然后用于構建tla。相關的C++結構體D3D12MayRracTraceInStasySDEC使用了幾個位字段。HLSL不支持位字段,因此必須手動將字段打包到uint中。
Performance
為了評估性能,提供了兩種基準測試模式,可通過按以下數字鍵調用:
1: 瀏覽多個預定義視圖。 Sweep through several predefined views.
2: 掃描過渡間隔的范圍。 Sweep through the range of transition
intervals.
圖5顯示了第一種模式的視圖。第一個視圖是從空中透視整個場景。隨后的視圖與平面的角度越來越小。
Figure 5. The four views used in the benchmark: “top” (upper-left), “high” (upper-right), “low” (lower-left), and “close” (lower-right).
圖5顯示了在NVIDIA GeForce RTX 2080Ti上獲得的渲染時間,該RTX有64×60個實例和8個lod。渲染時間因視圖而異。圖6還顯示了LOD可以實現顯著的加速:對于幾乎所有對象都以低LOD渲染的俯視圖,可以達到2.2x。
Figure 6. Render times and speedups for each view.
正如預期的那樣,隨機LOD比離散LOD稍慢,加速比更低。幀時間、LOD選擇時間和TLAS構建時間的其組件獨立于視圖。看到平均LOD選擇時間為0.018ms,TLAS構建時間為0.22ms。
圖7顯示了改變轉換間隔的效果。此實驗有助于分離相鄰光線使用不同的光線面罩跟蹤不同對象的影響。
Figure 7. The effect of varying the transition interval for stochastic LOD on the “low” view.
隨著躍遷間隔的增加,光線之間的發散量也會增加,這會對性能產生負面影響。但是,最高約為10%,這一成本是有限的。當過渡間隔為0時,渲染結果等效于離散LOD。唯一的區別是在TLAS中每個對象仍然有兩個實例,而不是一個。這只占渲染時間的1.6%。
結論
源碼地址:https://developer.download.nvidia.com/devblogs/DxrLod.zip
有了這篇文章和附帶的示例代碼,展示了一個直接的、離散的LOD機制,正在各種航運游戲中使用。表明,根據具體情況,這種機制所提供的加速效果是顯著的。還演示了在DXR中實現完全硬件加速的隨機LOD方法的一種可能方法,該方法在對性能影響很小的情況下顯著減少了離散LOD的彈出偽影。
鼓勵在這里下載示例的源代碼和模型并使用。快樂的實驗!
總結
以上是生活随笔為你收集整理的用Microsoft DirectX光线跟踪改善渲染质量的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 用NVIDIA A100 GPUs提高计
- 下一篇: CUDA刷新:GPU计算生态系统