Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question problem with my shader: no shadows through alphatest

Discussion in 'Shaders' started by pitibonom, Jun 4, 2021.

  1. pitibonom

    pitibonom

    Joined:
    Aug 17, 2010
    Posts:
    220
    hi all :)

    see this pic:
    upload_2021-6-4_16-50-59.png

    Shadows do not appear between the 2 green lines....


    Here's the shader code:
    Code (CSharp):
    1. Shader "My_shaders/MyStd"
    2. {
    3.     Properties {
    4.         [NoScaleOffset] _MainTex ("Diffuse Texture", 2D) = "white" {}
    5.       [NoScaleOffset] _DirtLMTex ("Dirt/AO-LM (RGB-A)", 2D) = "(RGBA: .98,.98,.98,1)" {} // bidouille: presque 1 pour eviter les effets de bord....
    6.       _NightLightColor ("Lightmap color", Color) = (1,1,1,1)
    7.         [NoScaleOffset] _BumpMap ("Normal Texture", 2D) = "bump" {}
    8.  
    9.     }
    10.     SubShader {
    11.         Pass{
    12.             Tags { "LightMode" = "ForwardBase" }
    13.             CGPROGRAM
    14.  
    15.          // my variants....
    16.          #pragma multi_compile_local ___ WITH_CITY_NIGHTLIGHTS
    17.  
    18.             #pragma vertex vertex_program
    19.             #pragma fragment fragment_program
    20.  
    21.          #pragma multi_compile_fog
    22.  
    23.          #pragma multi_compile_fwdbase nolightmap nodirlightmap nodynlightmap novertexlight
    24.  
    25.  
    26.  
    27.  
    28.  
    29.          #include "Lighting.cginc"
    30.          #include "AutoLight.cginc"
    31.          
    32.             // My vars
    33.             sampler2D _MainTex;
    34.             sampler2D _BumpMap;
    35.             sampler2D _DirtLMTex;
    36.          static const half _BumpDistFade=20;
    37.          static const half _BumpLengthFade=5;
    38.      
    39. #if defined(WITH_CITY_NIGHTLIGHTS)
    40.          fixed4 _NightLightColor;
    41. #endif
    42.  
    43.  
    44.             // Base Input Structs
    45.             struct APP2V {
    46.                 float4 vertex: POSITION;
    47.                 half3 normal: NORMAL;
    48.                 half4 UV0: TEXCOORD0;
    49.                 half4 UV1: TEXCOORD1;
    50.                 half4 UVdissolve: TEXCOORD2;
    51.                 half4 tangent: TANGENT;
    52.             };
    53.      
    54.             struct V2F {
    55.                 float4 pos: SV_POSITION;
    56.                 half4 UV0: TEXCOORD0;
    57.                 half4 UV1: TEXCOORD1;
    58.                 half4 posWorld: TEXCOORD2;
    59.                 half3 normalWorld: TEXCOORD3;
    60.                 half3 tangentWorld: TEXCOORD4;
    61.                 half3 binormalWorld: TEXCOORD5;
    62.             SHADOW_COORDS(6) // shadows data into TEXCOORD6
    63.             UNITY_FOG_COORDS(7) // fog in 7    
    64.             };
    65.  
    66.  
    67.          //========================================================================
    68.          
    69.             // Vertex program
    70.             V2F vertex_program( APP2V v )
    71.          {
    72.                 V2F o;
    73.              
    74.                 o.normalWorld = normalize( mul( float4( v.normal, 0.0 ), unity_WorldToObject ).xyz );    
    75.                 o.tangentWorld = normalize( mul( unity_ObjectToWorld, v.tangent ).xyz );
    76.                 o.binormalWorld = normalize( cross( o.normalWorld, o.tangentWorld )* v.tangent.w);
    77.                      
    78.                 o.posWorld = mul( unity_ObjectToWorld, v.vertex );
    79.                 o.pos = UnityObjectToClipPos( v.vertex );
    80.                 o.UV0 = v.UV0;
    81.                 o.UV1 = v.UV1;
    82.  
    83.             TRANSFER_SHADOW(o)
    84.             UNITY_TRANSFER_FOG(o,o.pos);
    85.              
    86.                 return o;
    87.             }
    88.          
    89.             // Fragment program
    90.             float4 fragment_program( V2F i ): SV_Target
    91.          {
    92.             half3 pixel_in_cam = _WorldSpaceCameraPos.xyz - i.posWorld.xyz;
    93.             half pixel_dist = length(pixel_in_cam);
    94.  
    95.                 half3 lightDirection = normalize( _WorldSpaceLightPos0.xyz );
    96.  
    97.                 // Texture Maps
    98.             //--------------
    99.             // diffuse
    100.                 fixed4 diffuse = tex2D( _MainTex, i.UV0);
    101.  
    102.             // if diffuse texture have some alpha then clip under 0.5
    103.             clip(diffuse.a-0.5);
    104.  
    105.      
    106.             // dirt-AO
    107.                 fixed4 dirt = tex2D( _DirtLMTex, i.UV1);// dirt and AO texture
    108.          
    109.             fixed3 diff = diffuse * dirt.rgb * 1.5; // *1.5 for less dark walls
    110.  
    111.             fixed3 normalDirection;
    112.          
    113.          
    114.             // fading bumps with distance ( far walls do not need bumpmaps )
    115.             //---------------------------------------------------------------
    116.             if(pixel_dist < _BumpDistFade)
    117.             {
    118.                // bump
    119.                fixed3 bump =  UnpackNormal (tex2D (_BumpMap,  i.UV0));
    120.            
    121.                // a revoir sur un vecteur plutot que sur des valeurs X et Y independantes
    122.                fixed delta=saturate((pixel_dist-(_BumpDistFade-_BumpLengthFade))/_BumpLengthFade);
    123.            
    124.                // small interpolation to make bump coming less visible...
    125.                bump = fixed3(lerp(bump.x,0,delta),lerp(bump.y,0,delta),1);
    126.  
    127.                // Normal Transpose Matrix ( i still do not get why this is here 8*(  )
    128.                half3x3 local2WorldTranspose = half3x3(
    129.                   i.tangentWorld,
    130.                   i.binormalWorld,
    131.                   i.normalWorld
    132.                );
    133.            
    134.                // Calculate Normal Direction from normal and bumpies
    135.                normalDirection = normalize( mul( bump, local2WorldTranspose ) );
    136.             }
    137.             else
    138.             {
    139.                normalDirection = i.normalWorld; // with no bumps
    140.             }
    141.            
    142.            
    143.             fixed3 outputColor;
    144.            
    145.            
    146. #if defined(WITH_CITY_NIGHTLIGHTS)
    147.             // Night lightmap and its color and its intensity
    148.             fixed lm =  dirt.a;
    149.             fixed3 emiss = lm * _NightLightColor.rgb;// * _NightLightFactor;
    150.          
    151.             // night city wall lightings with less dirt/AO....
    152.             outputColor = diff * UNITY_LIGHTMODEL_AMBIENT.rgb + diffuse*(1-(dirt.rgb*lm-(lm-1)))*emiss*2;
    153. #else
    154.             // Lighting
    155.             fixed3 diffuseReflection = _LightColor0.rgb * saturate( dot( normalDirection, lightDirection ) );
    156.          
    157.                 outputColor = diff * (diffuseReflection * SHADOW_ATTENUATION(i) + UNITY_LIGHTMODEL_AMBIENT.rgb);
    158.              
    159. #endif            
    160.  
    161.             UNITY_APPLY_FOG(i.fogCoord,outputColor);
    162.          
    163.                 return half4(outputColor, 1.0);
    164.          
    165.             // show grey normals+bumps
    166. //                return half4(saturate( dot( normalDirection, lightDirection )),saturate( dot( normalDirection, lightDirection )),saturate( dot( normalDirection, lightDirection )), 1.0);
    167.          
    168.             }
    169.          
    170.             ENDCG
    171.         }
    172.    
    173.       // shadow caster rendering pass, implemented manually
    174.       // using macros from UnityCG.cginc
    175.       Pass
    176.       {
    177.          Tags {"LightMode"="ShadowCaster"}
    178.  
    179.          CGPROGRAM
    180.          #pragma vertex vert
    181.          #pragma fragment frag
    182.          #pragma multi_compile_shadowcaster
    183.          #include "UnityCG.cginc"
    184.  
    185.          struct v2f {
    186.              V2F_SHADOW_CASTER;
    187.          };
    188.  
    189.          v2f vert(appdata_base v)
    190.          {
    191.              v2f o;
    192.              TRANSFER_SHADOW_CASTER_NORMALOFFSET(o)
    193.              return o;
    194.          }
    195.  
    196.          float4 frag(v2f i) : SV_Target
    197.          {
    198.              SHADOW_CASTER_FRAGMENT(i)
    199.          }
    200.          ENDCG
    201.       }
    202.    }
    203. }
    I tried various things including deleting my shadow caster and calling for a tranp/cutout fallback, but nothing works....

    Does anyone have an idea of what am doing wrong please ?

    Note that i clip early in my shader code.....

    Thanks and happy unitying !
     
    Last edited: Jun 9, 2021
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    Your shader caster pass also needs to sample the
    _MainTex
    and
    clip()
    .

    The shadow caster pass is used both for shadow casting, and rendering the camera depth texture. The later of which Unity actually casts the directional shadows on to generate a screen space shadow texture. So if the shadow caster pass doesn't use alpha testing that matches the main forward pass directional shadows will appear to be casting on & from the un-clipped geometry.
     
  3. pitibonom

    pitibonom

    Joined:
    Aug 17, 2010
    Posts:
    220
    Thanks @bgolus for your answer :)

    This all makes sense but why it still did not work when i replace the shadow caster with an transparent/cutout/diffuse fallback ?
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    Cutout/Diffuse uses a
    _Cutoff
    property to set the
    clip()
    threshold. If your shader doesn't have that as a property it'll default to 0.0, which means no cutoff.

    Add this line to your shader's properties.
    [HideInInspector] _Cutoff ("Alpha cutoff", Range(0,1)) = 0.5[/code]
     
    pitibonom likes this.