英偉達詳述面向Vulkan的實時光線追蹤技術(shù)
英偉達新推出的圖靈顯卡首次在消費者GPU中實現(xiàn)了實時光線追蹤。自此,社區(qū)開始討論DirectX 12中的光線追蹤。然而,一系列的開發(fā)者都希望能夠通過Vulkan(Khronos Group支持的low-level API)實現(xiàn)這一點,從而帶來更為開放的策略。Vulkan令開發(fā)者能夠針對眾多不同的平臺,包括Windows和Linux,從而允許更廣泛地分發(fā)3D加速的應用程序。英偉達的411.63驅(qū)動程序現(xiàn)在啟用了一個實驗性的Vulkan擴展,它通過Vulkan API公開(expose)了英偉達用于實時光線追蹤的RTX技術(shù)。
這個名為VK_NVX_raytracing的擴展屬于開發(fā)者預覽版。擴展程序面向希望熟悉API概念并開始測試相關(guān)功能的開發(fā)者。正如“NVX”前綴所示,這個API尚未最終確定,并且有可能在最終版本發(fā)布之前進行一定的更改。
日前,英偉達開發(fā)技術(shù)工程師Nuno Subtil向我們詳細介紹了面向Vulkan的實時光線追蹤技術(shù),以下是映維網(wǎng)的具體整理:
1. 光線追蹤API的演變
在英偉達,GPU加速的光線追蹤成為研究課題已有超過10年的時間。
GPU逐漸發(fā)展成為功能強大的光柵化機器。為架構(gòu)添加可編程性可以創(chuàng)建基于光柵化的復雜算法。這種可編程性令GPU能夠處理更復雜的計算問題,并最終促成了英偉達GPU計算平臺CUDA的推出。英偉達的GPU加速光線追蹤研究專注于通過CUDA編程模型公開(expose)光線追蹤。
英偉達努力的首個可見結(jié)果之一是OptiX,一種用于加速光線投射應用的通用SDK。英偉達在2010年SIGGRAPH大會發(fā)布的 論文 細介紹了針對OptiX的API設計研究,并包含了今天用于實時光線追蹤的關(guān)鍵創(chuàng)建模塊。圖1是論文的摘錄。
圖1:早期論文的摘錄,其詳細介紹了關(guān)于OptiX API的研究
英偉達圍繞OptiX所做的努力,特別是為了令其變得越來越高效和可擴展而進行的研發(fā)工作,最終在實時光線追蹤(RTX)達到了頂峰。RTX是算法,計算機圖形和GPU架構(gòu)10多年研究的產(chǎn)物,它使得實時光線追蹤應用程序能夠在英偉達的GPU上運行。RTX利用了英偉達所有的研究工作和硬件改進,是創(chuàng)建實時光線追蹤API的基礎(chǔ)。
2. 為Vulkan帶來光線追蹤
英偉達Vulkan光線追蹤擴展(簡稱“VKRay”)背后的關(guān)鍵設計原則利用了他們之前關(guān)于光線追蹤API的研究。VKRay建立在經(jīng)過驗證和現(xiàn)場測試的API概念之上,其足夠靈活,可以支持各種各樣的應用程序,并同時仍然提供了運行應用程序利用未來研究的抽象層。
Vulkan是一個跨硬件API,而英偉達已經(jīng)確保VKRay實現(xiàn)跨硬件支持。整個API可以在現(xiàn)有的Vulkan計算功能之上實現(xiàn)。英偉達同時在全力確保這個擴展符合現(xiàn)有的Vulkan API概念。內(nèi)存分配,資源處理和著色器語言/字節(jié)碼的處理方式與核心Vulkan API規(guī)定的方式相同。
3. 光線追蹤管道
通過光線追蹤管道的數(shù)據(jù)流不同于傳統(tǒng)的光柵管道。圖2比較了兩個管道。
一般認為灰色塊不可編程。隨著底層實現(xiàn)的成熟,這一切都隨著時間的推移而不斷發(fā)展和改進。白色塊代表完全可編程的階段。鉆石形階段是調(diào)度工作發(fā)生的地方。
與光柵化不同,光線追蹤所執(zhí)行的工作“單位(光線)”數(shù)量取決于先前工作單位的結(jié)果。這意味著新的工作能夠通過可編程階段產(chǎn)生,并直接饋送回管道。
英偉達光線追蹤API包含四個關(guān)鍵組件:
加速結(jié)構(gòu)
用于光線追蹤的新shader domain
Shader Binding Table
光線追蹤管道對象
4. 加速結(jié)構(gòu)
傳統(tǒng)的光柵化涉及獨立處理每一個幾何圖元。相比之下,光線追蹤針對所有場景基元測試每條光線,而這樣做的成本十分昂貴。
大多數(shù)光線追蹤器是實現(xiàn)某種形式的加速結(jié)構(gòu),從而快速拒絕基元,英偉達的API將其公開(expose)為“一等公民”。加速結(jié)構(gòu)(acceleration structure)是一個對象,它為場景中的基元保存幾何信息,以這樣的方式進行預處理,從而能夠流暢地拒絕潛在的光線-基元交叉點。這是可以進行光線追蹤的API基元。
加速結(jié)構(gòu)(acceleration structure,AS)作為不透明的,實現(xiàn)定義的數(shù)據(jù)結(jié)構(gòu)公開(expose),不依賴于任何基礎(chǔ)算法或剔除方法。它建模為兩級結(jié)構(gòu):bottom-level AS節(jié)點包含幾何數(shù)據(jù),而top-level AS節(jié)點則包含對底層節(jié)點的引用列表,以及相關(guān)的變換和著色信息。圖3概述了結(jié)構(gòu)之間的關(guān)系。
可以使用VkBuffer對象中的現(xiàn)有幾何創(chuàng)建加速結(jié)構(gòu)。創(chuàng)建AS的過程分為兩步:首先創(chuàng)建bottom-level節(jié)點,然后生成top-level節(jié)點。
所有創(chuàng)建/更新操作都發(fā)生在GPU上,如圖4所示。在這個情形下,“創(chuàng)建”意味著從零開始創(chuàng)建新對象(如在初始設置場景時),而“更新”則意味著我們通過新數(shù)據(jù)來更新現(xiàn)有對象(如當角色在現(xiàn)有場景中移動時)。盡管創(chuàng)建和更新操作都旨在以非常高效的方式進行,但兩者都存在一定的限制,尤其是更新。
在API Level,我們定義一個新的Vulkan對象類型:VkAccelerationStructureNVX。對象的每個實例都在top-level AS節(jié)點或bottom-level封裝。我們同時定義了一個新的資源描述符類型VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NVX,主要用于將AS對象綁定至著色器。
對象創(chuàng)建和消除遵循一般的Vulkan范例:通過調(diào)用vkCreateAccelerationStructureNVX創(chuàng)建加速結(jié)構(gòu)節(jié)點,這會返回不透明句柄。然后,這個句柄可與vkGetAccelerationStructureMemoryRequirementsNVX一起使用,以獲取有關(guān)該加速結(jié)構(gòu)需要的內(nèi)存類型和內(nèi)存量信息。接下來,可以使用vkAllocateMemory分配內(nèi)存,并通過調(diào)用vkBindAccelerationStructureMemoryNVX將其綁定至該對象。
4.1 管理加速結(jié)構(gòu)內(nèi)存
加速結(jié)構(gòu)創(chuàng)建/更新操作需要一定的臨時“暫存(scratch memory)”??梢酝ㄟ^調(diào)用vkGetAccelerationStructureScratchMemoryRequirementsNVX來查詢這一內(nèi)存。
暫存(scratch memory)以常規(guī)VkBuffer對象的形式出現(xiàn),根據(jù)實現(xiàn)返回的內(nèi)存要求進行分配。這將作為創(chuàng)建/更新命令的參數(shù)進行傳入。
AS對象所需的內(nèi)存量取決于傳入的特定幾何數(shù)據(jù)。因此,vkGetAccelerationStructureMemoryRequirementsNVX返回的數(shù)據(jù)是特定對象所需內(nèi)存量的上限。創(chuàng)建結(jié)構(gòu)后,可以使用vkCmdWriteAccelerationStructurePropertiesNVX命令,讓GPU將給定AS對象的壓縮大小寫入Vulkan查詢對象,而這可以在CPU進行讀取。然后,可以使用它來分配具有所需內(nèi)存量的單獨AS對象,并且可以使用vkCmdCopyAccelerationStructureNVX來將原始AS對象壓縮為新的AS對象。
4.2 加速結(jié)構(gòu)創(chuàng)建/更新執(zhí)行
AS創(chuàng)建/更新命令在GPU上執(zhí)行,可以提交給圖形或計算隊列。API允許實現(xiàn)并行化連續(xù)的創(chuàng)建/更新命令,從而最大化GPU利用率。
在創(chuàng)建/更新命令之間重用暫存緩沖區(qū)時應小心,因為它們的執(zhí)行可能會重疊。為確保正確,我們需要barrier同時,使用新的存儲器訪問flag位VK_AC CES S_ACCELERATION_STRUCTURE_R EA D_BIT_NVX和VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_NVX:應該在暫存緩沖區(qū)上的緩沖存儲器barrier中使用它們,然后再將相同的緩沖區(qū)用于另一個操作,并用在全局存儲器barrier上,從而確保AS創(chuàng)建/更新在AS對象用于光線追蹤之前完成更新。
為了最大化重疊,建議為多個創(chuàng)建/更新操作分配足夠的臨時緩沖區(qū)內(nèi)存,并為每個連續(xù)操作分配不同的內(nèi)存區(qū)域。分配多少內(nèi)存取決于應用程序?qū)铀俳Y(jié)構(gòu)創(chuàng)建性能的敏感程度,以及使用的加速結(jié)構(gòu)量。
5. 光線追蹤shader domain
為了向Vulkan API公開(expose)光線追蹤功能,我們定義一組新的shader domain,以及用于著色器間通信的基元。圖5說明了流程。
5.1 光線生成著色器(Ray Generation Shader)
光線生成著色器開始所有的光線追蹤工作。光線生成著色器在線程的2D網(wǎng)格上運行,非常類似于計算著色器,并且是將追蹤進入場景光線的起點。它同時負責將光線追蹤算法的最終輸出寫入至內(nèi)存。
5.2 相交著色器(Intersection Shader)
相交著色器實現(xiàn)任意光線-基元相交算法。對于支持應用程序?qū)⒐饩€與不具備內(nèi)置支持的不同類型基元(如球體)相交,它們是否有用。三角形基元具備內(nèi)置支持,不需要相交著色器。
5.3 擊中著色器(Hit Shader)
當發(fā)現(xiàn)光線-基元相交時,將調(diào)用擊中著色器。它們負責計算在交叉點處發(fā)生的交互(如圖形應用程序的光線-材質(zhì)交互),并且可以根據(jù)需要產(chǎn)生新的光線。
有兩種擊中著色器:對于光線以任意順序與場景基元的所有相交,調(diào)用任意擊中著色器(any-hit shader),除了計算著色數(shù)據(jù)之外,它同時可以拒絕相交。最接近擊中著色器(Closest-hit Shader)僅在沿光線的最接近相交點上調(diào)用。
5.4 未擊中著色器(Miss Shader)
當給定光線沒有相交時,調(diào)用未擊中著色器Inter-shader communication
5.5 著色器間通信
在執(zhí)行光線追蹤調(diào)用期間,各個著色器階段需要在彼此之間傳遞數(shù)據(jù)。相交著色器需要輸出相交數(shù)據(jù),擊中著色器需要消耗相交數(shù)據(jù)并修改一定的任意結(jié)果數(shù)據(jù),而光線生成著色器則需要使用最終結(jié)果數(shù)據(jù)并將其輸出到內(nèi)存。
光線有效負載是一種任意的,由應用程序定義的數(shù)據(jù)結(jié)構(gòu),用于存儲沿光線路徑累積的信息。它由啟動光線查詢操作的著色器(通常是光線生成著色器)初始化,并且可以由擊中著色器讀取和修改。它通常用于輸出沿光線路徑累積的材質(zhì)屬性,然后由光線生成著色器將其寫入內(nèi)存。
光線屬性包含從相交著色器傳回至擊中著色器的一組值,包含應用程序需要從相交點測試發(fā)出的任何數(shù)據(jù)。它們封裝在一個由應用程序定義的結(jié)構(gòu)中,由相交著色器編寫,并由該交集點調(diào)用的擊中著色器讀取。對于內(nèi)置的光線-三角形相交著色器,光線屬性是包含沿三角形相交點的重心坐標的vec2。
5.6 GLSL語言映射
相對來說,在Vulkan中啟用光線追蹤只需要更少的著色語言改動。
API定義了五個用于創(chuàng)建GLSL著色器的新著色器階段:用于光線生成著色器的rgen,用于相交著色器的rint,用于最接近擊中著色器的rchit,用于任意擊中著色器的rahit,以及用于未擊中著色器的rmiss。
目前存在數(shù)個新的內(nèi)置變量,具體取決于著色器階段,它們包含有關(guān)各種參數(shù)的信息。這包括當前的光線生成線程ID,基元和實例ID值,當前光線原點,世界和對象空間中的方向,以及沿光線處理的當前相交的T值等等。
為加速結(jié)構(gòu)資源綁定定義一個新的不透明資源類型:accelerationStructureNVX。加速結(jié)構(gòu)以與其他資源類型相同的方式綁定至著色器管道。注意,可以在同一著色器中使用多個加速結(jié)構(gòu),從而在著色器中對不同的幾何數(shù)據(jù)集進行分層遍歷。
我們同時為用戶定義的類型定義了一些新的存儲限定符:rayPayloadNVX,rayPayloadInNVX和hitAttributeNVX,它們定義了要使用的光線有效負載(并定義了哪個著色器階段擁有給定有效負載的存儲)和擊中屬性類型。增加了一個新的布局限定符shaderRecordNVX,它定義了一個綁定至Shader Binding Table的SSBO。
最后,增加了一系列新的內(nèi)置函數(shù)。這包括將光線發(fā)射至場景的traceNVX();丟棄一個給定相交點的ignoreIntersectionNVX();以及在擊中點終止處理光線的terminateRayNVX()。
5.6.1 光線有效負載結(jié)構(gòu)匹配
光線追蹤著色器API允許將任何應用程序定義的結(jié)構(gòu)用作光線有效負載。這個有效負載是在可以生成光線的著色器階段進行定義,并通過引用修改它的擊中著色器階段傳入。
因為GLSL不具有類型多態(tài)性,所以我們不能將traceNVX()調(diào)用定義為類型多態(tài)。這意味著我們不能將任意類型作為參數(shù)傳遞。針對這個問題,我們設計了一個基于位置布局限定符來匹配數(shù)據(jù)類型的解決方案。
每個光線有效負載結(jié)構(gòu)都使用rayPayloadNVX限定符,以及一個將其與整數(shù)值相關(guān)聯(lián)的位置布局限定符進行定義。這個整數(shù)值基本上成為有效負載變量的數(shù)字標識符,然后傳入traceNVX()調(diào)用以代替對實際變量的引用。擊中著色器需要使用rayPayloadInNVX限定符定義與變量相同的數(shù)據(jù)類型,從而令光線追蹤基礎(chǔ)結(jié)構(gòu)能夠?qū)⒆兞恳暈閷斎氲挠行ж撦d數(shù)據(jù)的引用。
為了說明這個機制,下面是一個簡單光線生成著色器的代碼片段:
你可以看到primaryPayload是我們的光線有效負載。它在定義中賦予了1的位置索引,而且該索引是作為traceNVX()的最后一個參數(shù)傳入。
對于相應的最接近擊中著色器,它看起來可能是這樣:
可以通過rayPayloadInNVX關(guān)鍵字定義相同的有效負載結(jié)構(gòu)。著色器中可能只存在一個rayPayloadInNVX變量(并且只有擊中著色器和未擊中著色器可以定義它們),因此不需要布局限定符。請注意,匹配的有效負載類型不存在靜態(tài)驗證,不匹配的類型將導致不確定的行為。另外,traceNVX()調(diào)用中的有效負載值必須是編譯期間的立即值。
更多關(guān)于GLSL語言映射的信息,請訪問 這個頁面
6. Shader Binding Table
API介紹的最后一個新概念是Shader Binding Table(SBT)。這是一個VkBuffer,包含一組統(tǒng)一大小的記錄,由后面緊跟著應用程序定義數(shù)據(jù)的著色器句柄組成。著色器句柄確定哪個著色器為給定SBT記錄運行,同時記錄中的應用程序定義數(shù)據(jù)可作為SSBO提供給著色器。
每個SBT實例都有固定的記錄大小。在每條記錄中,一系列的索引規(guī)則確定光線追蹤基礎(chǔ)結(jié)構(gòu)將如何獲取下一個著色器要執(zhí)行的句柄和SSBO數(shù)據(jù)。
SBT中的SSBO數(shù)據(jù)旨在指定每個著色器將使用的資源(紋理,統(tǒng)一緩沖區(qū)等)。預期的使用模式是,所有潛在的可訪問資源通過描述符集綁定至管道。然后,SBT將包含數(shù)組中的索引,并指定應該為給定的著色器集使用哪些特定資源。也就是說,從著色器的角度來看,SBT只是“數(shù)據(jù)”,它也可以包含其他類型的信息。
更多關(guān)于Shader Binding Table的信息,請訪問 這個頁面 。
7. 光線追蹤管道
所需的最后一塊拼圖是光線追蹤管道狀態(tài)對象。光線追蹤管道僅包含一個(可能非常大)光線生成著色器,相交著色器,擊中著色器和未擊中著色器的集合,以及一定的光線追蹤特定參數(shù)(如最大光線遞歸深度)。
由于單個光線追蹤PSO可以包含許多著色器,因此編譯可能非常耗時。通過添加一個接口來允許應用程序控制各個著色器的編譯,我們可以降低這方面的成本。在PSO創(chuàng)建時,VK_PIPELINE_CREATE_DEFER_COMPILE_BIT_NVX這個新flag可以指示驅(qū)動程序避免立即編譯著色器。然后,應用程序必須為每個著色器調(diào)用vkCompileDeferredNVX,以便觸發(fā)編譯工作。這可以跨線程并行化,從而最大限度地縮短編譯時間。
在創(chuàng)建后,可以使用包含新管道綁定點VK_PIPELINE_BIND_POINT_RAYTRACING_NVX的標準Vulkan調(diào)用來將光線追蹤管道對象綁定到圖形或計算隊列。
更多關(guān)于光線追蹤管道創(chuàng)建的信息,請訪問 這個頁面 。
8. 啟動工作
在創(chuàng)建加速結(jié)構(gòu)和Shader Binding Table,以及創(chuàng)建和綁定光線追蹤PSO后,現(xiàn)在是時候開始追蹤光線了。
單個Vulkan命令啟動光線追蹤工作:vkCmdTraceRaysNVX。這個命令的參數(shù)指定2D線程網(wǎng)格尺寸,以及要使用的包含SBT的VkBuffer,以及該SBT中用于各種數(shù)據(jù)元素的偏移量(光線生成著色器句柄和SSBO數(shù)據(jù)偏移量,初始擊中著色器句柄和SSBO數(shù)據(jù)偏移量,以及未擊中著色器句柄和相應SSBO數(shù)據(jù)的偏移量)。
更多關(guān)于vkCmdTraceRaysNVX的信息,請訪問 這個頁面 。
9. 總結(jié)
英偉達已經(jīng)將VK_NVX_raytracing作為開發(fā)者預覽版發(fā)布,支持開發(fā)者熟悉Vulkan中基于RTX的光線追蹤。這可以與LunarG的最新Vulkan SDK一起使用,它支持英偉達所有的圖靈擴展,允許你通過Vulkan開發(fā)光線追蹤的應用程序。
英偉達表示,他們相信Vulkan為這個功能提供了良好的基礎(chǔ)。API內(nèi)置的可擴展性意味著我們可以利用大多數(shù)現(xiàn)有的機制和基礎(chǔ)架構(gòu),可實現(xiàn)與現(xiàn)有光柵化功能的無縫集成。
文章來源:映維網(wǎng) 如轉(zhuǎn)載請標明出處
原文鏈接 : https://yivian.com/news/52567.html
未經(jīng)授權(quán),禁止轉(zhuǎn)載,違者必將追究法律責任。