Fade, cutoff and trasparent shaders that keep shadows.

Hi everyone. I’m trying to make a script that fade out objects between camera and player and then show them again. It works fine with Unity Standard Shader and you can also choose the rendering mode to use (fade, cutout, trasparent and opaque).

Problem is I want shadows to remain when the object fade out. So I’m trying to write custom shaders that keep shadows, ignoring transparency.

  • Fade shader with shadows works well.

dirtythornyelkhound

  • Cutout one does its job removing the object but shadows on object surface remain visible.

mediumpinkblackrussianterrier

Shader "Custom/CutoutKeepShadows" {
    Properties {
        _Color ("Color", Color) = (1, 1, 1, 1)
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _Cutoff ("Alpha cutoff", Range(0, 1)) = 0.5
    }
    SubShader
    {
        ZWrite Off
        Tags {"Queue" = "Geometry"}
        LOD 200

        Lighting Off

        CGPROGRAM


        #pragma surface surf Standard fullforwardshadows
        #pragma target 3.0

        sampler2D _MainTex;
        struct Input {
            float2 uv_MainTex;
        };

        fixed4 _Color;
        float _Cutoff;

         //#pragma instancing_options assumeuniformscaling
        UNITY_INSTANCING_BUFFER_START(Props)
            // put more per-instance properties here
        UNITY_INSTANCING_BUFFER_END(Props)
        void surf (Input IN, inout SurfaceOutputStandard o) {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
            o.Albedo = c.rgb;
            clip(c.a-_Cutoff);
        }

        ENDCG
    }
    FallBack "VertexLit"
}
  • I have no ideas for the trasparent one… I just want to generate shadows using a constant alpha value.

Every help will be very appreciated! :slight_smile:

I covered a similar topic here:

The TLDR is the shadow caster pass is used both for casting and receiving shadows. By default a Surface Shader is using the shadowcaster pass from the Fallback shader, which means it ignores any alpha testing (clip()) or alpha blending you do in the Surface Shader. Using addshadow will generate a unique shadow caster pass for your Surface Shader, but you’ll need to differentiate between when rendering the camera depth texture (what the shadow receiving is based off of) and when rendering a shadow map and do different things depending on that (ie: don’t clip for shadow maps, do clip for camera depth).

Thanks for the reply. I was trying to figure out a solution, so I’ve simply changed Queue tag. “Transparent” works.

If you don’t need your objects to receive real time shadows, yep, that works.