Hello Vulkan(六)| 圖形渲染新技術(shù)Vulkan Command Buffers及光追
上一期技術(shù)分享中,我們講述了如何關(guān)于Vulkan的紋理繪制部分,將紋理貼圖映射到3D模型上,也介紹了Vulkan里存儲(chǔ)類型,紋理貼圖是存放在GPU的設(shè)備內(nèi)存,為了能夠快速的讀取。
本期將繼續(xù)分享關(guān)于Vulkan的關(guān)于「Command?Buffers」以及「光追Ray?Tracing」,本期也將會(huì)是我們此次教程的最后一章了,后續(xù)會(huì)再推出其他系列講解,也會(huì)加入我們虹圖產(chǎn)品在不同平臺(tái)的使用方法教程和一些有趣的使用場(chǎng)景分享。
Command?Buffers
首先我們來(lái)看下Vulkan的整體框架圖:

Vulkan通過(guò)創(chuàng)建實(shí)例Instance,建立起我們的應(yīng)用和Vulkan庫(kù)之間的橋梁,通過(guò)Instance初始化Vulkan后,我們需要在系統(tǒng)中查找并選擇一個(gè)支持我們所需功能的顯卡。實(shí)際上,我們可以選擇任意數(shù)量的顯卡并同時(shí)使用他們。而Queue隊(duì)列是用來(lái)和物理設(shè)備溝通的橋梁,而具體的溝通過(guò)程就需要?Command Buffer命令緩沖區(qū),它是若干命令的集合,我們向?Queue 提交?Command Buffer,然后才交由物理設(shè)備?GPU 進(jìn)行處理。我們不需要自己創(chuàng)建Queue,物理設(shè)備已經(jīng)有了隊(duì)列。
Command buffer用于記錄(record)GPU指令(command)。在Vulkan中,指令是通過(guò)類似于vkCmdxxx()的接口來(lái)寫入到Command buffer,驅(qū)動(dòng)會(huì)負(fù)責(zé)生成適配當(dāng)前GPU的二進(jìn)制指令內(nèi)容。

創(chuàng)建Command buffer
創(chuàng)建command buffer需先創(chuàng)建command buffer池:
Command buffer池與queue簇是一一對(duì)應(yīng)的關(guān)系,創(chuàng)建command buffer池需指定使用的queue簇類型。
創(chuàng)建完Command?buffer池后,就可以分配Command?buffer了:
Command buffer分配好之后,就可以記錄GPU指令了。vkBeginCommandBuffer()用于開(kāi)啟Command buffer的記錄狀態(tài),vkCmdxxx()用于記錄指令,比如:vkCmdSetLineWidth()、vkCmdDraw(),完成記錄后用vkEndCommandBuffer()關(guān)閉記錄狀態(tài),變成可提交狀態(tài)。
?到這兒就可以完成了開(kāi)啟Command?Buffer的過(guò)程,一張圖回顧下:

光追Ray?Tracing
最后簡(jiǎn)單給大家介紹下Vulkan里的光線追蹤Ray?Tracing應(yīng)用,這個(gè)本身其實(shí)還是比較復(fù)雜的,這里只做最簡(jiǎn)單的應(yīng)用講解。比如折射、反射都是屬于光追計(jì)算。

Ray?Tracing管線具有5個(gè)新著色器Shader種類:

創(chuàng)建光線追蹤管線需要讀取著色器數(shù)據(jù),按照光線生成,光線未命中,光線命中,可調(diào)用四個(gè)組合,將它們根據(jù)頂層加速結(jié)構(gòu)的實(shí)例,以索引代替著色器頭,構(gòu)建出著色器表的簡(jiǎn)化版本。將它傳遞給管線創(chuàng)建所需要的struct,創(chuàng)建管線。
我們來(lái)看下光線在球體上的處理方式,我們知道三維球面的方程是(x-xc)?2?+ (y-yc)?2 + (z-zc) 2 = R2?,切線的方程是(x,y,z) = (x0,y0,z0) + t*(dx,dy,dz) ,帶入(x,y,z) 到第一個(gè)方程,能夠得到1個(gè)關(guān)于t的一元二次方程,能夠接觸t1和t2兩個(gè)解。如果t1和t2兩個(gè)解都是復(fù)數(shù),則光線未觸及球面,如果t1和t2相等,則光線貼著球面沿切線方向擦過(guò),如果t1和t2不等且都為實(shí)數(shù),則光線直接觸及球面。
這就是一個(gè)簡(jiǎn)單的計(jì)算針對(duì)球體物體的光線匯聚方法。在Vulkan里,gl_WorldRayOriginNV = (x0,y0,z0),gl_HitNV = t,gl_WorldRayDirectionNV = (dx,dy,dz) 。
根據(jù)光線與物體的命中規(guī)律,才引入了上述新的著色器種類,簡(jiǎn)單講述著色器的種類:光線生成、光線未命中、最近命中、任意命中、相交命中。它們之間的數(shù)據(jù)互相傳遞,可以參見(jiàn)上述管線圖,其他的就不再做更深入的講解,代碼部分會(huì)以zip形式在后臺(tái)發(fā)放,演示了如何進(jìn)行下面的光追效果。

Vulkan教程的全部?jī)?nèi)容就結(jié)束了。我們會(huì)在后續(xù)內(nèi)容中繼續(xù)與大家分享,開(kāi)發(fā)者如何利用我們虹圖AI的產(chǎn)品進(jìn)行快速開(kāi)發(fā)以及如果做使用上的優(yōu)化等。
敬請(qǐng)期待~