碧居士>今日>正文

研發實戰:如何在Oculus Mobile VR平台進行Vulkan開發

2019-09-24 01:09:12 映維網 分享

來源:映維網 作者 顔昳華

移動VR從一開始就将OpenGL ES作為圖形API,但現在大多數引擎都開始轉向Vulkan和DX12等API,因為它們為開發者提供了更大的靈活性和更低的渲染負載。Oculus日前介紹了GL和Vulkan在開發VR遊戲功能方面的差異。需要注意的是,本文深入介紹了與圖形相關的細節,讀者需要掌握GL和Vulkan的基本知識。下面是映維網的具體整理:

由于Adreno圖形驅動和Oculus運行時方面的改動,下面介紹的大多數功能都需要新發布的Build 7.0版本。

1. 多重采樣抗鋸齒(Multi-sampling Anti-aliasing;MSAA)

與PC顯卡不同,移動芯片集的MSAA是由Tiler執行MASS操作,然後當Tile完成時進行解析(将所有子樣本平均到最終像素),再将其結果存儲到主存儲器。由于從Tile内存到一般内存的帶寬是非MSAA,這允許我們以接近與非MSAA相同的速度運行MSAA幀緩沖器。這對VR非常重要,因為每個眼睛的像素非常低,會産生明顯的邊緣鋸齒。

對于GLES,這是通過使用MSAA幀緩沖區将其渲染到非MSAA紋理來完成。MSAA幀緩沖區使用以下函數進行初始化:glFramebufferTextureMultisampleMultiviewOVR

盡管有效,但由于其隐式性質,這引起了一系列的問題,例如“我不認為我的系統支持MSAA,我的紋理隻是RGBA8888,我如何啟用MSAA”。

在Vulkan中,由于一切都為顯式。每個子通道由包含pColorAttachments,pDepthStencilAttachment和pResolveAttachments的vkSubpassDescription結構定義。一個優秀的Vulkan應用程序應該通過附着4x MSAA緩沖區來設置MSAA,并将其用于顔色/深度附件中的顔色和深度,以及pResolveAttachment中的非MSAA顔色緩沖區。應用程序同時應該将pColorAttachments和pDepthStencilAttachments storeOperations設置為VK_ATTACHMENT_STORE_OP_DONT_CARE。這将告訴驅動:“我以後不會要求這種顔色或深度,請不要将它們存儲在Tile内存中并丢棄它們”。

加分項是,MSAA顔色和深度緩沖區應該設置為瞬态,并且系統會慢吞吞地分配它們的内存,因為所述緩沖區甚至沒有内存(唯一的是pResolveAttachment中的顔色解析附件)。下面是一個優秀的管道狀态示例:

使用這一路徑(通過renderpass/subpass系統進行MSAA處理)而非vkCmdResolveImage路徑非常重要。vkCmdResolveImage路徑是一個以PC為中心的API,它不會利用Tiler在存儲期間解析的能力,所以通過vkCmdResolveImage命令執行MSAA的引擎會将4x MSAA數據存儲在内存中,再次從内存加載到Tiler ,然後将非MSAA解析回内存。這很容易就會給GPU添加3ms。

2. 多視圖(Multiviw)

每次提交時,Multiview這個擴展允許GPU驅動程序在紋理數組的N個不同的切片(slice)執行N次繪制調用。它在VR中通過單次繪制調用來在2-deep紋理陣列繪制左眼和右眼。Vulkan通過VK_KHR_Multiview擴展提供支持。它需要顔色,深度和解析圖像為2D Array而非2D,并且需要将VkRenderPassMultiviewCreateInfo結構添加到要通過Multiview執行的渲染通道。它(在UE4.23進行了測試)支持多個子通道。renderdoc管道狀态圖片(與上面相同)展示了具有2個視圖的多視圖捕獲(一個用于左眼,一個用于右眼)。

VkRenderPassMultiviewCreateInfo有一個pViewMasks參數,其要求對多視圖的視圖數進行按位掩碼。對于viewMask[0]值為0b11,雙視圖系統要求bit0和bit1為真。

我們的運行時本身支持紋理數組作為時間扭曲合成的輸入紋理。開發者應該使用VRAPI_TEXTURE_TYPE_2D_ARRAY枚舉創建紋理,而非渲染到多視圖緩沖區,然後再手動将它們到非多視圖圖像并發送到VRAPI(計算要求非常高)。

3. 固定注視點渲染(Fixed Foveated Rendering;FFR)

從開發者的角度來看,由于兩個FFR API之間存在較大的架構差異,所以GL和Vulkan之間的FFR非常不同。從概念上講,FFR是一種應用于幀緩沖區的渲染設置,因為它會修改GPU計算幀的方式,同時不會以任何方式影響紋理(無論發生什麼,顔色和深度紋理中的所有紋素都會被填充)。

實際上,來自QCOM的原始FFR擴展應該通過glFramebufferFoveationConfigQCOM函數應用于幀緩沖區,而老實說它應該存在于API中。但對于Oculus Go,我們希望在無需深入的引擎/應用改動的情形下引入這項功能。更重要的是,我們希望運行時控制應用的注視點設置,這樣我們就不需要每位開發者和引擎來控制FFR設置,并且整個平台上都會具有同類設置。所以,我們要求QCOM在顔色紋理中存儲FFR元數據(由我們控制,因為運行時分配紋理而非幀緩沖區),因此誕生了glTextureFoveationParametersQCOM。從開發者的角度來看,這個實現在很大程度上是隐藏在運行時中。開發者請求FFR級别(關閉/低/中/高),而我們自動為他們配置更低的級别。

聲明:本站部分資源來源于網絡,版權歸原作者或者來源機構所有,如作者或來源機構不同意本站轉載采用,請通知我們,我們将第一時間删除内容。本站刊載文章出于傳遞更多信息之目的,所刊文章觀點僅代表作者本人觀點,并不意味着本站贊同作者觀點或證實其描述,其原創性及對文章内容的真實性、完整性、及時性本站亦不作任何保證或承諾,請讀者僅作參考。
編輯: