Normal map not working when adding Standard in Always Included Shaders

If i add Standard Shader in Graphic Settings > Always Included Shaders the normal map is not working properly and lighting fails (shadows, etc…) on WebGL.

The problem occurs with WebGL builds and does not occur with standalone builds. Tested with Unity 2018.2.14f1. It happens in both Firefox and Chrome. The problem also occurs if the normal map is in the Secondary Maps.

Video showing the bug:

Video showing expected result:

I need the Standard Shader in Always Included Shaders because I want to do Variant Stripping (note that I’m not stripping anything in this scene, I created it for test purpose because I noticed the bug while writing a stripper).

I wrote a shader to display only the normal map, world normals and lambert coefficient and everything works correctly. I guess the problem must come from the standard shader.

Maybe I’m missing something about variants but I haven’t noticed anything relevant in the docs and online.

Here is the unity scene reproducing the bug:
https://www.dropbox.com/s/s8kjupajqppjf2c/WebGLNormalMapBug.unitypackage?dl=1
(Don’t forget to add Standard in Graphic Settings > Always Included Shaders to reproduce the bug).

Here is my settings:


The bug doesn’t show up when using the Lightweight Rendering Pipeline.

I think this should be added to the issue tracker.

1 Like

Nobody else encountered this issue ?

The bug also appears with different shaders like “Standard (Specular Setup)” or “Mobile/Bumped Diffuse (1 directional light)”.
I suppose it is a normal map bug, when I see the code that extract the normal in “Mobile/Bumped Diffuse”, I’m wondering why the normal isn’t being transformed before being used for lighting.

o.Normal = UnpackNormal (tex2D(_BumpMap, IN.uv_MainTex));
...
inline fixed3 UnpackNormal(fixed4 packednormal)
{
#if defined(UNITY_NO_DXT5nm)
    return packednormal.xyz * 2 - 1;
#else
    return UnpackNormalmapRGorAG(packednormal);
#endif
}

But that doesn’t makes sense because the bug doesn’t appear when the shader isn’t in “Always Included Shaders”, which shouldn’t affect the code. Moreover, I have extracted the list of variants that are being compiled in both case and lists are identical.

Just sent a bug report: Unity Issue Tracker - [WebGL] Normal Maps produce wrong lighting on WebGL build when appropriate Unity shader is put into Always Included Shaders list

1 Like

Hi, we’ve been having a similar issue with normals on WebGL except in our case they break when we put the shader (and the objects that want to use that shader) in an asset bundle. The shader in question is not included in the ‘Always Included shaders’ list. Now, if we override the UnpackNormal function from above with a version that always calls UnpackNormalmapRGorAG (and doesn’t care about the define) and put that in the asset bundle everything works and shading looks correct.

I tried to build with shader variant stripping disabled from graphics settings (and without the override in the shader) but that results into broken shading as well.

So, I’m thinking here that something that is same for the ‘Always Included Shaders’ list and asset bundles is causing ‘UNITY_NO_DXTnm’ to be defined which is not the correct behaviour for the shader on WebGL.

3 Likes

Really weird things are happening with this ‘Always Included Shaders’ list…

1 Like

You guys just saved my day :slight_smile:

[EDIT]: To clarify what we did to solve our issue (since I had a few PMs): We simply called UnpackNormalmapRGorAG() instead of UnpackNormal(). This way we’re skipping the UNITY_NO_DXTnm check.

We are having the same problem, even with asset bundles that were built with the addressable asset system.
Wrongly putting the normal maps into “default” format instead of normal maps also seems to help with this issue, but is by no means a fix obviously.

Reproduced the issue, and working to fix this up. Thanks for the bug report!

It looks like the issue is that shaders in the Always Included Shaders list are getting miscompiled without the appropriate compilation options being present in the shader, which results in wrong set of #defines being present.

To work around the issue, removing the shaders from Always Included Shaders list, or cloning the shader and making sure that the clone is not placed in the Always Included Shaders list should work.

I have not yet been able to check out the issue regarding addressables/asset bundles, but the issue is likely related.

2 Likes

@jukka_j Cool, so glad to hear! :slight_smile:
The solution here did however not work in my case. :confused:

Thanks for checking this out though, this is an immense problem as I had to go back to Legacy Shaders in WebGL atm.

Spent a couple days trying to fix it. I’m using the Universal RP, and changing the material shader to URP/Baked Lit instead of URP/Lit did it for me. Hope this helps someone.

Try setting your normalmap texture types not to normalmap, but texture and set sRGB to false, that got it to work for us (URP/Lit materials on prefab loaded by addressables)

where is that?

Actually idk why I can’t do that :confused: