加入收藏 手機版 手機微信 網站地圖 +微博關注
按品牌查找
全部資訊

英偉達詳述面向Vulkan的實時光線追蹤技術

來源:https://yivian.com

英偉達新推出的圖靈顯卡首次在消費者GPU中實現了實時光線追蹤。自此,社區開始討論DirectX 12中的光線追蹤。然而,一系列的開發者都希望能夠通過Vulkan(Khronos Group支持的low-level API)實現這一點,從而帶來更為開放的策略。Vulkan令開發者能夠針對眾多不同的平臺,包括Windows和Linux,從而允許更廣泛地分發3D加速的應用程序。英偉達的411.63驅動程序現在啟用了一個實驗性的Vulkan擴展,它通過Vulkan API公開(expose)了英偉達用于實時光線追蹤的RTX技術。


這個名為VK_NVX_raytracing的擴展屬于開發者預覽版。擴展程序面向希望熟悉API概念并開始測試相關功能的開發者。正如“NVX”前綴所示,這個API尚未最終確定,并且有可能在最終版本發布之前進行一定的更改。


英偉達詳述面向Vulkan的實時光線追蹤技術


日前,英偉達開發技術工程師Nuno Subtil向我們詳細介紹了面向Vulkan的實時光線追蹤技術,以下是映維網的具體整理:


1. 光線追蹤API的演變


在英偉達,GPU加速的光線追蹤成為研究課題已有超過10年的時間。


GPU逐漸發展成為功能強大的光柵化機器。為架構添加可編程性可以創建基于光柵化的復雜算法。這種可編程性令GPU能夠處理更復雜的計算問題,并最終促成了英偉達GPU計算平臺CUDA的推出。英偉達的GPU加速光線追蹤研究專注于通過CUDA編程模型公開(expose)光線追蹤。


英偉達努力的首個可見結果之一是OptiX,一種用于加速光線投射應用的通用SDK。英偉達在2010年SIGGRAPH大會發布的 論文 細介紹了針對OptiX的API設計研究,并包含了今天用于實時光線追蹤的關鍵創建模塊。圖1是論文的摘錄。


圖1:早期論文的摘錄,其詳細介紹了關于OptiX API的研究


英偉達圍繞OptiX所做的努力,特別是為了令其變得越來越高效和可擴展而進行的研發工作,最終在實時光線追蹤(RTX)達到了頂峰。RTX是算法,計算機圖形和GPU架構10多年研究的產物,它使得實時光線追蹤應用程序能夠在英偉達的GPU上運行。RTX利用了英偉達所有的研究工作和硬件改進,是創建實時光線追蹤API的基礎。


2. 為Vulkan帶來光線追蹤


英偉達Vulkan光線追蹤擴展(簡稱“VKRay”)背后的關鍵設計原則利用了他們之前關于光線追蹤API的研究。VKRay建立在經過驗證和現場測試的API概念之上,其足夠靈活,可以支持各種各樣的應用程序,并同時仍然提供了運行應用程序利用未來研究的抽象層。


Vulkan是一個跨硬件API,而英偉達已經確保VKRay實現跨硬件支持。整個API可以在現有的Vulkan計算功能之上實現。英偉達同時在全力確保這個擴展符合現有的Vulkan API概念。內存分配,資源處理和著色器語言/字節碼的處理方式與核心Vulkan API規定的方式相同。


3. 光線追蹤管道


通過光線追蹤管道的數據流不同于傳統的光柵管道。圖2比較了兩個管道。


一般認為灰色塊不可編程。隨著底層實現的成熟,這一切都隨著時間的推移而不斷發展和改進。白色塊代表完全可編程的階段。鉆石形階段是調度工作發生的地方。


與光柵化不同,光線追蹤所執行的工作“單位(光線)”數量取決于先前工作單位的結果。這意味著新的工作能夠通過可編程階段產生,并直接饋送回管道。


英偉達光線追蹤API包含四個關鍵組件:


加速結構


用于光線追蹤的新shader domain


Shader Binding Table


光線追蹤管道對象


4. 加速結構


傳統的光柵化涉及獨立處理每一個幾何圖元。相比之下,光線追蹤針對所有場景基元測試每條光線,而這樣做的成本十分昂貴。


大多數光線追蹤器是實現某種形式的加速結構,從而快速拒絕基元,英偉達的API將其公開(expose)為“一等公民”。加速結構(acceleration structure)是一個對象,它為場景中的基元保存幾何信息,以這樣的方式進行預處理,從而能夠流暢地拒絕潛在的光線-基元交叉點。這是可以進行光線追蹤的API基元。


加速結構(acceleration structure,AS)作為不透明的,實現定義的數據結構公開(expose),不依賴于任何基礎算法或剔除方法。它建模為兩級結構:bottom-level AS節點包含幾何數據,而top-level AS節點則包含對底層節點的引用列表,以及相關的變換和著色信息。圖3概述了結構之間的關系。


英偉達詳述面向Vulkan的實時光線追蹤技術


可以使用VkBuffer對象中的現有幾何創建加速結構。創建AS的過程分為兩步:首先創建bottom-level節點,然后生成top-level節點。


所有創建/更新操作都發生在GPU上,如圖4所示。在這個情形下,“創建”意味著從零開始創建新對象(如在初始設置場景時),而“更新”則意味著我們通過新數據來更新現有對象(如當角色在現有場景中移動時)。盡管創建和更新操作都旨在以非常高效的方式進行,但兩者都存在一定的限制,尤其是更新。


在API Level,我們定義一個新的Vulkan對象類型:VkAccelerationStructureNVX。對象的每個實例都在top-level AS節點或bottom-level封裝。我們同時定義了一個新的資源描述符類型VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NVX,主要用于將AS對象綁定至著色器。


對象創建和消除遵循一般的Vulkan范例:通過調用vkCreateAccelerationStructureNVX創建加速結構節點,這會返回不透明句柄。然后,這個句柄可與vkGetAccelerationStructureMemoryRequirementsNVX一起使用,以獲取有關該加速結構需要的內存類型和內存量信息。接下來,可以使用vkAllocateMemory分配內存,并通過調用vkBindAccelerationStructureMemoryNVX將其綁定至該對象。


4.1 管理加速結構內存


加速結構創建/更新操作需要一定的臨時“暫存(scratch memory)”。可以通過調用vkGetAccelerationStructureScratchMemoryRequirementsNVX來查詢這一內存。


暫存(scratch memory)以常規VkBuffer對象的形式出現,根據實現返回的內存要求進行分配。這將作為創建/更新命令的參數進行傳入。


AS對象所需的內存量取決于傳入的特定幾何數據。因此,vkGetAccelerationStructureMemoryRequirementsNVX返回的數據是特定對象所需內存量的上限。創建結構后,可以使用vkCmdWriteAccelerationStructurePropertiesNVX命令,讓GPU將給定AS對象的壓縮大小寫入Vulkan查詢對象,而這可以在CPU進行讀取。然后,可以使用它來分配具有所需內存量的單獨AS對象,并且可以使用vkCmdCopyAccelerationStructureNVX來將原始AS對象壓縮為新的AS對象。


4.2 加速結構創建/更新執行


AS創建/更新命令在GPU上執行,可以提交給圖形或計算隊列。API允許實現并行化連續的創建/更新命令,從而最大化GPU利用率。


在創建/更新命令之間重用暫存緩沖區時應小心,因為它們的執行可能會重疊。為確保正確,我們需要barrier同時,使用新的存儲器訪問flag位VK_AC CES S_ACCELERATION_STRUCTURE_R EA D_BIT_NVX和VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_NVX:應該在暫存緩沖區上的緩沖存儲器barrier中使用它們,然后再將相同的緩沖區用于另一個操作,并用在全局存儲器barrier上,從而確保AS創建/更新在AS對象用于光線追蹤之前完成更新。


為了最大化重疊,建議為多個創建/更新操作分配足夠的臨時緩沖區內存,并為每個連續操作分配不同的內存區域。分配多少內存取決于應用程序對加速結構創建性能的敏感程度,以及使用的加速結構量。


5. 光線追蹤shader domain


為了向Vulkan API公開(expose)光線追蹤功能,我們定義一組新的shader domain,以及用于著色器間通信的基元。圖5說明了流程。


5.1 光線生成著色器(Ray Generation Shader)


光線生成著色器開始所有的光線追蹤工作。光線生成著色器在線程的2D網格上運行,非常類似于計算著色器,并且是將追蹤進入場景光線的起點。它同時負責將光線追蹤算法的最終輸出寫入至內存。


5.2 相交著色器(Intersection Shader)


相交著色器實現任意光線-基元相交算法。對于支持應用程序將光線與不具備內置支持的不同類型基元(如球體)相交,它們是否有用。三角形基元具備內置支持,不需要相交著色器。


5.3 擊中著色器(Hit Shader)


當發現光線-基元相交時,將調用擊中著色器。它們負責計算在交叉點處發生的交互(如圖形應用程序的光線-材質交互),并且可以根據需要產生新的光線。


有兩種擊中著色器:對于光線以任意順序與場景基元的所有相交,調用任意擊中著色器(any-hit shader),除了計算著色數據之外,它同時可以拒絕相交。最接近擊中著色器(Closest-hit Shader)僅在沿光線的最接近相交點上調用。


5.4 未擊中著色器(Miss Shader)


當給定光線沒有相交時,調用未擊中著色器Inter-shader communication


5.5 著色器間通信


在執行光線追蹤調用期間,各個著色器階段需要在彼此之間傳遞數據。相交著色器需要輸出相交數據,擊中著色器需要消耗相交數據并修改一定的任意結果數據,而光線生成著色器則需要使用最終結果數據并將其輸出到內存。


光線有效負載是一種任意的,由應用程序定義的數據結構,用于存儲沿光線路徑累積的信息。它由啟動光線查詢操作的著色器(通常是光線生成著色器)初始化,并且可以由擊中著色器讀取和修改。它通常用于輸出沿光線路徑累積的材質屬性,然后由光線生成著色器將其寫入內存。


光線屬性包含從相交著色器傳回至擊中著色器的一組值,包含應用程序需要從相交點測試發出的任何數據。它們封裝在一個由應用程序定義的結構中,由相交著色器編寫,并由該交集點調用的擊中著色器讀取。對于內置的光線-三角形相交著色器,光線屬性是包含沿三角形相交點的重心坐標的vec2。


5.6 GLSL語言映射


相對來說,在Vulkan中啟用光線追蹤只需要更少的著色語言改動。


API定義了五個用于創建GLSL著色器的新著色器階段:用于光線生成著色器的rgen,用于相交著色器的rint,用于最接近擊中著色器的rchit,用于任意擊中著色器的rahit,以及用于未擊中著色器的rmiss。


目前存在數個新的內置變量,具體取決于著色器階段,它們包含有關各種參數的信息。這包括當前的光線生成線程ID,基元和實例ID值,當前光線原點,世界和對象空間中的方向,以及沿光線處理的當前相交的T值等等。


為加速結構資源綁定定義一個新的不透明資源類型:accelerationStructureNVX。加速結構以與其他資源類型相同的方式綁定至著色器管道。注意,可以在同一著色器中使用多個加速結構,從而在著色器中對不同的幾何數據集進行分層遍歷。


我們同時為用戶定義的類型定義了一些新的存儲限定符:rayPayloadNVX,rayPayloadInNVX和hitAttributeNVX,它們定義了要使用的光線有效負載(并定義了哪個著色器階段擁有給定有效負載的存儲)和擊中屬性類型。增加了一個新的布局限定符shaderRecordNVX,它定義了一個綁定至Shader Binding Table的SSBO。


最后,增加了一系列新的內置函數。這包括將光線發射至場景的traceNVX();丟棄一個給定相交點的ignoreIntersectionNVX();以及在擊中點終止處理光線的terminateRayNVX()。


5.6.1 光線有效負載結構匹配


光線追蹤著色器API允許將任何應用程序定義的結構用作光線有效負載。這個有效負載是在可以生成光線的著色器階段進行定義,并通過引用修改它的擊中著色器階段傳入。


因為GLSL不具有類型多態性,所以我們不能將traceNVX()調用定義為類型多態。這意味著我們不能將任意類型作為參數傳遞。針對這個問題,我們設計了一個基于位置布局限定符來匹配數據類型的解決方案。


每個光線有效負載結構都使用rayPayloadNVX限定符,以及一個將其與整數值相關聯的位置布局限定符進行定義。這個整數值基本上成為有效負載變量的數字標識符,然后傳入traceNVX()調用以代替對實際變量的引用。擊中著色器需要使用rayPayloadInNVX限定符定義與變量相同的數據類型,從而令光線追蹤基礎結構能夠將變量視為對輸入的有效負載數據的引用。


為了說明這個機制,下面是一個簡單光線生成著色器的代碼片段:


你可以看到primaryPayload是我們的光線有效負載。它在定義中賦予了1的位置索引,而且該索引是作為traceNVX()的最后一個參數傳入。


對于相應的最接近擊中著色器,它看起來可能是這樣:


可以通過rayPayloadInNVX關鍵字定義相同的有效負載結構。著色器中可能只存在一個rayPayloadInNVX變量(并且只有擊中著色器和未擊中著色器可以定義它們),因此不需要布局限定符。請注意,匹配的有效負載類型不存在靜態驗證,不匹配的類型將導致不確定的行為。另外,traceNVX()調用中的有效負載值必須是編譯期間的立即值。


更多關于GLSL語言映射的信息,請訪問 這個頁面


6. Shader Binding Table


API介紹的最后一個新概念是Shader Binding Table(SBT)。這是一個VkBuffer,包含一組統一大小的記錄,由后面緊跟著應用程序定義數據的著色器句柄組成。著色器句柄確定哪個著色器為給定SBT記錄運行,同時記錄中的應用程序定義數據可作為SSBO提供給著色器。


每個SBT實例都有固定的記錄大小。在每條記錄中,一系列的索引規則確定光線追蹤基礎結構將如何獲取下一個著色器要執行的句柄和SSBO數據。


SBT中的SSBO數據旨在指定每個著色器將使用的資源(紋理,統一緩沖區等)。預期的使用模式是,所有潛在的可訪問資源通過描述符集綁定至管道。然后,SBT將包含數組中的索引,并指定應該為給定的著色器集使用哪些特定資源。也就是說,從著色器的角度來看,SBT只是“數據”,它也可以包含其他類型的信息。


更多關于Shader Binding Table的信息,請訪問 這個頁面 。


7. 光線追蹤管道


所需的最后一塊拼圖是光線追蹤管道狀態對象。光線追蹤管道僅包含一個(可能非常大)光線生成著色器,相交著色器,擊中著色器和未擊中著色器的集合,以及一定的光線追蹤特定參數(如最大光線遞歸深度)。


由于單個光線追蹤PSO可以包含許多著色器,因此編譯可能非常耗時。通過添加一個接口來允許應用程序控制各個著色器的編譯,我們可以降低這方面的成本。在PSO創建時,VK_PIPELINE_CREATE_DEFER_COMPILE_BIT_NVX這個新flag可以指示驅動程序避免立即編譯著色器。然后,應用程序必須為每個著色器調用vkCompileDeferredNVX,以便觸發編譯工作。這可以跨線程并行化,從而最大限度地縮短編譯時間。


在創建后,可以使用包含新管道綁定點VK_PIPELINE_BIND_POINT_RAYTRACING_NVX的標準Vulkan調用來將光線追蹤管道對象綁定到圖形或計算隊列。


更多關于光線追蹤管道創建的信息,請訪問 這個頁面 。


8. 啟動工作


在創建加速結構和Shader Binding Table,以及創建和綁定光線追蹤PSO后,現在是時候開始追蹤光線了。


單個Vulkan命令啟動光線追蹤工作:vkCmdTraceRaysNVX。這個命令的參數指定2D線程網格尺寸,以及要使用的包含SBT的VkBuffer,以及該SBT中用于各種數據元素的偏移量(光線生成著色器句柄和SSBO數據偏移量,初始擊中著色器句柄和SSBO數據偏移量,以及未擊中著色器句柄和相應SSBO數據的偏移量)。


更多關于vkCmdTraceRaysNVX的信息,請訪問 這個頁面 。


9. 總結


英偉達已經將VK_NVX_raytracing作為開發者預覽版發布,支持開發者熟悉Vulkan中基于RTX的光線追蹤。這可以與LunarG的最新Vulkan SDK一起使用,它支持英偉達所有的圖靈擴展,允許你通過Vulkan開發光線追蹤的應用程序。


英偉達表示,他們相信Vulkan為這個功能提供了良好的基礎。API內置的可擴展性意味著我們可以利用大多數現有的機制和基礎架構,可實現與現有光柵化功能的無縫集成。


文章來源:映維網 如轉載請標明出處

原文鏈接 : https://yivian.com/news/52567.html

版權聲明:VR之家(www.vavwgp.live)所有原創文章獨家稿件
未經授權,禁止轉載,違者必將追究法律責任。

相關文章

文章點評

相關閱讀

本周熱門文章

推薦閱讀

吉林十一选五走势图图表