Search code examples
unity-game-engineshaderrendering

Custom shader does not receive light


I made a grid shader which is working fine. However, it does not get impacted at all by any light. Just so that you know concerning the plane having the shader:

  • Its dimensions are 1000x1x1000 (so wide enough)
  • Displays shadows with any other material and cast shadows is on
  • Using Unity 2019.3.0f3
  • Universal Render Pipeline

The plane using custom grid shader (not receiving light)

The plane using basic shader (receiving light)

Custom grid shader code

I tried few solutions though including adding FallBack "Diffuse" at the end, or #include along with TRANSFER_SHADOW things. However, these don't work either.


Solution

  • You need to tell your shader what to do with the light information if you want it to be lit. Here is an example applying diffuse light directly to the albedo of your grid shader:

    Shader "Custom/Grid"
    {
        Properties
        {
            _GridThickness("Grid Thickness", Float) = 0.01
            _GridSpacing("Grid Spacing", Float) = 10.0
            _GridColour("Grid Colour", Color) = (0.5, 0.5, 0.5, 0.5)
            _BaseColour("Base Colour", Color) = (0.0, 0.0, 0.0, 0.0)
        }
    
            SubShader{
            Tags { "Queue" = "Transparent" }
    
            Pass {
            ZWrite Off
            Blend SrcAlpha OneMinusSrcAlpha
    
            Tags {
            "LightMode" = "ForwardBase"
            } // gets us access to main directional light
    
    
            CGPROGRAM
    
            // Define the vertex and fragment shader functions
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityStandardBRDF.cginc" // for shader lighting info and some utils
            #include "UnityStandardUtils.cginc" // for energy conservation
    
            // Access Shaderlab properties
            uniform float _GridThickness;
            uniform float _GridSpacing;
            uniform float4 _GridColour;
            uniform float4 _BaseColour;
    
            // Input into the vertex shader
            struct vertexInput
            {
                float4 vertex : POSITION;
                float3 normal : NORMAL; // include normal info
            };
    
            // Output from vertex shader into fragment shader
            struct vertexOutput
            {
                float4 pos : SV_POSITION;
                float4 worldPos : TEXCOORD0;
                float3 normal : TEXCOORD1; // pass normals along
            };
    
            // VERTEX SHADER
            vertexOutput vert(vertexInput input)
            {
                vertexOutput output;
                output.pos = UnityObjectToClipPos(input.vertex);
                // Calculate the world position coordinates to pass to the fragment shader
                output.worldPos = mul(unity_ObjectToWorld, input.vertex);
    
                output.normal = input.normal; //get normal for frag shader from vert info
    
                return output;
            }
    
            // FRAGMENT SHADER
            float4 frag(vertexOutput input) : COLOR
            {
                float3 lightDir = _WorldSpaceLightPos0.xyz;
                float3 viewDir = normalize(_WorldSpaceCameraPos - input.worldPos);
                float3 lightColor = _LightColor0.rgb;
    
                float3 col;
    
                if (frac(input.worldPos.x / _GridSpacing) < _GridThickness || frac(input.worldPos.z / _GridSpacing) < _GridThickness)
                    col = _GridColour;
                else
                    col = _BaseColour;
    
                col *= lightColor * DotClamped(lightDir, input.normal); // apply diffuse light by angle of incidence
    
                return float4(col, 1);
            }
            ENDCG
            }
        }
    }
    

    You should check out these tutorials to learn more about other ways to light your objects. Same applies if you want them to accept shadows.

    Setting FallBack "Diffuse" won't do anything here since the shader is not "falling back", it's running exactly the way you programmed it to, with no lighting or shadows.