Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Question Custom render target shows different result between left eye and right eye in AVP

Discussion in 'VR' started by Dragon_Baby, Mar 14, 2024.

  1. Dragon_Baby

    Dragon_Baby

    Joined:
    Apr 19, 2020
    Posts:
    7
    I’m trying to add a simple custom renderer feature in urp, get the camera color target, and mix it in a forward lit shader.It works if using _CameraOpaqueTexture in shader, but if using my custom render target _GrabBlurTexture, the result is different between eyes, it seems that the uv is not auto scale and offset when Blit the render target.
    Platform: Unity 2022.3.20f1, Apple VisionOS XR plugin 1.0.3, XCode 15.2
    My renderer feature and render pass:
    Code (CSharp):
    1. public class FrostedGlassRenderFeature : ScriptableRendererFeature
    2. {
    3.     [System.Serializable]
    4.     public class Settings
    5.     {
    6.         public RenderPassEvent renderEvent = RenderPassEvent.BeforeRenderingTransparents;
    7.         public Material blurMat;
    8.     }
    9.     public Settings settings = new Settings();
    10.  
    11.     FrostedGlassRenderPass m_ScriptablePass;
    12.     public override void Create()
    13.     {
    14.         m_ScriptablePass = new FrostedGlassRenderPass(settings);
    15.     }
    16.  
    17.     public override void SetupRenderPasses(ScriptableRenderer renderer,
    18.                                         in RenderingData renderingData)
    19.     {
    20.         if (renderingData.cameraData.cameraType == CameraType.Game)
    21.         {
    22.             m_ScriptablePass.ConfigureInput(ScriptableRenderPassInput.Color);
    23.             //m_ScriptablePass.SetTarget(renderer, renderer.cameraColorTargetHandle);
    24.         }
    25.     }
    26.     public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
    27.     {
    28.  
    29.         m_ScriptablePass.ConfigureInput(ScriptableRenderPassInput.Color);
    30.         if (renderingData.cameraData.cameraType == CameraType.Game)
    31.         {
    32.             renderer.EnqueuePass(m_ScriptablePass);
    33.         }
    34.     }
    35. }
    36.  
    37. public class FrostedGlassRenderPass : ScriptableRenderPass
    38. {
    39.     CommandBuffer cmd;
    40.     string m_ProfilerTag;//cmd name
    41.     Material m_blurMat;
    42.     RTHandle source;
    43.     RTHandle rth_tempTex;
    44.     RenderTextureDescriptor m_Desc;
    45.  
    46.     public FrostedGlassRenderPass(FrostedGlassRenderFeature.Settings param)
    47.     {
    48.         m_ProfilerTag = "FrostedGalss";
    49.         this.renderPassEvent = param.renderEvent;
    50.         m_blurMat = param.blurMat;
    51.     }
    52.     public void SetTarget(ScriptableRenderer renderer, RTHandle colorHandle)
    53.     {
    54.         rth_tempTex = colorHandle;
    55.     }
    56.  
    57.     public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
    58.     {
    59.         var renderer = renderingData.cameraData.renderer;
    60.         source = renderer.cameraColorTargetHandle;
    61.         RenderTextureDescriptor opaqueDesc = renderingData.cameraData.cameraTargetDescriptor;
    62.         opaqueDesc.depthBufferBits = 0;
    63.         //opaqueDesc.msaaSamples = 1;
    64.         opaqueDesc.vrUsage = VRTextureUsage.DeviceSpecific;
    65.         m_Desc = opaqueDesc;
    66.    
    67.         RenderingUtils.ReAllocateIfNeeded(ref rth_tempTex, opaqueDesc, FilterMode.Bilinear, TextureWrapMode.Clamp, name: "_TempTex");  
    68.     }
    69.  
    70.     public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
    71.     {
    72.         CommandBuffer cmd = CommandBufferPool.Get();
    73.         using (new ProfilingScope(cmd, new ProfilingSampler(m_ProfilerTag)))
    74.         {
    75.             Blitter.BlitCameraTexture(cmd, source, rth_tempTex,m_blurMat, 0);
    76.             cmd.SetGlobalTexture("_GrabBlurTexture", (RenderTargetIdentifier)rth_tempTex);
    77.         }
    78.         //---------------------------------------------
    79.         context.ExecuteCommandBuffer(cmd);
    80.         cmd.Clear();
    81.         CommandBufferPool.Release(cmd);
    82.     }
    83.    
    84.     public override void OnCameraCleanup(CommandBuffer cmd) { }
    85.     public override void FrameCleanup(CommandBuffer cmd) { }
    86.     public void Dispose()
    87.     {
    88.         rth_tempTex?.Release();
    89.         rth_Blur01?.Release();
    90.         rth_Blur02?.Release();
    91.     }
    92. }
    Blit Shader:
    Code (CSharp):
    1. Shader "FX/SeparableGlassBlur_v2" {
    2.     // Properties {}
    3.     Subshader {
    4.         Tags { "RenderType"="Opaque" "RenderPipeline"="UniversalPipeline" }
    5.         Pass {
    6.             Name "CopyColor"
    7.             ZTest Always
    8.             Cull Off
    9.             ZWrite Off
    10.             HLSLPROGRAM
    11.             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
    12.             // Blit.hlsl 提供 vertex shader (Vert), input structure (Attributes) and output strucutre (Varyings)
    13.             #include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl"
    14.             #pragma vertex myVert
    15.             #pragma fragment myFrag
    16.             struct v2f {
    17.                 float4 positionCS : SV_POSITION;//POSITION;
    18.                 float2 texcoord : TEXCOORD0;
    19.                 UNITY_VERTEX_OUTPUT_STEREO //Insert to support Single-Pass Instanced VR
    20.             };
    21.  
    22.             v2f myVert (Attributes input) {
    23.                 v2f output;
    24.                  
    25.                 UNITY_SETUP_INSTANCE_ID(input);
    26.                 UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
    27.  
    28.             #if SHADER_API_GLES
    29.                 float4 pos = input.positionOS;
    30.                 float2 uv  = input.uv;
    31.             #else
    32.                 float4 pos = GetFullScreenTriangleVertexPosition(input.vertexID);
    33.                 float2 uv  = GetFullScreenTriangleTexCoord(input.vertexID);
    34.             #endif
    35.  
    36.                 output.positionCS = pos;
    37.                 output.texcoord   = uv * _BlitScaleBias.xy + _BlitScaleBias.zw;
    38.                 return output;
    39.             }
    40.             half4 myFrag (v2f i) : SV_Target {//COLOR
    41.                 UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);//Insert to support Single-Pass Instanced VR
    42.                 half4 color = float4 (0,0,0,0);
    43.                 color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_PointClamp, i.texcoord);
    44.                 return color;
    45.             }
    46.             ENDHLSL
    47.         }
    48.     }
    49. }
    Forward Lit Shader:
    Code (CSharp):
    1. Shader "FX/Glass/Stained BumpDistort (no grab) v2" {
    2.     Properties {
    3.         _BumpAmt  ("Distortion", Range (0,256)) = 125
    4.         _TintAmt ("Tint Amount", Range(0,1)) = 0.1
    5.         _MainTex ("Tint Color (RGB)", 2D) = "white" {}
    6.         _BumpMap ("Normalmap", 2D) = "bump" {}
    7.     }
    8.     SubShader{
    9.         Tags {  "RenderPipeline"="UniversalPipeline" "Queue"="Transparent" "RenderType"="Opaque" }
    10.         Pass {
    11.             Name "BASE"
    12.             Tags { "LightMode"="UniversalForward" }
    13.             HLSLPROGRAM
    14.             #pragma vertex vert
    15.             #pragma fragment frag
    16.             #pragma multi_compile_fog
    17.             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
    18.             struct appdata_t {
    19.                 float4 vertex : POSITION;
    20.                 float2 texcoord: TEXCOORD0;
    21.                 UNITY_VERTEX_INPUT_INSTANCE_ID //Insert to support Single-Pass Instanced VR
    22.             };
    23.             struct v2f {
    24.                 float4 vertex : SV_POSITION;
    25.                 float2 uvbump : TEXCOORD1;
    26.                 float2 uvmain : TEXCOORD2;
    27.                 float fogFactor : TEXCOORD3;
    28.                 UNITY_VERTEX_OUTPUT_STEREO //Insert to support Single-Pass Instanced VR
    29.             };
    30.             float _BumpAmt;
    31.             half _TintAmt;
    32.             float4 _BumpMap_ST;
    33.             float4 _MainTex_ST;
    34.             TEXTURE2D_X(_CameraOpaqueTexture);
    35.             SAMPLER(sampler_CameraOpaqueTexture);
    36.             float4 _CameraOpaqueTexture_TexelSize;
    37.             v2f vert (appdata_t v){
    38.                 v2f o;
    39.                 UNITY_SETUP_INSTANCE_ID(v); //Insert to support Single-Pass Instanced VR
    40.                 UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); //Insert to support Single-Pass Instanced VR
    41.                 o.vertex = TransformObjectToHClip(v.vertex.xyz);
    42.                 o.uvbump = TRANSFORM_TEX( v.texcoord, _BumpMap );
    43.                 o.uvmain = TRANSFORM_TEX( v.texcoord, _MainTex );
    44.                 o.fogFactor = ComputeFogFactor(o.vertex.z);
    45.                 return o;
    46.             }
    47.             sampler2D _BumpMap;
    48.             sampler2D _MainTex;
    49.             float4 _GrabBlurTexture_TexelSize;
    50.            
    51.             TEXTURE2D_X(_GrabBlurTexture);// sampler2D _GrabBlurTexture; //Insert to support Single-Pass Instanced VR
    52.             SAMPLER(sampler_GrabBlurTexture);//Insert to support Single-Pass Instanced VR
    53.             half4 frag (v2f i) : SV_Target{
    54.                 UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);//Insert to support Single-Pass Instanced VR
    55.                 // calculate perturbed coordinates
    56.                 // we could optimize this by just reading the x & y without reconstructing the Z
    57.                 half2 bump = UnpackNormal(tex2D( _BumpMap, i.uvbump )).rg;
    58.                 float2 offset = bump * _BumpAmt * _GrabBlurTexture_TexelSize.xy;
    59.                 float2 screenUV = (i.vertex.xy / _ScaledScreenParams.xy);
    60.                 #if UNITY_UV_STARTS_AT_TOP
    61.                 screenUV.y *= -_ProjectionParams.x;
    62.                 #endif
    63.                 screenUV  = offset * i.vertex.z + screenUV;
    64.                 half4 col = SAMPLE_TEXTURE2D_X(_GrabBlurTexture, sampler_GrabBlurTexture, screenUV);                            
    65.                 // it would work if using _CameraOpaqueTexture
    66.                 //half4 col = SAMPLE_TEXTURE2D_X (_CameraOpaqueTexture, sampler_CameraOpaqueTexture, screenUV);
    67.                 half4 tint = tex2D(_MainTex, i.uvmain);
    68.                 col = lerp (col, tint, _TintAmt);
    69.                 col.rgb = MixFog(col.rgb, i.fogFactor);
    70.                 return col;
    71.             }
    72.             ENDHLSL
    73.         }
    74.     }
    75. }
    The front glass uses forward shader and the camera target grabs the boxes behind the glass.
    If using _CameraOpaqueTexture:
    Screenshot 2024-03-14 at 10.58.04.png
    If using _GrabBlurTexture(only right eye in screenshot, show different result in device):
    IMG_0020.PNG
    I also tried unity_StereoScaleOffset, but it’s float4(0,0,0,0) in Xcode frame capture.