這篇文章根據(jù)我們目前在游戲中使用 NVIDIA RTX 光線跟蹤的經(jīng)驗收集了最佳實踐。實用技巧被組織成簡短的、可操作的項目,供今天從事光線跟蹤工作的開發(fā)人員使用。他們旨在深入了解什么樣的解決方案在大多數(shù)情況下會帶來良好的性能。為了找到特定案例的最佳解決方案,我總是建議進行分析和實驗。
本文中使用的常見縮寫和短詞:
AABB: 軸對齊邊界框
AS :加速度結(jié)構(gòu)
BLAS: 底層加速結(jié)構(gòu)
Geometry: 和 BLAS 中的幾何體
Instance: TLAS 中 BLAS 的實例
TLAS: 頂層加速結(jié)構(gòu)
加速結(jié)構(gòu)
本節(jié)重點介紹光線跟蹤加速結(jié)構(gòu)的構(gòu)建和管理,這是將光線跟蹤用于任何目的的起點。主題包括:
一般提示
建筑時最大化 GPU 利用率
內(nèi)存分配
將幾何圖形組織為 BLAS
生成首選項標(biāo)志
動態(tài) BLASE
非不透明幾何形狀
粒子
一般提示
考慮異步計算作為構(gòu)建。 特別是在混合渲染中, G 緩沖區(qū)或陰影貼圖被光柵化,在異步計算的基礎(chǔ)上執(zhí)行可能是有益的。
考慮將工作線程生成為構(gòu)建命令列表。 生成生成生成命令可能包括大量 CPU 端工作。它可以直接在編譯調(diào)用中,也可以直接在一些相關(guān)任務(wù)中,如對象的剔除。將 CPU 工作轉(zhuǎn)移到一個或多個工作線程可能是有益的。
TLA 的剔除實例。 通常,在 TLAS 中包括整個場景不是最佳的。相反,根據(jù)情況挑選實例。例如,考慮基于擴展的相機截錐體進行消隱。在光柵化中,最大距離通??梢孕∮谶h平面距離。在剔除時,還可以考慮實例大小,以便在較短的距離內(nèi)剔除較小的實例。
對實例使用適當(dāng)?shù)脑敿毘潭龋?LOD )。 與光柵化一樣,對所有內(nèi)容使用最詳細的幾何 LOD 通常是次優(yōu)的。用于遠距離對象的 LOD 可以更簡單。在混合渲染中,可以考慮使用相同的 LOD 進行光柵化和光線跟蹤。這是避免自相交偽影(如曲面陰影本身)的有效方法。
還應(yīng)考慮在光線跟蹤中使用較低細節(jié) LOD ,特別是為了降低動態(tài) BLAS 的更新成本。如果光柵化和光線跟蹤之間的 LOD 不匹配,則在光線跟蹤中通常需要啟用背面消隱,以防止自相交。有關(guān)光線跟蹤中 LOD 的更多信息,以及如何實現(xiàn)隨機 LOD ,請參見 使用 Microsoft DirectX 光線跟蹤實現(xiàn)隨機細節(jié)級別 。
盡可能將幾何體或?qū)嵗龢?biāo)記為不透明。 將實例或幾何體標(biāo)記為不透明允許不間斷的硬件交叉點搜索,并防止調(diào)用任何命中著色器。盡可能做到這一點。只允許對需要的幾何體使用任何命中著色器;例如,進行 alpha 測試。
盡可能使用三角形幾何形狀。 硬件擅長執(zhí)行光線三角形相交。光線盒交點也會加速,但在跟蹤三角形幾何體時,您可以充分利用硬件。
建筑時最大化 GPU 利用率
批處理頂點變形和 BLAS 構(gòu)建。 連續(xù)執(zhí)行所有頂點變形調(diào)用,生成用作 BLAS 構(gòu)建和所有 BLAS 構(gòu)建調(diào)用輸入的三角形。不要在連續(xù)通話之間設(shè)置資源障礙。這允許驅(qū)動程序在一定程度上并行調(diào)用。所有 BLAS 構(gòu)建調(diào)用都需要唯一的暫存內(nèi)存,以允許無障礙執(zhí)行。
無需為每個資源持有區(qū)設(shè)置單獨的無人機屏障。相反,在 TLAS 構(gòu)建之前,您可以有一個單一的全球 UAV 屏障,以確保所有 BLAS 構(gòu)建都已完成,無論它們位于何處。
考慮合并小頂點變形調(diào)用。 通常,為一個幾何體或?qū)嵗敵鲎冃雾旤c的調(diào)用是輕量級的,即使在連續(xù)調(diào)用之間沒有障礙的情況下執(zhí)行,也不會填充整個 GPU 。將多個幾何圖形或?qū)嵗奶幚砗喜⒌揭粋€調(diào)用中可以提高 GPU 利用率并產(chǎn)生更好的性能。
內(nèi)存分配
匯集小額撥款: BLASE 可以很小,有時只有幾千字節(jié)。使用單獨的提交資源來存儲每個這樣的小 BLA 并不是最優(yōu)的。相反,用更大的資源集中他們。池可以節(jié)省內(nèi)存,通??梢蕴岣咝阅?。一種選擇是在大型資源堆中使用放置的資源。
或者,通過手動從緩沖區(qū)中分配部分,可以將許多 BLAE 存儲在單個緩沖區(qū)中。由于子分配只需遵循 256 字節(jié)對齊,因此這允許更緊密地將 BLASE 備份到內(nèi)存中。無論采用何種池機制,都要避免內(nèi)存碎片,以保持池帶來的好處。
考慮壓縮靜態(tài) BLAS: 壓縮 BLASE 可以節(jié)省內(nèi)存并提高性能。內(nèi)存消耗的減少取決于幾何形狀,但可能高達 50% 左右。由于在 GPU 上完成 BLAS 構(gòu)建后,需要將壓縮大小讀回 CPU ,這對于只構(gòu)建一次的 BLAS 最為實用。請記住,要集中小的分配并避免內(nèi)存碎片,以從壓縮中獲得最大的好處。
將幾何圖形組織為 BLAS
當(dāng)實例的世界空間 AABB 中有很多空白空間時,考慮拆分 BLA 。 世界空間 AABB 用于測試光線是否可能擊中實例并遍歷其相關(guān) BLA 。大量的空白會導(dǎo)致通過 BLAS 進行不必要的遍歷。
獨立移動的幾何體通常應(yīng)該在自己的 BLAS 中。將它們合并到單個 BLAS 中可能會導(dǎo)致一個具有大量空白空間的 AABB ,以及不必要的 BLAS 重建,而不是簡單地更改獨立實例的轉(zhuǎn)換。
當(dāng)實例世界空間 AABB 顯著重疊時,考慮合并 BLASE 。 當(dāng)實例的世界空間 AABBs 重疊時,穿過該區(qū)域的每條光線必須分別處理所有重疊的 BLAS 實例,以找到潛在的交點。遍歷一個合并的 BLA 將更有效。
針對 BLAS 的跟蹤性能不取決于其中幾何體的數(shù)量。合并到單個 BLAS 中的幾何體仍然可以具有獨特的材質(zhì)。
盡可能實例化 BLAS 。 實例化 BLASE 可以節(jié)省內(nèi)存。它還可以提高光線跟蹤性能。實例可以具有唯一的材質(zhì)和變換。在實例的 AABB 重疊很多的情況下,盡管內(nèi)存消耗增加,但將它們復(fù)制并合并為單個 BLA 作為多個幾何體仍然是更好的選擇。
避免幾何形狀中的細長三角形。 長而薄的三角形具有非最佳邊界體積,具有大量的空白空間。它們很容易與許多其他邊界體積重疊。當(dāng)根據(jù)幾何體跟蹤光線時,這會導(dǎo)致非最佳性能。
駕駛員可以根據(jù)幾何形狀在一定程度上緩解問題。第一個三角形不太可能引起問題,但太多的三角形確實會引起問題,因此我建議盡可能避免它們;例如,將它們分割成較小的三角形。
不要在 TLA 中包含天空幾何體。 天盒或天球?qū)⒂幸粋€ AABB ,與其他所有物體重疊,所有光線都必須進行測試。對于表示天空的幾何體,在未命中著色器中處理天空著色比在命中著色器中更有效。
生成首選項標(biāo)志
對于 TLA ,考慮PREFER_FAST_TRACE標(biāo)志并僅執(zhí)行重建。通常,這會產(chǎn)生最佳的整體性能。其基本原理是,無論場景中發(fā)生何種移動,盡可能高質(zhì)量地制作 TLA 都很重要,而且成本不高。
對于靜態(tài) BLASE ,使用PREFER_FAST_TRACE標(biāo)志。對于所有只構(gòu)建一次的 BLASE ,優(yōu)化最佳光線跟蹤性能是一個簡單的選擇。
對于動態(tài) BLASE ,請選擇使用PREFER_FAST_TRACE或PREFER_FAST_BUILD標(biāo)志,或者兩者都不使用。對于偶爾重建或更新的 BLAE ,最佳構(gòu)建首選項標(biāo)志取決于許多因素。建造了多少?射線痕跡有多貴?可以通過在異步計算上執(zhí)行構(gòu)建來隱藏構(gòu)建成本嗎?為了找到特定情況下的最佳解決方案,我建議嘗試不同的選項。
動態(tài) BLASE
盡可能重復(fù)使用舊 BLA 。 如果您知道 BLAS 的頂點在上次更新后沒有移動,請繼續(xù)使用舊 BLAS 。
僅為可見對象更新 BLAS 。 當(dāng)從 TLA 中剔除實例時,也將其剔除的 BLAS 從 BLAS 更新過程中排除。
考慮根據(jù)距離和大小跳過更新。 有時不需要在每一幀上更新 BLA ,這取決于它在屏幕上的大小??梢蕴^某些更新,而不會引起明顯的視覺錯誤。
在大變形后重建 BLASE 。 有限變形后的 BLAS 更新是一個不錯的選擇,因為它們比重建便宜得多。然而,先前重建后的大變形可能會導(dǎo)致非最佳光線跟蹤性能。細長的三角形加劇了這個問題。
考慮定期重建更新的 BLASE 。 當(dāng)幾何體變形過大并且需要重建以恢復(fù)最佳光線跟蹤性能時,可以進行檢測。簡單地定期重建所有 BLASE 是一種合理的方法,可以避免顯著的性能影響,而不考慮變形。
在框架上分布重建。 由于重建比更新慢得多,因此在單個幀上進行的許多重建可能會導(dǎo)致口吃。為了避免這種情況,最好將重建分布在框架上。
考慮僅使用具有不可預(yù)測變形的重建。 在某些情況下,當(dāng)幾何體變形足夠大和快速時,在構(gòu)建 BLAS 時省略ALLOW_UPDATE標(biāo)志并始終重建它是有益的。如果需要,可以考慮使用PREFER_FAST_BUILD標(biāo)志來降低重建成本。在極端情況下,使用PREFER_FAST_BUILD標(biāo)志會比使用PREFER_FAST_TRACE標(biāo)志和更新產(chǎn)生更好的整體光線跟蹤性能。
避免在 BLAS 更新中更改三角形拓撲。 更新中的拓撲變化意味著三角形退化或復(fù)活。如果退化三角形的位置不代表恢復(fù)三角形的位置,則可能導(dǎo)致非最佳光線跟蹤性能?!皬澢弊冃沃信紶柊l(fā)生的拓撲變化通常不會造成問題,但“斷裂”變形中較大的拓撲變化可能會造成問題。
在可能的情況下,最好使用單獨的 BLAS 版本,或?qū)Α捌茐摹弊冃我鸬牟煌負涫褂梅腔顒尤切巍.?dāng)三角形的位置為 N A N 時,三角形處于非活動狀態(tài)。如果這些替代方案不可行,我建議重建 BLAS ,而不是在拓撲更改后更新。更新中不允許通過索引緩沖區(qū)修改來更改拓撲。
非不透明幾何形狀
盡可能減少非不透明區(qū)域。 調(diào)用任何命中著色器(通常用于對非不透明三角形執(zhí)行 alpha 測試)會中斷硬件交點搜索。盡可能減少未標(biāo)記為不透明的區(qū)域是提高性能的簡單方法。使用更多的三角形更準(zhǔn)確地定義非不透明區(qū)域可能是一個很好的權(quán)衡。
考慮拆分為不透明和非不透明幾何體。 當(dāng)定義良好的幾何三角形部分可以被視為完全不透明時,可以考慮將其拆分為單獨的幾何體并將其標(biāo)記為不透明。不同的幾何形狀仍然可以駐留在同一 BLAS 中。
粒子
考慮將公告牌粒子表示為三角形幾何體。 在 BLASE 中表示廣告牌粒子的一個選項是將廣告牌輸出為三角形,將廣告牌的一部分沿垂直軸旋轉(zhuǎn) 90 度到不同的方向。這允許利用三角形相交硬件,同時為粒子的視覺邊界提供合理的近似。
考慮 alpha 測試而不是混合。 根據(jù)粒子類型,在二次光線中對渲染主可見性時混合的粒子進行 alpha 測試可能會提供合理的視覺質(zhì)量。這種方法最適用于邊界清晰的粒子。對于表示煙或霧等物體的粒子,這可能不適用。有關(guān)更多信息,請參閱 光線跟蹤 《沃爾芬斯坦:年輕的血液》中的思考 。
避免對死粒子使用退化三角形。 更新 BLASE 中的退化三角形可能會使結(jié)構(gòu)對于光線跟蹤而言不是最優(yōu)的。對于具有動態(tài)活粒子數(shù)的粒子系統(tǒng),我建議考慮其他解決方案,例如使用正確的粒子數(shù)在每個幀上重建 BLAS 。
考慮將網(wǎng)格粒子表示為 TLA 中的實例。 對于渲染為三角形網(wǎng)格的粒子,每個粒子都有一個唯一的實例是一個合理的解決方案。當(dāng)粒子在場景周圍分布時,這是真實的,因此單個光線通常不會擊中許多實例。實例應(yīng)共享基礎(chǔ)網(wǎng)格 BLAS 。此外,考慮壓縮 BLAS 。
點擊著色
本節(jié)重點介紹光線命中的著色。即使是經(jīng)驗豐富的圖形開發(fā)人員在開始開發(fā)光線跟蹤著色器時也可能會受益于新想法,因為最佳解決方案可能與光柵化中的不同。主題包括:
一般提示
最小化分歧
任何命中著色器
著色器資源綁定
內(nèi)聯(lián)光線跟蹤
管道狀態(tài)
一般提示
保持光線有效載荷較小。 寄存器用于保存有效負載值,它們減少了命中著色器可用的寄存器數(shù)量。我建議避免草率使用有效負載,盡管向包值中添加復(fù)雜代碼很少有好處。
使用有效負載訪問限定符。 此功能在 HLSL 著色器模型 6.6 中可用。它允許指定哪些著色器階段寫入或讀取有效負載中的每個字段,并使編譯器能夠更好地優(yōu)化寄存器使用,從而提高占用率和性能。為了獲得最大的潛在效益,請盡可能準(zhǔn)確地定義每個字段的限定符。有關(guān)更多信息,請參閱 GitHub 上的 DirectX-Specs 。
考慮將安全默認(rèn)值寫入未使用的有效負載字段。 當(dāng)某些著色器不使用負載中其他著色器所需的所有字段時,仍然可以將安全默認(rèn)值寫入未使用的字段。這允許編譯器在寫入之前丟棄未使用的輸入值,并將有效負載寄存器用于其他目的。
盡可能在第一次擊中時終止射線。 當(dāng)不需要解析正確的最近命中時(對于陰影光線),使用RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH或gl_RayFlagsTerminateOnFirstHitEXT標(biāo)記光線是一種簡單有效的優(yōu)化。
僅當(dāng)需要正確性時才使用面剔除。 與光柵化不同,啟用背面或正面消隱不會提高性能。相反,它稍微減慢了光線遍歷。僅當(dāng)需要獲得正確的渲染結(jié)果時才使用它們。
最小化光線跟蹤調(diào)用的活動狀態(tài)。 在TraceRay或traceRayExt調(diào)用之前初始化并在調(diào)用后使用的變量是活動狀態(tài),在調(diào)用命中和未命中著色器時必須在調(diào)用過程中保持這些狀態(tài)。司機有幾種不同的選擇,但都有成本。
我建議盡量減少活動狀態(tài)的數(shù)量。識別這樣的變量并不總是微不足道的。 NVIDIA 和微軟正在合作開發(fā)一種編譯器功能,用于自動檢測活動狀態(tài)。
避免深度遞歸。 深度、非均勻光線遞歸可能代價高昂。
最小化分歧
對每個材質(zhì)模型使用單獨的命中著色器。 減少命中著色器中的代碼和數(shù)據(jù)發(fā)散是有幫助的,尤其是在非相干光線的情況下。特別是,避免在材質(zhì)模型之間手動切換的 U bershader 。在單獨的命中著色器中實現(xiàn)每個所需的材質(zhì)模型,為系統(tǒng)提供了管理發(fā)散命中著色的最佳可能性。
當(dāng)材質(zhì)模型允許使用統(tǒng)一的著色器而沒有太多分歧時,可以考慮對具有各種材質(zhì)的幾何體使用公共命中著色器。
考慮簡化著色。 通常,不需要復(fù)制用于渲染主要可見性的所有功能,以進行著色鏡面反射或間接漫反射照明。忽略特征并不總是導(dǎo)致顯著的視覺差異。或者,視覺效果的改善并不能證明渲染成本是合理的。光線越不相干,通常需要的主要可見性特征的復(fù)制越不準(zhǔn)確。此外,隨著命中距離的增加,著色有時可以進一步簡化。
避免直接從頂點和像素著色器轉(zhuǎn)換。 在命中著色中獲得最佳性能的方法不同于光柵化的最佳方法。在光柵化中,即使代碼差異很小,也可以使用單獨的著色器置換。在命中著色中,減少單個命中著色器內(nèi)的發(fā)散度和單獨命中著色器的數(shù)量都很有幫助。通常,我不建議直接將頂點和像素著色器轉(zhuǎn)換為命中著色器。
考慮將公共代碼移到命中和未命中著色器之外。 當(dāng)所有命中著色器都有一個公共部分時,我建議將該代碼從命中著色器中移除;例如,到光線生成著色器。有時,命中著色器和未命中著色器中也可能存在常見代碼,例如,當(dāng)命中著色器中下一次反彈的近似值與未命中著色器中第一次反彈的近似值相同時。同樣,我建議將該常見代碼移到命中和未命中著色器之外。
任何命中著色器
更喜歡統(tǒng)一和簡化的任何命中著色器。 在光線遍歷期間,可能會大量執(zhí)行任意命中著色器,并且它會中斷硬件交點搜索。任何命中著色器的成本都會對整體性能產(chǎn)生顯著影響。我建議在光線跟蹤過程中使用統(tǒng)一且簡化的任意命中著色器。此外, GPU 的完整寄存器容量不適用于任何命中著色器,因為它的一部分被驅(qū)動程序用于存儲光線狀態(tài)。
優(yōu)化對材料數(shù)據(jù)的訪問。 在任何命中著色器中,對材質(zhì)數(shù)據(jù)的最佳訪問通常至關(guān)重要。一系列相關(guān)內(nèi)存訪問是一種常見模式。加載頂點索引、頂點數(shù)據(jù)和采樣紋理。在可能的情況下,從該路徑中刪除間接操作是有益的。
混合時,請記住未定義的點擊順序。 沿光線的點擊被發(fā)現(xiàn),并且相應(yīng)的任何點擊著色器調(diào)用以未定義的順序發(fā)生。這意味著混合技術(shù)必須與順序無關(guān)。這還意味著,為了排除最近的不透明命中之外的命中,必須適當(dāng)限制光線距離。此外,可能需要使用NO_DUPLICATE_ANYHIT_INVOCATION標(biāo)記混合幾何體,以確保結(jié)果正確。有關(guān)更多信息,請參閱 光線跟蹤寶石 中的第 9 章。
著色器資源綁定
如果可能,首選全局根表( DXR )或直接描述符訪問( Vulkan )。 通常,光線生成和未命中著色器使用的資源可以像計算著色器一樣方便地綁定,而不是通過著色器記錄綁定。此外,不管命中了什么,通常也可以這樣綁定使用的命中著色器資源。在所有命中記錄中具有相同的資源限制不是最優(yōu)的。
考慮 hit 著色器的無綁定資源。 無界描述符表( DXR )或無大小描述符數(shù)組( Vulkan )中的資源,由命中特定的系統(tǒng)值(如 InstanceIndex 或 gl _ InstanceID )或直接存儲在命中記錄中的值( DXR 中的根常數(shù))索引,可以是向命中著色器提供資源的有效方法。
考慮索引和頂點緩沖區(qū)的根描述符。 ( DXR )作為無界描述符表的替代方法,可以高效地將索引和頂點緩沖區(qū)地址直接存儲在命中記錄中作為根描述符。當(dāng)通過根描述符訪問資源時,不會隱式執(zhí)行越界檢查。根描述符地址必須遵循四字節(jié)對齊。預(yù)計算到基址的 16 位索引的偏移量可能會破壞對齊。
盡可能使用根簽名版本 1.1 和靜態(tài)描述符。 ( DXR )根簽名 1.1 允許驅(qū)動程序預(yù)期描述符是靜態(tài)的;也就是說,在記錄命令列表后,應(yīng)用程序不會修改它們。這可以在驅(qū)動程序中實現(xiàn)一些潛在的有益優(yōu)化,尤其是當(dāng)根描述符不用于訪問緩沖區(qū)時。與根描述符一樣,越界檢查不是用靜態(tài)描述符隱式執(zhí)行的。此外,靜態(tài)描述符和根描述符都不能為 null 。
考慮在 GPU 上構(gòu)建著色器表。 當(dāng)有許多幾何體和許多光線跟蹤過程時,命中表可能會變大,上載它們可能會耗費大量時間。與其上載在 CPU 上構(gòu)建的整個命中表,不如只上載每個幀上所需的新信息,例如當(dāng)前可見實例的材質(zhì)索引,然后在 GPU 上執(zhí)行命中表構(gòu)建過程以提高效率。
表構(gòu)造中所需的大部分信息可以永久駐留在 GPU 內(nèi)存中,例如命中組標(biāo)識符、頂點緩沖區(qū)地址和幾何體的偏移量。
內(nèi)聯(lián)光線跟蹤
考慮螺紋組尺寸為 8 × 8 或更大。 作為計算著色器進行內(nèi)聯(lián)光線跟蹤的經(jīng)驗法則,可以使用大小為 8 × 8 的線程組。通常,一組中的線程數(shù)是 GPU 波大小的倍數(shù)是有效的。 NVIDIA GPU 中的波形大小為 32 個線程。
然而,由于同時執(zhí)行的組數(shù)量有限,使用只有一個波形的線程組限制了線程占用。一組中有兩個波浪會使?jié)撛谡加寐史?。著色器寄存器和組共享內(nèi)存消耗也可以設(shè)置占用限制。當(dāng)其他因素允許時,可以從三個波組開始達到最大線程占用率。
組大小的實際選擇可以是 16 × 8 螺紋。將尺寸增加到遠遠超出此范圍通常是沒有好處的。通過不同尺寸的實驗,可以發(fā)現(xiàn)針對特定情況的最佳尺寸。不同硬件代的最佳尺寸可能不同。
使用內(nèi)聯(lián)光線跟蹤避免發(fā)散著色。 由于未基于命中調(diào)用命中著色器,因此所有著色都在投射光線的著色器中內(nèi)聯(lián)發(fā)生。在根據(jù)點擊數(shù)選擇的著色器中具有發(fā)散的代碼路徑或數(shù)據(jù)訪問可能會減慢著色速度,尤其是在光線不相干的情況下。當(dāng)需要多個不同的著色模型時,使用DispatchRays或vkCmdTraceRaysKHR是更好的選擇。
使用 hit 特定的系統(tǒng)值進行內(nèi)聯(lián)光線跟蹤的無綁定資源訪問。由于命中記錄中的綁定不可用,因此必須通過其他方式提供特定于幾何體的綁定。基于特定于 hit 的系統(tǒng)值(如InstanceContributionToHitGroupIndex和GeometryIndex)訪問無界描述符表中的資源是一種很好的做法。
我建議盡可能避免間接訪問索引、頂點和材質(zhì)數(shù)據(jù)。例如,基于系統(tǒng)值(如InstanceID)從緩沖區(qū)讀取資源索引以選擇索引緩沖區(qū)可能會導(dǎo)致難以隱藏的延遲。
首選編譯時光線標(biāo)志。 編譯時和運行時光線標(biāo)志都可以用于內(nèi)聯(lián)光線跟蹤。我建議盡可能使用編譯時標(biāo)志,因為它們可以實現(xiàn)有益的編譯時優(yōu)化。
監(jiān)視查詢對象的寄存器消耗。 初始化后,當(dāng)著色器執(zhí)行可能繼續(xù)遍歷的代碼時,查詢對象必須保持光線遍歷的狀態(tài)。這會消耗寄存器,復(fù)雜的用戶代碼可能會比通常更快地限制占用。這種情況類似于在DispatchRays或vkCmdTraceRaysKHR過程中執(zhí)行任何命中著色器。在使用查詢對象之前初始化并在之后使用的變量可能會消耗額外的寄存器。
考慮線程組重新排序以提高一致性。 當(dāng)使用來自計算著色器的內(nèi)聯(lián)光線跟蹤時,調(diào)度線程組的默認(rèn)行主分配到 GPU 執(zhí)行通常不會產(chǎn)生最佳性能。通過手動重新排序線程組,可以提高在 GPU 上執(zhí)行時線程組同時進行的內(nèi)存訪問的一致性。有關(guān)更多信息,請參閱 光線跟蹤管道狀態(tài)的并行著色器編譯 。
管道狀態(tài)
考慮每個光線生成著色器一個狀態(tài)對象。 我建議為每個DispatchRays或vkCmdTraceRaysKHR調(diào)用使用該過程中所需的著色器編譯一個單獨的狀態(tài)對象。它可以幫助優(yōu)化寄存器消耗,并允許優(yōu)化本文后面描述的管道配置值設(shè)置。
將MaxTraceRecursionDepth、MaxRecursionDepth、MaxPayloadSizeInBytes , 和MaxAttributeSizeInBytes設(shè)置得盡可能小。將這些值設(shè)置為高于必要值可能會對性能產(chǎn)生不必要的負面影響。在DispatchRays或vkCmdTraceRaysKHR調(diào)用中使用內(nèi)聯(lián)光線跟蹤時,這些光線跟蹤調(diào)用不計入最大遞歸深度。
盡可能使用SKIP_PROCEDURAL_PRIMITIVES, SKIP_AABBS , 和SKIP_TRIANGLES。這些管道狀態(tài)標(biāo)志允許在狀態(tài)編譯中進行簡單但潛在有效的優(yōu)化。
考慮使用著色器集合進行并行編譯和共享。 ( DXR )當(dāng)您管理多個著色器時,著色器集合可能允許多線程編譯狀態(tài)對象,并在狀態(tài)對象之間共享編譯代碼。有關(guān)更多信息,請參閱 光線跟蹤管道狀態(tài)的并行著色器編譯 。
當(dāng)需要自動綁定點分配時,請考慮編譯器選項。 ( DXR )默認(rèn)情況下,編譯著色器庫時不使用著色器資源的自動綁定點指定。如果需要,有幾個有用的編譯器選項。首先,/auto-binding-space在給定寄存器空間中啟用自動綁定點分配。此外,默認(rèn)情況下,所有未標(biāo)記關(guān)鍵字 static 的函數(shù)都被視為庫導(dǎo)出。
使用/auto-binding-space時,任何導(dǎo)出函數(shù)訪問的資源都會消耗綁定點,而不管它們是否在最終狀態(tài)對象中使用。為了將綁定點消耗限制為真正需要的函數(shù),可以使用/exports來限制庫導(dǎo)出。
考慮AddToStateObject的增量構(gòu)建。它允許基于現(xiàn)有對象增量構(gòu)建狀態(tài)對象,這在使用多個著色器管理動態(tài)內(nèi)容時非常有用。
M 如果適用,每年管理堆棧。 使用 API 的查詢函數(shù)來確定每個著色器所需的堆棧大小,并應(yīng)用有關(guān)調(diào)用圖的應(yīng)用程序端知識來減少內(nèi)存消耗并提高性能。
一個很好的例子是拍攝二次陰影光線的昂貴反射著色器,應(yīng)用程序知道,二次陰影光線僅使用具有低堆棧要求的普通命中著色器。驅(qū)動程序無法提前知道此調(diào)用圖,因此默認(rèn)的保守堆棧大小計算會過度分配內(nèi)存。
關(guān)于作者
Juha 是一名軟件工程師,在實時圖形方面有 15 年的經(jīng)驗。他曾在各種游戲、引擎和硬件基準(zhǔn)測試中使用過尖端渲染技術(shù)。最近,他專注于 RTX 光線追蹤在游戲中的應(yīng)用。
審核編輯:郭婷
-
寄存器
+關(guān)注
關(guān)注
31文章
5295瀏覽量
119824 -
NVIDIA
+關(guān)注
關(guān)注
14文章
4856瀏覽量
102711
發(fā)布評論請先 登錄
相關(guān)推薦
評論