Search Unity

Command Buffer Blit not working on VR Singlepass Instanced?

Discussion in 'General Graphics' started by Raul_T, Apr 16, 2020.

  1. Raul_T

    Raul_T

    Joined:
    Jan 10, 2015
    Posts:
    363
    Hello, I've been working on updating some assets to work with VR SPI but I don't seem to have any luck with command buffers.

    For regular VR and non VR I've been using the typical CommandBuffer.Blit() but this doesnt seem to work with SPI? It seems that only the left eye gets rendered.
    Code (CSharp):
    1. RtDownsampler.vrUsage = UnityEngine.XR.XRSettings.eyeTextureDesc.vrUsage;
    2. RtDownsampler.Create();
    3. ...
    4. RenderTargetIdentifier ssaaCommandBufferTargetId = new RenderTargetIdentifier(RtDownsampler);
    5. ...
    6. CbDownsampler.Blit(BuiltinRenderTextureType.CameraTarget, ssaaCommandBufferTargetId);
    7. CbDownsampler.Blit(ssaaCommandBufferTargetId, BuiltinRenderTextureType.CameraTarget, MaterialCurrent, 0);
    I am using a test shader currently that should render 1 different color to each eye and is setup to support SPI as per unity docs.
    Code (CSharp):
    1. Shader "Hidden/SPI_Def"
    2. {
    3.     Properties
    4.     {
    5.         _MainTex ("Texture", 2D) = "" {}
    6.     }
    7.     SubShader {
    8.         Tags{ "RenderType" = "Opaque"  "Queue" = "Geometry+0" }
    9.         Blend [_SrcBlend] [_DstBlend]
    10.         Pass {
    11.              ZTest Always Cull Off ZWrite On
    12.             CGPROGRAM
    13.             #include "UnityCG.cginc"
    14.             //#include "Include/_SSAA_Utils.cginc"
    15.             #pragma vertex vert//_img
    16.             #pragma fragment frag
    17.             UNITY_DECLARE_SCREENSPACE_TEXTURE(_MainTex); //Insert
    18.             struct Input
    19.             {
    20.                 float4 vertex : POSITION;
    21.                 float2 uv : TEXCOORD0;
    22.  
    23.                 UNITY_VERTEX_INPUT_INSTANCE_ID //Insert
    24.             };
    25.             struct Varying
    26.             {
    27.                 float2 uv : TEXCOORD0;
    28.                 float4 vertex : SV_POSITION;
    29.  
    30.                 UNITY_VERTEX_OUTPUT_STEREO //Insert
    31.             };
    32.             Varying vert(Input input)
    33.             {
    34.                 Varying o;
    35.                 UNITY_SETUP_INSTANCE_ID(input); //Insert
    36.                 UNITY_INITIALIZE_OUTPUT(Varying, o); //Insert
    37.                 UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); //Insert
    38.  
    39.                 o.vertex = UnityObjectToClipPos(input.vertex);
    40.                 o.uv = input.uv;
    41.                 return o;
    42.             }
    43.             fixed4 frag(Varying i) : SV_Target
    44.             {
    45.                 UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
    46.                 return lerp(float4(1,0,0,1), float4(0,1,0,1), unity_StereoEyeIndex);
    47.                 //return UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, i.texcoord);
    48.             }
    49.             ENDCG
    50.         }
    51.     }
    52.     Fallback Off
    53. }
    54.  
    So, what is the best way to handle post processing with command buffers on VR single-pass instanced? Or am I missing something in my shader or command buffer?
     
    Last edited: Apr 16, 2020
  2. Raul_T

    Raul_T

    Joined:
    Jan 10, 2015
    Posts:
    363
  3. Raul_T

    Raul_T

    Joined:
    Jan 10, 2015
    Posts:
    363
    no one can tell? :(
     
  4. mikesf

    mikesf

    Unity Technologies

    Joined:
    Jul 14, 2017
    Posts:
    14
    Hi Raul, Unity's Postprocessing Stack v2 is using command buffers to work VR stereo modes. If you don't use postfx v2 and are implement your own post effects, following the shader modifications from https://docs.unity3d.com/Manual/SinglePassInstancing.html should work with your Blits.
     
  5. Raul_T

    Raul_T

    Joined:
    Jan 10, 2015
    Posts:
    363
    Thanks for the info. Seems that there is more to it than just setting up the shaders as in that doc links. However by digging more through postprocessing stack v2 source and with the help of a fellow asset store publisher I managed to get it running.

    This is how the command buffer code looks now.

    Code (CSharp):
    1. CbDownsampler.GetTemporaryRT(Shader.PropertyToID("_SSAAVRSamplerTexture"), UnityEngine.XR.XRSettings.eyeTextureDesc);
    2. RenderTargetIdentifier ssaaCommandBufferTargetId = new RenderTargetIdentifier(Shader.PropertyToID("_SSAAVRSamplerTexture"));
    3.                
    4. CbDownsampler.Blit(BuiltinRenderTextureType.CameraTarget, ssaaCommandBufferTargetId);
    5. CbDownsampler.Blit(ssaaCommandBufferTargetId, BuiltinRenderTextureType.CameraTarget, MaterialDefault);
    The important bit seems to be using the xr eye texture descriptor (which I wasn't using before because on multi pass and singlepass the rendering worked as is) when generating the render texture, and I've also switched from manually constructed render textures in original post to cb.GetTemporaryRT(..) for ease of use

    Using render textures constructed by code also seem to work, however the render target identifier has to be constructed like this for some reason (important bits are the extra parameters) so I stick with the cb.GetTemporaryRT implementation as its more cleaner and easier to understand code wise.

    Code (CSharp):
    1. RenderTargetIdentifier ssaaCommandBufferTargetId = new RenderTargetIdentifier(RtDownsampler, 0, CubemapFace.Unknown, -1);
    Maybe it would be good to include some of this information regarding construction of the RTs to be used with vr rendering in the unity docs, so the next person running into this issue wouldn't have to dig through source code of other assets and ask around other developers for 1 week to get it running :D
     
    mpeddicord, MR_Fancy_Pants and briank like this.
  6. numu

    numu

    Joined:
    Mar 3, 2014
    Posts:
    2
    Hi everyone,
    i was trying to achieve the same thing, but unfortunately i am a complete newbie, especially to the SRP.
    When I was trying your code @Raul_MadGoat i had the following 2 errors:

    Attempting to get Camera relative temporary RenderTexture (width || height <= 0) via a CommandBuffer Unlit in a Sriptable Render Pipeline.

    Trying to get RenderBuffer with invalid antiAliasing (must be at least 1)


    Would anyone maybe know how to port a Shader to VR (preferably SPI) or has any propper tutorial showing how (including the C# part), i would be very thankful! As i am slowly turning mad.
     
  7. mpeddicord

    mpeddicord

    Joined:
    Mar 17, 2013
    Posts:
    13

    Yes. For future people searching for this. This fixed the problem I was having with SPI and command buffers.
    Here's my distilled code:

    commandBuffer.GetTemporaryRT(_shaderPropertyID, UnityEngine.XR.XRSettings.eyeTextureDesc);
    commandBuffer.SetRenderTarget(_shaderPropertyID, 0, CubemapFace.Unknown, -1);