Search Unity

Shadows disappearing in custom VertexLit shader depending on view point

Discussion in 'Shaders' started by uwdlg, May 20, 2020.

  1. uwdlg

    uwdlg

    Joined:
    Jan 16, 2017
    Posts:
    150
    Hi,

    I'm experimenting with a custom shader (see below) because I want support for vertex colors and per-vertex lighting without interpolation. I tried adding support for casting and receiving shadows with mixed results: shadow are being cast and received, however the shadows only show up at specific camera angles and distances.
    This only happens when I use
    "LightMode" = "Vertex"
    , using
    "LightMode" = "ForwardBase"
    fixes it but I naturally also lose my non-interpolated vertex lighting. Another weird way to get rid of the problem is to have a mesh in view with a built-in shader (e.g. the Standard shader), then the shadows only disappear when I'm past the shadow distance as it should be, not when I'm getting closer to the shadow receiver or looking at it from different angles.
    Finding good documentation on implementing shadows has proven difficult for me, so I don't really understand what's going wrong. As a side note, I also couldn't find comprehensive information on the use of the UNITY_ prefixed macros as opposed to those without the prefix (SHADOW_COORDS, TRANSFER_SHADOW and SHADOW_ATTENUATION) so if anyone could shed some light on that (ha!) I would appreciate it as well. I'm using the UNITY_ variants now because SHADOW_ATTENUATION made surfaces darker everywhere when I used it (and the other old(?) macros), not just in shaded areas.

    My shader code:
    Code (CSharp):
    1. Shader "Mobile/NoInterpolationVertexColor" {
    2.     Properties {
    3.         _MainTex ("Base (RGB)", 2D) = "white" {}
    4.     }
    5.  
    6.     SubShader {
    7.         Tags { "RenderType" = "Opaque" }
    8.         LOD 80
    9.  
    10.         Pass {
    11.             Tags { "LightMode" = "Vertex" "Queue" = "Geometry" }
    12.          
    13.             CGPROGRAM
    14.             #pragma vertex vert halfasview
    15.             #pragma fragment frag
    16.             #pragma multi_compile_fog
    17.             #pragma multi_compile_fwdbase nolightmap nodirlightmap nodynlightmap noforwardadd nometa
    18.          
    19.             #include "UnityCG.cginc"
    20.             #include "Lighting.cginc"
    21.             #include "AutoLight.cginc"
    22.          
    23.             struct appdata {
    24.                 float4 vertex : POSITION;
    25.                 float3 normal : NORMAL;
    26.                 float4 color : COLOR;
    27.                 float2 uv : TEXCOORD0;
    28.                 float2 uv1 : TEXCOORD1;
    29.             };
    30.          
    31.             struct v2f {
    32.                 float4 pos : SV_POSITION;
    33.                 float4 posWorld : TEXCOORD2;
    34.                 float2 uv : TEXCOORD0;
    35.                 float4 vertexColor : COLOR0;
    36.                 nointerpolation float4 vertexLighting : TEXCOORD4;
    37.                 UNITY_SHADOW_COORDS(3) // put shadows data into TEXCOORD3
    38.             };
    39.          
    40.             uniform float4 _MainTex_ST;
    41.          
    42.             v2f vert(appdata v)
    43.             {
    44.                 v2f o;
    45.                 UNITY_SETUP_INSTANCE_ID(v);
    46.                 o.pos = UnityObjectToClipPos(v.vertex);
    47.                 o.posWorld = mul(unity_ObjectToWorld, v.vertex);
    48.                 o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    49.                 o.vertexLighting = float4(ShadeVertexLightsFull(v.vertex, v.normal, 4, true), v.color.w);
    50.                 o.vertexColor = v.color;
    51.                 UNITY_TRANSFER_SHADOW(o, o.uv1);
    52.                 return o;
    53.             }
    54.          
    55.             uniform sampler2D _MainTex;
    56.          
    57.             fixed4 frag(v2f i) : SV_Target
    58.             {
    59.                 fixed4 albedo = tex2D(_MainTex, i.uv);
    60.                 albedo *= i.vertexColor;
    61.                 fixed shadow = UNITY_SHADOW_ATTENUATION(i, i.posWorld);
    62.                 fixed3 lighting = i.vertexLighting.rgb * shadow;
    63.                 albedo.rgb *= lighting;
    64.              
    65.                 return albedo;
    66.             }
    67.             ENDCG
    68.         }
    69.      
    70.         Pass
    71.         {
    72.             Name "ShadowCaster"
    73.             Tags { "LightMode" = "ShadowCaster" }
    74.          
    75.             CGPROGRAM
    76.          
    77.             #pragma vertex vert
    78.             #pragma fragment frag
    79.          
    80.             #pragma multi_compile_shadowcaster
    81.          
    82.             #include "UnityCG.cginc"
    83.          
    84.             struct v2f {
    85.                 float4 vertex : SV_POSITION;
    86.                 float3 norm : NORMAL;
    87.                 float2 uv : TEXCOORD0;
    88.             };
    89.          
    90.             uniform float4 _MainTex_ST;
    91.          
    92.             v2f vert(appdata_full v)
    93.             {
    94.                 v2f o;
    95.                 UNITY_SETUP_INSTANCE_ID(v);
    96.                 o.vertex = UnityObjectToClipPos(v.vertex);
    97.                 o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
    98.                 o.norm = v.normal;
    99.                 return o;
    100.             }
    101.          
    102.             uniform sampler2D _MainTex;
    103.          
    104.             fixed4 frag(v2f i) : SV_Target
    105.             {
    106.                 fixed4 fragmentColor = tex2D(_MainTex, i.uv);
    107.                 return fragmentColor;
    108.             }
    109.             ENDCG
    110.         }
    111.     }
    112.     Fallback "Diffuse"
    113. }
    Looking forward to any insights, thanks in advance!
     
    Last edited: May 20, 2020