硬件加速的PowerVR光線追蹤API(一)
本文我將對(duì)PowerVR光線追蹤團(tuán)隊(duì)創(chuàng)建的API進(jìn)行簡(jiǎn)要介紹。該API允許開(kāi)發(fā)人員訪問(wèn)Wizard 架構(gòu)的PowerVR光線追蹤硬件。我將簡(jiǎn)單概述硬件層發(fā)生的物理變化及其相比傳統(tǒng)的GPU所變化的具體內(nèi)容。隨后,我將著重討論新創(chuàng)建的供開(kāi)發(fā)人員訪問(wèn)硬件的OpenGL ES 3.1擴(kuò)展程序。
在2016年度游戲開(kāi)發(fā)者大會(huì)(GDC)上,ImaginaTIon的 idc16開(kāi)發(fā)人員會(huì)議對(duì)API進(jìn)行了討論,點(diǎn)擊此處可獲取API討論資訊。
以下內(nèi)容的前提是默認(rèn)各位讀者已經(jīng)了解光線追蹤的概念。若不了解,可以先查閱光線追蹤的相關(guān)信息。本文不會(huì)深入探討每個(gè)功能,詳細(xì)的信息將在后續(xù)的文章中進(jìn)行討論。
前一段時(shí)間,我們介紹了啟動(dòng)光線追蹤功能的四核集群PowerVR GR6500 GPU。最近,我們又展示了一些目前在GPU上運(yùn)行的光線追蹤應(yīng)用程序。
下圖是我們添加的用于加速光線追蹤的硬件功能:
圖表展示了光線追蹤新的硬件模光線數(shù)據(jù)管理光線數(shù)據(jù)管理(RDM)模塊將交叉點(diǎn)歸至統(tǒng)一著色集群(USC)中,再由集群進(jìn)行光線著色
場(chǎng)景層級(jí)生成器場(chǎng)景層級(jí)生成器(SHG)模塊即使用標(biāo)準(zhǔn)頂點(diǎn)著色器生成的世界坐標(biāo)頂點(diǎn),在光線交點(diǎn)處理器之后生成加速結(jié)構(gòu)。
相干引擎該模塊是光線追蹤裝置(RTU)的一部分,并以相同的方式緩沖了一組遍歷場(chǎng)景層級(jí)的光線且遵循類似的執(zhí)行路徑。這樣,在內(nèi)存中獲取光線數(shù)據(jù)時(shí)便可以避免緩存缺失,并由此減少帶寬和功耗。更多信息將在后續(xù)文章中詳細(xì)介紹。同時(shí),您還可以關(guān)注2014GDC論壇獲取更多相干引擎的資訊。
光線交叉處理器該模塊是RTU的一部分,可以測(cè)試SGH生成的位于主內(nèi)存的三角形光線及場(chǎng)景層級(jí)光線。
幀累加緩存該硬件模塊從USC中獲取累積指令,并使用編寫的緩存來(lái)加速某些在光線追蹤著色器中可以使用的圖像原子操作。這意味著我們可以發(fā)出只編寫指令,這些指令將異步列隊(duì)并執(zhí)行。
PowerVR GR6500 GPU在PCIe卡上進(jìn)行集成,如下圖所示,使用RTU時(shí)其峰值性能為每秒3億光線。SHG的目標(biāo)是生成加速結(jié)構(gòu),使頂點(diǎn)輸出從每秒1億動(dòng)態(tài)三角形開(kāi)始加速。
The API
光線跟蹤硬件對(duì)典型的GPU設(shè)計(jì)進(jìn)行了延伸,使之不僅僅只是單一的硬件。我們決定通過(guò)添加光線追蹤功能來(lái)擴(kuò)展OpenGL ES 3.1,以充分利用這個(gè)開(kāi)發(fā)人員較為熟知的OpenGL ES API。我們選擇使用現(xiàn)代規(guī)范,如直接狀態(tài)訪問(wèn)、無(wú)綁定等,因?yàn)轭A(yù)計(jì)這將是未來(lái)的API模式。Vulkan API的潛力不容忽視,但Vulkan仍處于待開(kāi)發(fā)中,本文只介紹OpenGL ES擴(kuò)展。
● 頂點(diǎn)處理
光線追蹤器輸入與光柵輸入是不同的。光線追蹤器處理的是世界坐標(biāo)中的對(duì)象,這是因?yàn)楣饩€追蹤器需要訪問(wèn)整個(gè)場(chǎng)景。例如,其場(chǎng)景中的對(duì)象反映的攝像機(jī)獲取的某個(gè)對(duì)象,而光柵中這卻很難處理。
正因?yàn)槿绱?,PowerVR硬件光線追蹤API處理頂點(diǎn)輸出時(shí)是在世界坐標(biāo)而非光柵的剪輯空間中。這意味著我們將要以不同的幀率運(yùn)行各層的頂點(diǎn)至光柵中——在光柵中,攝像機(jī)通常從幀到幀移動(dòng)。即便不是,大多數(shù)游戲平臺(tái)也將重新渲染場(chǎng)景,因?yàn)閭鬏斶^(guò)程中某些信息發(fā)生了改變。
這不同于光線追蹤器。我們從攝像機(jī)運(yùn)動(dòng)中解耦,在應(yīng)用程序啟動(dòng)時(shí)運(yùn)行頂點(diǎn)著色器,隨后,如果場(chǎng)景中沒(méi)有任何對(duì)象在世界坐標(biāo)中發(fā)生移動(dòng),則無(wú)需再次運(yùn)行頂點(diǎn)著色器。當(dāng)然,當(dāng)攝像機(jī)移動(dòng)時(shí),仍然需要在每一幀進(jìn)行光線遍歷,但為場(chǎng)景靜態(tài)部分生成的場(chǎng)景層級(jí)則無(wú)需如此。
預(yù)期OpenGL ES的變量及其他特性運(yùn)行如下:
layout(std140, binding=0) uniform UboPerObjecTIn {highp mat4 worldFromModel;highp mat4 worldFromModelIT;} UboPerObject[2];
out gl_PerVertex {vec4 gl_PosiTIon;float gl_PointSize;};out PerVertexData {vec3 vertexNormal;};void main() {gl_PosiTIon = UboPerObject[gl_BuildIDIMG].worldFromModel * vec4(inVertex, 1.0); // Output in world spacevertexNormal = (UboPerObject[gl_BuildIDIMG].worldFromModelIT * vec4(inNormal, 0.0)).xyz
(gl_BuildIDIMG explained below)
然而,由于世界坐標(biāo)中的頂點(diǎn)處理與光柵頂點(diǎn)處理不同,因此我們需要不同的API來(lái)進(jìn)行頂點(diǎn)處理……
● 場(chǎng)景構(gòu)造