Forum Discussion

raeldor's avatar
raeldor
Adventurer
3 years ago

Passthrough with Shadow

I'm trying to get shadow cast against the passthrough image.  I have a transparent shadow shader (attached to an invisible floor plane) that works fine against a UI Canvas/Image in 'Screen Space - Camera' (see screenshot).  When I remove that UI image though, I was expecting it to render that shadow over the passthrough image on the headset, since the passthrough image is at the back.  However, no shadow gets rendered.

 

Has anyone done this sucessfully?

 

 

18 Replies

    • raeldor's avatar
      raeldor
      Adventurer

      I am doing something very similar.  That may work well for a smart phone AR experience, but it seems Oculus passthrough is completely blatting out EVERYTHING if it thinks the 3D object is transparent; regardless of whether that object has shadows rendered to it or not.

      • mreimer's avatar
        mreimer
        Expert Protege

        Double check your unity quality settings and make sure shadows are on for the android device. Are you using URP or standard render?

  • So, I updated to URP.  My custom shader no longer works, so I used the UDP/Lit shader.  However, using this shader I can't seem to get a solid shadow on a completely transparent object, so I used the shader from the YouTube video.  That seems to work fine, but again, as soon as I run it in Oculus it just loses that shadow even though it works in the play window.

     

    I think this may be all about which material Oculus are using to render the passthrough.  To get it to work using a UI image as the background, I had to set the material to use Render Queue 'Geometry' (3000) instead of the default (From Shader, 2000).  There seems to be no Render Queue option for Passthrough though.

  • mreimer's avatar
    mreimer
    Expert Protege

    Double check that your Android quality settings have cast shadows enabled. 

     

     

    • raeldor's avatar
      raeldor
      Adventurer

      It definitely does, because if I make that invisible plane visible the shadows show up immediately.

  • Has anyone successfully got shadow working using OVR Passthrough Layer?

  • Yes, I've got it to work with URP.

     

    What I think was happening in our case is that the Passthrough Layer was rendered afterwards, and used the alpha value in the framebuffer for blending. So if your shadows are rendering and not setting the alpha to >0, they will be completely overwritten by the passthrough image.

     

    So a good thing to try would be to modify whichever shader renders your shadows to output an alpha value (say 1.0 or 255 to start with).

    • raeldor's avatar
      raeldor
      Adventurer

      That's great to know someone has got it working.  I suspected this might be the case.  Would you be able to share your shader code here?  Are you doing some kind of multi-pass?  Thanks!

      • dtaddisF42's avatar
        dtaddisF42
        Explorer

        I can't post the whole shader, but I think the crucial bit is to make sure you output a value for the alpha in the fragment shader:

        return half4(0, 0, 0, alphaWithShadowStrength);

         

        And I have my RenderQueue set to (Geometry - 1), so 1999. ZWrite On, Cull Off.

  • I finally got it to work.  I had to change the Blend mode and the color output from frag() to get it to work.  The original shader I pinched was...

     

    Shader "URP AR Shadow Receiver"
    {
        Properties
        {
            _ShadowColor ("Shadow Color", Color) = (0.35,0.4,0.45,1.0)
        }
     
        SubShader
        {
            Tags
            {
                "RenderPipeline"="UniversalPipeline"
                "RenderType"="Transparent"
                "Queue"="Transparent-1"
            }
     
            Pass
            {
                Name "ForwardLit"
                Tags { "LightMode" = "UniversalForward" }
     
                Blend DstColor Zero, Zero One
                Cull Back
                ZTest LEqual
                ZWrite Off
       
                HLSLPROGRAM
                #pragma vertex vert
                #pragma fragment frag
     
                #pragma prefer_hlslcc gles
                #pragma exclude_renderers d3d11_9x
                #pragma target 2.0
     
                #pragma multi_compile _ _MAIN_LIGHT_SHADOWS
                #pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE
                #pragma multi_compile _ _SHADOWS_SOFT
                #pragma multi_compile_fog
     
                #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
     
                CBUFFER_START(UnityPerMaterial)
                float4 _ShadowColor;
                CBUFFER_END
     
                struct Attributes
                {
                    float4 positionOS : POSITION;
                    UNITY_VERTEX_INPUT_INSTANCE_ID
                };
     
                struct Varyings
                {
                    float4 positionCS               : SV_POSITION;
                    float3 positionWS               : TEXCOORD0;
                    float fogCoord                  : TEXCOORD1;
                    UNITY_VERTEX_INPUT_INSTANCE_ID
                    UNITY_VERTEX_OUTPUT_STEREO
                };
     
                Varyings vert (Attributes input)
                {
                    Varyings output = (Varyings)0;
     
                    UNITY_SETUP_INSTANCE_ID(input);
                    UNITY_TRANSFER_INSTANCE_ID(input, output);
                    UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
     
                    VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz);
                    output.positionCS = vertexInput.positionCS;
                    output.positionWS = vertexInput.positionWS;
                    output.fogCoord = ComputeFogFactor(vertexInput.positionCS.z);
     
                    return output;
                }
     
                half4 frag (Varyings input) : SV_Target
                {
                    UNITY_SETUP_INSTANCE_ID(input);
                    UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
     
                    half4 color = half4(1,1,1,1);
     
                #ifdef _MAIN_LIGHT_SHADOWS
                    VertexPositionInputs vertexInput = (VertexPositionInputs)0;
                    vertexInput.positionWS = input.positionWS;
     
                    float4 shadowCoord = GetShadowCoord(vertexInput);
                    half shadowAttenutation = MainLightRealtimeShadow(shadowCoord);
                    color = lerp(half4(1,1,1,1), _ShadowColor, (1.0 - shadowAttenutation) * _ShadowColor.a);
                    color.rgb = MixFogColor(color.rgb, half3(1,1,1), input.fogCoord);
                #endif
                    return color;
                }
     
                ENDHLSL
            }
        }
    }

     

     

    After modification it's now...

     

     

    Shader "My Shadow Shader"
    {
        Properties
        {
            _ShadowColor ("Shadow Color", Color) = (0.35,0.4,0.45,1.0)
        }
     
        SubShader
        {
            Tags
            {
                "RenderPipeline"="UniversalPipeline"
                "RenderType"="Transparent"
                "Queue"="Transparent-1"
            }
     
            Pass
            {
                Name "ForwardLit"
                Tags { "LightMode" = "UniversalForward" }
    
    	Blend SrcAlpha OneMinusSrcAlpha 
                Cull Back
                ZTest LEqual
                ZWrite Off
       
                HLSLPROGRAM
                #pragma vertex vert
                #pragma fragment frag
     
                #pragma prefer_hlslcc gles
                #pragma exclude_renderers d3d11_9x
                #pragma target 2.0
     
                #pragma multi_compile _ _MAIN_LIGHT_SHADOWS
                #pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE
                #pragma multi_compile _ _SHADOWS_SOFT
                #pragma multi_compile_fog
     
                #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
     
                CBUFFER_START(UnityPerMaterial)
                float4 _ShadowColor;
                CBUFFER_END
     
                struct Attributes
                {
                    float4 positionOS : POSITION;
                    UNITY_VERTEX_INPUT_INSTANCE_ID
                };
     
                struct Varyings
                {
                    float4 positionCS               : SV_POSITION;
                    float3 positionWS               : TEXCOORD0;
                    float fogCoord                  : TEXCOORD1;
                    UNITY_VERTEX_INPUT_INSTANCE_ID
                    UNITY_VERTEX_OUTPUT_STEREO
                };
     
                Varyings vert (Attributes input)
                {
                    Varyings output = (Varyings)0;
     
                    UNITY_SETUP_INSTANCE_ID(input);
                    UNITY_TRANSFER_INSTANCE_ID(input, output);
                    UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
     
                    VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz);
                    output.positionCS = vertexInput.positionCS;
                    output.positionWS = vertexInput.positionWS;
                    output.fogCoord = ComputeFogFactor(vertexInput.positionCS.z);
     
                    return output;
                }
     
                half4 frag (Varyings input) : SV_Target
                {
                    UNITY_SETUP_INSTANCE_ID(input);
                    UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
     
                    half4 color = half4(1,1,1,1);
     
                #ifdef _MAIN_LIGHT_SHADOWS
                    VertexPositionInputs vertexInput = (VertexPositionInputs)0;
                    vertexInput.positionWS = input.positionWS;
     
                    float4 shadowCoord = GetShadowCoord(vertexInput);
                    half shadowAttenutation = MainLightRealtimeShadow(shadowCoord);
                     color = lerp(half4(0,0,0,0), _ShadowColor, (1.0 - shadowAttenutation));
               #endif
                    return color;
                }
     
                ENDHLSL
            }
        }
    }

     

     

    I'm sure due to my lack of experience this is a bit off, but it seems to produce the desired effect.  Next, I will try and project it onto the defined room geometry (walls, floor, desk etc.) that I can hopefully pick up from the SDK.  Really appreciated your pointers here, thank you.

     

  • I got this working and I keep replying with my shader code, but my reply keeps getting wiped out.  I don't know why. Anyway, thank you for the pointers, it helped a lot.  I had to modify the 'Blend' to get it to work.

  • Hi Raeldor,

    thanks for your shader! I have the same problem but I cannot make it work! I checked everything pipeline related and any other settings. I used your shader and it shows shadows in the editor but not in the build on my quest 2. Did you also changed settings at the SelectivePassthrough-Material like ZTest or blend alpha?

     

    Thanks for help, Can