Search Unity

  1. Unity 2020.1 has been released.
    Dismiss Notice
  2. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

Command Buffer Blit not working on VR Singlepass Instanced?

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

  1. Raul_MadGoat


    Jan 10, 2015
    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;
    23.                 UNITY_VERTEX_INPUT_INSTANCE_ID //Insert
    24.             };
    25.             struct Varying
    26.             {
    27.                 float2 uv : TEXCOORD0;
    28.                 float4 vertex : SV_POSITION;
    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
    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. }
    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_MadGoat


    Jan 10, 2015
  3. Raul_MadGoat


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


    Unity Technologies

    Jul 14, 2017
    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 should work with your Blits.
  5. Raul_MadGoat


    Jan 10, 2015
    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"));
    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