Search Unity

Question Native Graphics Device D3D11 and VR - Multi-Pass Rendering Support

Discussion in 'General Graphics' started by austintsmith13, Jan 8, 2022.

  1. austintsmith13

    austintsmith13

    Joined:
    Dec 27, 2018
    Posts:
    8
    Unity-Version: 2021.1.19 and 2019.4.16

    Pipeline: Built-in using command buffers and OnPreRender event

    Dependencies:
    "com.unity.visualscripting": "1.6.1",
    "com.unity.xr.management": "4.2.1",
    "com.unity.xr.mock-hmd": "1.3.0-preview.1",
    "com.unity.xr.oculus": "1.6.1",
    "com.unity.xr.windowsmr": "2.4.1",

    Docs:
    https://docs.unity3d.com/Manual/NativePluginInterface.html
    https://docs.unity3d.com/Manual/LowLevelNativePluginRenderingExtensions.html

    Gif: https://gyazo.com/6df31febec8bf18fe9bdc4e042f10971

    Hello, I have a question with regards to using Unity's Low-Level native plug-in interface with OpenXR. I'm trying to render some polygons to my headset using a call to "IssuePluginEventWithData(IntPtr, eventId)", everything seems to work fine but every few seconds I notice a small flicker on the left eye. It looks like the right eye is being duplicated to the left. I've confirmed that the eyeIndex is correct and that the viewProjection Matrix is correct on the frame it flickers. It almost seems like Unity is copying the right eye to the left behind the scenes.

    I'm really stumped on how to get this working for VR any information or help would be appreciated.

    Is there a way to grab a internal pointer to the left and right eye RenderTextures or texture array?



    Code:

    Code (CSharp):
    1. struct ShaderData
    2. {
    3.     float localToWorldMatrix[16];
    4.     float worldToViewMatrix[16];
    5.     float leftViewToProjectionMatrix[16];
    6.     float rightViewToProjectionMatrix[16];
    7.     int eye;
    8.     float a;
    9.     float b;
    10.     float c;
    11. };
    12.  
    13. struct NativeRenderingData
    14. {
    15.      float localToWorldMatrix[16];
    16.      float worldToViewMatrix[16];
    17.      float leftViewToProjectionMatrix[16];
    18.      float rightViewToProjectionMatrix[16];
    19.      int32_t eyeIndex;
    20. };
    21.  
    22.  
    23.  
    24. void UnityRenderLogic::InitializeGraphicPipeline(ComPtr<ID3D11Device>& dev, ComPtr<ID3D11DeviceContext>& devcon)
    25. {
    26.     // This is meant to be an example so I am not too concerned with error handling.
    27.     // You may wonder how I magically know all the formats and sizes that should be used
    28.     // when creating the various pipeline state objects.  Afterall, some of these details
    29.     // are not documented.  To figure out the various state information, I made Unity render
    30.     // my model normally and then I took a RenderDoc capture and examined the input into
    31.     // each of the Graphics API calls.
    32.     unsigned int vertexByteCodeLength = sizeof(vertexShaderByteCode);
    33.  
    34.     HRESULT hr = S_OK;
    35.     hr = dev->CreateVertexShader((const void*)vertexShaderByteCode, vertexByteCodeLength, 0, vertexShader.GetAddressOf());
    36.     hr = dev->CreatePixelShader((const void*)pixelShaderByteCode, sizeof(pixelShaderByteCode), 0, pixelShader.GetAddressOf());
    37.  
    38.     devcon->VSSetShader(vertexShader.Get(), 0, 0);
    39.     devcon->PSSetShader(pixelShader.Get(), 0, 0);
    40.  
    41.     D3D11_INPUT_ELEMENT_DESC inputElementDesc[4] =
    42.     {
    43.         { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    44.         { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    45.         { "TANGENT", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    46.         { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 40, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    47.     };
    48.     unsigned int inputElementCount = sizeof(inputElementDesc) / sizeof(D3D11_INPUT_ELEMENT_DESC);
    49.  
    50.     vertexBufferStride = CalculateVertexBufferStride(inputElementDesc, inputElementCount);
    51.  
    52.     hr = dev->CreateInputLayout(inputElementDesc, inputElementCount, (const void*)vertexShaderByteCode, vertexByteCodeLength, &vertexInputLayout);
    53.  
    54.     D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
    55.     srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
    56.     srvDesc.Format = DXGI_FORMAT_BC1_UNORM;
    57.     srvDesc.Texture2D.MostDetailedMip = 0;
    58.     srvDesc.Texture2D.MipLevels = 9;
    59.     hr = dev->CreateShaderResourceView(nativeTextureResource.Get(), &srvDesc, nativeTextureResourceView.GetAddressOf());
    60.  
    61.     D3D11_SAMPLER_DESC samplerDesc = {};
    62.     samplerDesc.Filter = D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT;
    63.     samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
    64.     samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
    65.     samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
    66.     samplerDesc.MipLODBias = 0.0f;
    67.     samplerDesc.MaxAnisotropy = 1;
    68.     samplerDesc.ComparisonFunc = D3D11_COMPARISON_GREATER;
    69.     hr = dev->CreateSamplerState(&samplerDesc, samplerState.GetAddressOf());
    70.  
    71.     D3D11_BUFFER_DESC constantBufferDesc = { 0 };
    72.     constantBufferDesc.Usage = D3D11_USAGE_DEFAULT;
    73.     constantBufferDesc.ByteWidth = sizeof(ShaderData);
    74.     constantBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
    75.     hr = dev->CreateBuffer(&constantBufferDesc, nullptr, constantBuffer.GetAddressOf());
    76.  
    77.     D3D11_BUFFER_DESC constantBufferDesc2 = { 0 };
    78.     constantBufferDesc2.Usage = D3D11_USAGE_DEFAULT;
    79.     constantBufferDesc2.ByteWidth = sizeof(ShaderDataInfo);
    80.     constantBufferDesc2.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
    81.     hr = dev->CreateBuffer(&constantBufferDesc2, nullptr, cbufferInfo.GetAddressOf());
    82. }
    83.  
    84.  
    85. void UnityRenderLogic::RenderMesh(ComPtr<ID3D11Device>& dev, ComPtr<ID3D11DeviceContext>& devcon)
    86. {
    87.     NativeRenderingData nativeRenderingData = *(data);
    88.     unsigned int strides[1] = { vertexBufferStride };
    89.     unsigned int offsets[1] = { 0 };
    90.     ShaderData shaderData;
    91.     ShaderDataInfo info;
    92.     shaderData.eye = nativeRenderingData.eyeIndex;
    93.     info.eyeIndex = nativeRenderingData.eyeIndex;
    94.     //shaderData.eyeIndex = nativeRenderingData.eyeIndex;
    95.     memcpy(shaderData.localToWorldMatrix, nativeRenderingData.localToWorldMatrix, sizeof(float) * 16);
    96.     memcpy(shaderData.worldToViewMatrix, nativeRenderingData.worldToViewMatrix, sizeof(float) * 16);
    97.     memcpy(shaderData.rightViewToProjectionMatrix, nativeRenderingData.rightViewToProjectionMatrix, sizeof(float) * 16);
    98.     memcpy(shaderData.leftViewToProjectionMatrix, nativeRenderingData.leftViewToProjectionMatrix, sizeof(float) * 16);
    99.  
    100.     devcon->VSSetShader(vertexShader.Get(), 0, 0);
    101.     devcon->PSSetShader(pixelShader.Get(), 0, 0);
    102.     devcon->PSSetShaderResources(0, 1, nativeTextureResourceView.GetAddressOf());
    103.     devcon->PSSetSamplers(0, 1, samplerState.GetAddressOf());
    104.  
    105.     // Set buffers
    106.     devcon->VSSetConstantBuffers(0, 1, constantBuffer.GetAddressOf());
    107.     devcon->PSSetConstantBuffers(2, 1, cbufferInfo.GetAddressOf());
    108.     //devcon->VSSetConstantBuffers(4, 1, cbufferInfo.GetAddressOf());
    109.  
    110.     devcon->UpdateSubresource(constantBuffer.Get(), 0, 0, &shaderData, 0, 0);
    111.     devcon->UpdateSubresource(cbufferInfo.Get(), 2, 0, &info, 0, 0);
    112.  
    113.  
    114.     devcon->IASetInputLayout(vertexInputLayout.Get());
    115.     devcon->IASetIndexBuffer(nativeIndexBuffer.Get(), DXGI_FORMAT_R16_UINT, 0);
    116.     devcon->IASetVertexBuffers(0, 1, nativeVertexBuffer.GetAddressOf(), strides, offsets);
    117.     devcon->DrawIndexed(indexCount, 0, 0);
    118. }
    119.  
    120.  
     
    Last edited: Jan 8, 2022