NVIDIA SMP(同時(shí)多投影)輔助NVAPI驅(qū)動程序擴(kuò)展是一種將多分辨率著色和鏡頭匹配著色集成到VR應(yīng)用程序中的簡單方法。它將大量的狀態(tài)設(shè)置和API調(diào)用封裝到簡化的API中,從而大大降低了將NVIDIAVRWorks集成到應(yīng)用程序中的復(fù)雜性。具體來說,SMP Assist驅(qū)動程序處理創(chuàng)建和管理快速幾何著色器,視口狀態(tài)和剪刀狀態(tài),而不是在應(yīng)用程序中手動管理這些狀態(tài)。
簡化多分辨率和鏡頭匹配陰影
在VR頭戴式耳機(jī)中,用戶通常通過引起枕形失真的透鏡來觀看顯示器。虛擬現(xiàn)實(shí)應(yīng)用渲染桶形失真圖像以反轉(zhuǎn)鏡頭本身的枕形失真,從而在頭戴式耳機(jī)中形成幾何上正確的場景。桶形失真圖像的周邊區(qū)域顯著收縮。NVIDIA VRWorks SDK包含多分辨率著色和鏡頭匹配著色等功能,允許應(yīng)用程序開發(fā)人員利用桶形失真圖像的非線性優(yōu)勢,減少渲染幀時(shí)所需的像素著色工作負(fù)載,同時(shí)保持視覺質(zhì)量。
如圖1所示,多分辨率著色(MRS)使用多個(gè)視口與剪刀矩形組合,以創(chuàng)建多分辨率投影。每個(gè)視口內(nèi)的分辨率保持不變,而分辨率在不同的視口中變化。它們的排列方式可以使視口一起呈現(xiàn)場景的一個(gè)復(fù)雜的無縫投影。中央視口通常具有比周邊視口更高的分辨率,從而更好地匹配桶失真圖像并節(jié)省不必要的像素著色工作量。
圖1:多分辨率陰影
鏡頭匹配陰影(LMS)使用多個(gè)視口結(jié)合剪形矩形和線性變換來創(chuàng)建鏡頭匹配投影,如圖2所示。在鏡頭匹配投影中,三角形頂點(diǎn)在被下列光柵化之前進(jìn)行變換轉(zhuǎn)型:
w'= w + Ax + By
從概念上講,這會在透視投影之前縮放剪輯空間中頂點(diǎn)的“w”坐標(biāo)。頂點(diǎn)的剪輯空間“w”坐標(biāo)可以作為“x”和“y”坐標(biāo)的函數(shù)來偏移,這導(dǎo)致頂點(diǎn)被拉向視口的中心,其“x”和“y” “坐標(biāo)是。仔細(xì)選擇幀的四個(gè)象限中的每一個(gè)的系數(shù)A和B產(chǎn)生類似桶形失真的變形圖像。
圖2:鏡頭匹配陰影
這些功能中的每一個(gè)都需要應(yīng)用程序根據(jù)所需的效果計(jì)算多個(gè)視口和剪刀。此外,對于透鏡匹配著色,應(yīng)用程序必須指定系數(shù)(上面公式中的A和B)。應(yīng)用程序必須確保通過在圖形管道中設(shè)置快速幾何著色器(Fast Geometry Shader,F(xiàn)astGS)來正確渲染場景。該著色器通過計(jì)算視口掩碼來剔除三角形并將其廣播到正確的視口。
全新的NVIDIA SMP Assist API實(shí)現(xiàn)了驅(qū)動程序中的所有這些步驟,并為應(yīng)用程序提供了簡化的API,使MRS和LMS更容易集成到應(yīng)用程序或游戲引擎中。
NVIDIA SMP Assist API
當(dāng)前可用于DirectX11應(yīng)用程序的SMP Assist API為應(yīng)用程序提供了一個(gè)接口,用于指定VR應(yīng)用程序使用的MRS / LMS配置。基于此配置,驅(qū)動程序在內(nèi)部執(zhí)行以下任務(wù):
-
計(jì)算視口和剪刀。
-
創(chuàng)建一個(gè)FastGS,它將基元選取并投影到正確的視口中,以匹配需要在投影和未投影的坐標(biāo)空間之間轉(zhuǎn)換的著色器所需的常量緩沖區(qū)數(shù)據(jù)。
-
計(jì)算鏡頭匹配陰影系數(shù)(如果適用)。
-
驅(qū)動程序計(jì)算并維護(hù)各種渲染模式的上述狀態(tài) - 單聲道,立體聲,實(shí)例化立體聲。(立體和立體渲染模式的計(jì)算假定應(yīng)用程序在并排配置中渲染,即在單個(gè)渲染目標(biāo)上渲染的兩個(gè)眼圖)。
應(yīng)用程序可以根據(jù)實(shí)現(xiàn)的易用性與靈活性的折衷來選擇協(xié)助級別
-
完整:應(yīng)用程序通過從預(yù)先配置的列表中選擇一個(gè)配置來指定配置,該列表針對當(dāng)前可用的VR HMD進(jìn)行了微調(diào)
-
部分:應(yīng)用程序通過提供單個(gè)配置參數(shù)來指定配置,這對于支持新的或預(yù)生產(chǎn)VR頭戴式顯示器可能有用。
-
最小化:應(yīng)用程序提供視口和剪刀,API處理相同的設(shè)置,而應(yīng)用程序負(fù)責(zé)設(shè)置FastGS,GS常量緩沖區(qū)和LMS系數(shù)。
使用SMP Assist非常簡單。只要MRS / LMS投影配置發(fā)生變化,應(yīng)用程序就會調(diào)用API,最多每幀應(yīng)該發(fā)生一次。然后,應(yīng)用程序?yàn)樾枰獞?yīng)用MRS / LMS投影的框架部分啟用SMP Assist。在隨后的繪制調(diào)用中,驅(qū)動程序選擇并設(shè)置上面1,2和3中描述的狀態(tài)的適當(dāng)版本,從而覆蓋應(yīng)用程序設(shè)置的視口和剪刀。禁用SMP Assist時(shí),驅(qū)動程序會將其覆蓋到原始狀態(tài)的任何狀態(tài)恢復(fù)為原始狀態(tài),并且以下繪制調(diào)用將使用通過常規(guī)DirectX API設(shè)置的狀態(tài)。
該API還提供了獲取內(nèi)部計(jì)算數(shù)據(jù)的功能。這些數(shù)據(jù)可用于放大通過MRS / LMS渲染的圖像。
圖3突出顯示了當(dāng)前由應(yīng)用程序執(zhí)行并由SMP Assist API內(nèi)部化的任務(wù):
圖3. SMP Assist API圖
使用SMP Assist API
初始化SMP輔助
通過查詢所需SMP功能(MRS / LMS)的平臺支持,獲取指向SMP Assist接口的指針以及使用此接口指針指定所需的配置(rendertarget大小等),可以初始化SMP Assist API。
NV_QUERY_SMP_ASSIST_SUPPORT_PARAMSQuerySMPAssist={0};QuerySMPAssist.version=NV_QUERY_SMP_ASSIST_SUPPORT_PARAMS_VER;QuerySMPAssist.eSMPAssistLevel=NV_SMP_ASSIST_LEVEL_FULL;QuerySMPAssist.eSMPAssistType=NV_SMP_ASSIST_LMS;NvStatus=NvAPI_D3D_QuerySMPAssistSupport(pD3DDevice,&QuerySMPAssist);if(NvStatus!=NVAPI_OK||QuerySMPAssist.bSMPAssistSupported==false){ //查詢失敗}NV_SMP_ASSIST_INITIALIZE_PARAMSinitParams={0};ID3DNvSMPAssist*pD3DNvSMPAssist=NULL;initParams.version=NV_SMP_ASSIST_INITIALIZE_PARAMS_VER;initParams.eSMPAssistType=NV_SMP_ASSIST_LMS;initParams.eSMPAssistLevel=NV_SMP_ASSIST_LEVEL_FULL;initParams.flags=NV_SMP_ASSIST_FLAGS_DEFAULT;initParams.ppD3DNvSMPAssist=&pD3DNvSMPAssist;NvStatus=NvAPI_D3D_InitializeSMPAssist(pD3DDevice,&initParams);if(NvStatus!=NVAPI_OK||pD3DNvSMPAssist==NULL){ //NvAPI_D3D_InitializeSMPAssist失敗}NV_SMP_ASSIST_SETUP_PARAMSsetupParams={0};setupParams.version=NV_SMP_ASSIST_SETUP_PARAMS_VER;setupParams.eLMSConfig=NV_LMS_CONFIG_OCULUSRIFT_CV1_BALANCED;setupParams.resolutionScale=1.0f;setupParams.boundingBox.TopLeftX=0;setupParams.boundingBox.TopLeftY=0;setupParams.boundingBox.Width=rt_width;setupParams.boundingBox.Height=rt_height;setupParams.boundingBox.MinDepth=0.0;setupParams.boundingBox.MaxDepth=1.0;NvStatus=pD3DNvSMPAssist->SetupProjections(pD3DDevice,&setupParams);
返回的SMP Assist接口對象NvAPI_D3D_InitializeSMPAssist是一個(gè)單例。對NvAPI_D3D_InitializeSMPAssist的任何后續(xù)調(diào)用都會返回一個(gè)指向同一對象的指針。該對象由驅(qū)動程序響應(yīng)NvAPI_D3D_InitializeSMPAssist應(yīng)用程序的第一個(gè)調(diào)用而創(chuàng)建。驅(qū)動程序在應(yīng)用程序退出時(shí)銷毀對象。應(yīng)用程序不應(yīng)試圖破壞對象。
用SMP輔助渲染
應(yīng)用程序應(yīng)該指出在渲染幀時(shí)是否要為即將來臨的繪圖調(diào)用啟用/禁用SMP功能。因此,API設(shè)置適用于所有后續(xù)繪制調(diào)用的渲染狀態(tài)(視口,剪刀,F(xiàn)astGS,LMS系數(shù))
NV_SMP_ASSIST_ENABLE_PARAMSenableParams={NV_SMP_ASSIST_ENABLE_PARAMS_VER,NV_SMP_ASSIST_EYE_INDEX_MONO};NV_SMP_ASSIST_DISABLE_PARAMSdisableParams={NV_SMP_ASSIST_DISABLE_PARAMS_VER};而(…){ ... NvStatus=pD3DNvSMPAssist->啟用(pD3DContext,&enableParams); 畫();//在啟用后,投影應(yīng)用于所有繪圖調(diào)用 畫(); ... NvStatus=pD3DNvSMPAssist->Disable(pD3DContext,&disableParams); 畫();//投影不適用于Disable后的任何繪圖調(diào)用}
獲取SMP輔助數(shù)據(jù)
應(yīng)用程序調(diào)用ID3DNvSMPAssist::GetConstants在初始化期間讀取由API計(jì)算的數(shù)據(jù)。這包括用于指定VR渲染模式的視口/剪刀,F(xiàn)astGS常量緩沖區(qū)數(shù)據(jù),投影大小和可用于展平通過的其他常數(shù)緩沖區(qū)數(shù)據(jù)。
NV_SMP_ASSIST_GET_CONSTANTSsmpAssistConstants={0};D3D11_VIEWPORT視口[NV_SMP_ASSIST_MAX_VIEWPORTS];D3D11_RECT剪刀[NV_SMP_ASSIST_MAX_VIEWPORTS];memset(視口,0,NV_SMP_ASSIST_MAX_VIEWPORTS*sizeof(D3D11_VIEWPORT));memset(剪刀,0,NV_SMP_ASSIST_MAX_VIEWPORTS*sizeof(D3D11_RECT));NV_SMP_ASSIST_FASTGSCBDATAfastGSCBData={0};NV_SMP_ASSIST_REMAPCBDATAremapCBData={0};smpAssistConstants.version=NV_SMP_ASSIST_GET_CONSTANTS_VER;smpAssistConstants.pViewports=viewports;smpAssistConstants.pScissors=剪刀;smpAssistConstants.eEyeIndex=NV_SMP_ASSIST_EYE_INDEX_MONO;smpAssistConstants.pFastGSCBData=&fastGSCBData;smpAssistConstants.pRemapCBData=&remapCBData;NvStatus=pD3DNvSMPAssist->GetConstants(&smpAssistConstants);
實(shí)例化立體聲注意事項(xiàng)
提供眼睛指數(shù)
由驅(qū)動程序設(shè)置的FastGS需要知道當(dāng)應(yīng)用程序以實(shí)例化立體模式呈現(xiàn)時(shí),當(dāng)前著色器實(shí)例是渲染左眼還是右眼。
VR應(yīng)用程序必須確保世界空間著色器(Vertex / Hull / Domain)正確地將當(dāng)前眼圖(eyeIndex)傳遞給FastGS。應(yīng)用程序還應(yīng)該通過NvAPI_D3D11_CreateVertexShaderEx/創(chuàng)建最后的世界空間著色器(頂點(diǎn)/域),NvAPI_D3D11_CreateDomainShaderEx并指示眼睛索引變量是NvAPI_Packed_Eye_Index自定義語義。SMP Assist要求眼圖索引變量是一個(gè)標(biāo)量。
NvAPI_D3D11_CREATE_VERTEX_SHADER_EXCreateVSExArgs={0};CreateVSExArgs.version=NVAPI_D3D11_CREATEVERTEXSHADEREX_VERSION;CreateVSExArgs.UseWithFastGS=true;CreateVSExArgs.UseSpecificShaderExt=false;CreateVSExArgs.NumCustomSemantics=1;CreateVSExArgs.pCustomSemantics=(NV_CUSTOM_SEMANTIC*)malloc((sizeof(NV_CUSTOM_SEMANTIC))*CreateVSExArgs.NumCustomSemantics);memset(CreateVSExArgs.pCustomSemantics,0,(sizeof(NV_CUSTOM_SEMANTIC))*CreateVSExArgs.NumCustomSemantics);CreateVSExArgs.pCustomSemantics[0].version=NV_CUSTOM_SEMANTIC_VERSION;CreateVSExArgs.pCustomSemantics[0].NVCustomSemanticType=NV_PACKED_EYE_INDEX_SEMANTIC;strcpy_s(&(CreateVSExArgs.pCustomSemantics[0].NVCustomSemanticNameString[0]),NVAPI_LONG_STRING_MAX,“EYE_INDEX”);NvStatus=NvAPI_D3D11_CreateVertexShaderEx(pD3DDevice,pVSBlob->GetBufferPointer(),pVSBlob->GetBufferSize(),NULL,&CreateVSExArgs,&pVertexShaderInstancedStereo);
不要忘記著色器HLSL文件:
結(jié)構(gòu)VS_OUTPUT{ ... uinteyeIndex:EYE_INDEX;};
如果您希望FastGS將當(dāng)前實(shí)例渲染到左眼,請將eyeIndex的LSB設(shè)置為0。否則,F(xiàn)astGS將渲染到右眼。
避免著色器修改
實(shí)例立體渲染涉及根據(jù)在當(dāng)前著色器實(shí)例中呈現(xiàn)的眼睛視圖來移位頂點(diǎn)。但是,LMS要求應(yīng)用程序不執(zhí)行這種頂點(diǎn)移動。這意味著應(yīng)用程序可能必須修改頂點(diǎn)著色器,以確保在LMS情況下頂點(diǎn)不會移位。
SMP Assist提供了一個(gè)API,UpdateInstancedStereoData可用于撤銷應(yīng)用程序著色器代碼執(zhí)行的頂點(diǎn)移位。該應(yīng)用程序不需要修改上述LMS特定要求的著色器代碼。應(yīng)用程序只需提供正確的系數(shù)給這個(gè)API。這些系數(shù)將用于實(shí)現(xiàn)該公式以逆轉(zhuǎn)由應(yīng)用程序的著色器代碼完成的頂點(diǎn)移動。
考慮以下頂點(diǎn)著色器片段:
VSOutput主(在頂點(diǎn)i_vtx中,在uint中i_instance:SV_InstanceID,...){... #ifSTEREO_MODE==STEREO_MODE_INSTANCED uinteyeIndex=i_instance&1; output.eyeIndex=eyeIndex; output.posClip=mul(pos,eyeIndex==0?g_matWorldToClip:g_matWorldToClipR); //將幾何圖形移動到正確的眼睛 output.posClip.x*=0.5; floateyeOffsetScale=eyeIndex==0?-0.5:0.5; output.posClip.x+=eyeOffsetScale*output.posClip.w; ...}
在上面的著色器中完成逆轉(zhuǎn)頂點(diǎn)移動的公式是:
output.posClip.x = (output.posClip.x - eyeOffsetScale * output.posClip.w ) / 0.5 =2.0 * output.posClip.x + (-eyeOffsetScale * 2.0) * output.posClip.w
左眼:
output.posClip.x = 2.0 * output.posClip.x + 1.0 * output.posClip.w = dotproduct( output.posClip, float4(2.0, 0.0, 0.0, 1.0))
右眼:
output.posClip.x = 2.0 * output.posClip.x - 1.0 * output.posClip.w = dotproduct(output.posClip, float4(2.0, 0.0, 0.0, -1.0))
左/右眼視圖x分量的方程可以看作頂點(diǎn)位置和大小為4的向量之間的點(diǎn)積。
由SMP Assist實(shí)施的等式每個(gè)眼睛視圖有5個(gè)值:具有頂點(diǎn)位置的點(diǎn)積的4個(gè)系數(shù)和添加到點(diǎn)積的結(jié)果的第5個(gè)值。
NV_SMP_ASSIST_UPDATE_INSTANCEDSTEREO_DATA_PARAMSinstancedStereoParams={0};instancedStereoParams.version=NV_SMP_ASSIST_UPDATE_INSTANCEDSTEREO_DATA_PARAMS_VER;instancedStereoParams.eSMPAssistType=NV_SMP_ASSIST_LMS;//左眼:pos.x=dotproduct(pos,leftCoeffs)+leftConstinstancedStereoParams.leftCoeffs[0]=2.0f;instancedStereoParams.leftCoeffs[1]=0.0f;instancedStereoParams.leftCoeffs[2]=0.0f;instancedStereoParams.leftCoeffs[3]=1.0f;instancedStereoParams.leftConst=0.0f;//右眼:pos.x=dotproduct(pos,rightCoeffs)+rightConstinstancedStereoParams.rightCoeffs[0]=2.0f;instancedStereoParams.rightCoeffs[1]=0.0f;instancedStereoParams.rightCoeffs[2]=0.0f;instancedStereoParams.rightCoeffs[3]=-1.0f;instancedStereoParams.rightConst=0.0f;status=m_activeSMPAssist->UpdateInstancedStereoData(m_pDevice,&instancedStereoParams);
應(yīng)用程序應(yīng)UpdateInstancedStereoData在SMP Assist成功初始化后調(diào)用
更容易的VR編程
NVIDIA驅(qū)動程序內(nèi)置的SMP Assist API使開發(fā)人員能夠更輕松地實(shí)現(xiàn)多分辨率著色和鏡頭匹配著色,這些關(guān)鍵功能使虛擬現(xiàn)實(shí)更易于使用和用戶友好。如果您目前不是NVIDIA開發(fā)人員并想查看VRWorks,注冊非常簡單 - 只需點(diǎn)擊NVIDIA開發(fā)者主頁上方的“加入”按鈕即可。SMP Assist API需要NVIDIA顯卡驅(qū)動程序版本397.31及更高版本。最新的VRWorks Graphics SDK 2.6版本包含一個(gè)示例應(yīng)用程序和編程指南,如果您已經(jīng)擁有NVIDIA開發(fā)人員帳戶,則可以通過SMP Assist進(jìn)行演示。
-
NVIDIA
+關(guān)注
關(guān)注
14文章
5309瀏覽量
106452 -
vr
+關(guān)注
關(guān)注
34文章
9675瀏覽量
152748
發(fā)布評論請先 登錄
如何通過 WICED API 讀取固件中編程的 BD 地址?
NVIDIA Omniverse Kit 107的安裝部署步驟

EE-311:面向Blackfin處理器的VisualDSP閃存編程器API

SMO與SMP的區(qū)別與聯(lián)系
使用NVIDIA Omniverse豐富汽車營銷資產(chǎn)
NVIDIA DOCA 2.9版本的亮點(diǎn)解析

DS320PR810-SMP-EVM用戶指南

NVIDIA推出適用于網(wǎng)絡(luò)安全的NIM Blueprint

VR施工安全科普:VR腳手架拆除傷害模擬體驗(yàn)系統(tǒng)#VR施工安全體驗(yàn)館#VR腳手架拆除傷害


NVIDIA NIM助力企業(yè)高效部署生成式AI模型
MSP430? USB HID Windows API編程人員指南

評論