Different light interaction in edit mode and play mode

I have a shader that is applied to SpriteRenderers in Built-in pipeline Unity that renders shadows + normals for sprites. The light’s interaction with the sprites in edit mode works perfectly but it has a very strange interaction in playmode. In playmode, the light only minimally affects the tiles at a lower y value. (entire level is rotated 90 degrees, a bit confusing I know). This weird interaction only happens for tiles with normals.

Note the environment is built out of tilemaps (only for the purpose of generating GameObjects to put SpriteRenderers on, the tilemap itself does no rendering), so the whole thing is re-generated at runtime. But that doesn’t matter as the same happens when I pull the tiles out of the tilemap.

Here’s a direct comparison:

There is something with the rotation of the tile relative to the light that produces this effect, but I don’t know why. Here is what I mean with a 90 degree rotation.

And here’s the shader used for this:

Shader "Custom/SpriteShadowNormal" {
    Properties{
        _Color("Color", Color) = (1,1,1,1)
        [PerRendererData]_MainTex("Sprite Texture", 2D) = "white" {}
        _Cutoff("Shadow alpha cutoff", Range(0,1)) = 0.5
        _NormalMap ("NormalMap", 2D) = "bump" {}
    }
        SubShader{
            Tags
            {
                "Queue" = "Geometry"
                "RenderType" = "TransparentCutout"
            }
            LOD 200

            Cull Off

            CGPROGRAM
            // Lambert lighting model, and enable shadows on all light types
            #pragma surface surf Lambert vertex:vert addshadow

            // Use shader model 3.0 target, to get nicer looking lighting
            #pragma target 3.0
            #include "UnityCG.cginc"

            sampler2D _MainTex;
            sampler2D _NormalMap;
            fixed4 _Color;
            fixed _Cutoff;

            struct appdata_t
            {
                float4 vertex : POSITION;
                float4 tangent : TANGENT;
                float3 normal : NORMAL;
                float2 texcoord : TEXCOORD0;
                float2 texcoord1 : TEXCOORD1;
                float2 texcoord2 : TEXCOORD2;
                float2 texcoord3 : TEXCOORD3;
                float4 color : COLOR;
            };

            struct Input
            {
                float2 uv_MainTex;
                //float2 uv_NormalMap;
                fixed4 color;
            };

            Input vert(inout appdata_t IN, out Input OUT)
            {
                OUT.uv_MainTex = IN.texcoord;
                OUT.color = IN.color;

                return OUT;
            }

            void surf(Input IN, inout SurfaceOutput o) {
                fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color * IN.color;
                o.Albedo = c.rgb;
                o.Alpha = c.a;
                o.Normal = UnpackNormal(tex2D (_NormalMap, IN.uv_MainTex));
                clip(o.Alpha - _Cutoff);
            }
            ENDCG
        }
            FallBack "Diffuse"
}

Any ideas why this is happening? I just don’t get it.

By testing settings and such, I have concluded the issue is NOT produced by static/dynamic batching or the structure of the normal map (using Unity’s “From Grayscale” option in the normal map has the same issue).

Figured it out. Nearly pulled my hair out in the process. I tested different shaders, rotations, settings on shaders etc. but the problem was apparently due to some Sprite Atlases not working properly with the normal maps assigned as secondary textures. This makes sense, but was incredibly hard to figure out.

I solved the issue for now by removing the atlases, but that is only temporary while I figure out how to include the normals in the atlases.

I confirmed that this lighting issue is caused by the Sprite Atlas packing of the secondary normal maps into the secondary texture atlas.

And I have nailed this down to being a bug pretty much 100%.

I made a repro project using the same shaders + textures and settings of the grass tile (one custom shader, one from this git link). The lighting bug only occurs when the sprites are atlased and specifically when in linear color space. In gamma space everything works fine and dandy.

Gamma color space:

Linear color space:

The point light when in linear color space also brightens the tile up way more in general, which I don’t know why. Might make a post about that separately. Regardless, the lighting is messed up in linear color space. Removing the sprite atlas fixes this issue, making the lighting evenly balanced on the tile.

I have attached a repro project too in case it is helpful for anyone. @Venkify I saw you posting in a related thread about secondary textures and normal maps, might this be interesting?

I use Unity 2020.3.2.1f1, Built-in renderer.

7626283–948838–gamma vs linear and sprite atlases.unitypackage (4.11 MB)

Thank you for taking the time to investigate this on your own. It does not seem to be related to baked or realtime GI. Rather, it appears to be a realtime rendering issue. Please submit a bug report, and someone from the customer QA team will take a look. You could also point them to this thread in your report. Thanks!

1 Like

I have sent a bug report. Thanks for your attention! You are also correct in that it is not related to baked lighting or GI but just regular lighting. Also, interestingly enough, it happens to point lights but NOT spot lights (nor I think directional lights).

I forgot to include the link in my bug report! Could you edit the report with it? Case number is 1378322. @kristijonas_unity

Thanks for submitting a bug report! I have included a link to this thread in the report for you. The case is currently waiting to be picked up.