Lighting randomly decided to not work. Great.

The image below is two different Unity projects. The one on the left randomly decided to stop working with lighting. The one on the right does work correctly with lighting.
Both have the same shader.
What could have caused it?

Here’s the simple code.

Shader "Unlit/Lighting"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"
            #include "Lighting.cginc"
            #include "AutoLight.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
                float3 normal : NORMAL;
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
                float2 uv : TEXCOORD0;
                float3 normal : TEXCOORD1;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                o.normal = UnityObjectToWorldNormal(v.normal);
                return o;
            }

            float4 frag (v2f i) : SV_Target
            {
                float3 N = i.normal;
                float3 L = _WorldSpaceLightPos0.xyz;


                return float4(L, 1);
            }
            ENDCG
        }
    }
}

ALSO! using _LightColor0 just randomly makes it black, aka no color. I’m like ugh.

Without "LightMode"="ForwardBase" there’s no guarantee that either _LightColor0 or _WorldSpaceLightPos0 will be set to anything useful. Basically it’ll be set if something else happens to set it before this shader renders.

When I add the LightMode tag my material just turns magenta. This always happens. Its frustrating and I don’t know if its a flaw of my code or a Unity bug.

Here’s the code:

Shader "Unlit/Lighting"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }

        Pass
        {

            Tags { "LightMode" = "ForwardBase" }
           
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"
            #include "Lighting.cginc"
            #include "AutoLight.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
                float3 normal : NORMAL;
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
                float2 uv : TEXCOORD0;
                float3 normal : TEXCOORD1;
                LIGHTING_COORDS(2,4)
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                o.normal = UnityObjectToWorldNormal(v.normal);
                TRANSFER_VERTEX_TO_FRAGMENT(v);
                return o;
            }

            float4 frag (v2f i) : SV_Target
            {
                float3 N = i.normal;
                float3 L = _WorldSpaceLightPos0.xyz;

                return float4(N, 1);
            }
            ENDCG
        }
    }
}

I assume you’re using URP or HDRP? Those require totally different shaders and tags. _WorldSpaceLightPos0 should never be set to anything if you’re using an SRP. The fact it is at all is the bug.

I am using URP, so everything I’m doing is incorrect? Could you point me in some resource to understand how to add lighting support to my shader with URP?

Basically, yeah.

Nope. Because none exist. There have been a few people that have posted example minimal shaders or done basic YouTube videos, but the SRPs were changing so often that usually within a week of those people posting they’d be out of date and no longer work. Unity hasn’t bothered to document the URP’s code yet themselves, and may never, and the community has essentially abandoned any attempt to do so waiting for the URP to drastically changing constantly every few months… which we’re still waiting for.

The best you can do is look at Unity’s own shaders for the URP.
https://github.com/Unity-Technologies/Graphics/blob/32ea6be2c6a695c37a0ce2c2fe417a135701d256/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl

So people who add lighting support to a shader in URP are all figuring it out themselves via trial and error? Damn… This will be harder than expected. Thanks for the help though. I will continue figuring it out.

Either they’re just remaking everything using Shader Graph, or they’re going insane. Yes. There’s a reason why @jbooth_1 ‘s Better Shaders exist and seems to be getting popular among the major asset store devs. They get to go back to focusing on making their asset work, and @jbooth_1 is taking on the responsibility of having to deal with every version of the SRP breaking something by making his own shader generation system so that he doesn’t have to go back and rewrite all of his own assets’ shaders each time a new version comes out too.

1 Like