WebGL and mobile shaders not rendering

When creating a URP renderer WebGL build, we’ve noticed that certain shaders do not display when the page is viewed via mobile devices, specifically an android google pixel4a and a 3rd generation ipad pro. This started with the custom toon shader we have created for the characters in game. I tracked it down to the shadow attenuation calculations around additional lights (specifically point lights in this case) and the call to “AdditionalLightShadow”, if I nullify that, the shader will display, but we’d prefer to have working shadows. I’m confident this isn’t down to the quality setting, because we’ve no issues when viewed via chrome on PC.

Likewise, the standard URP shader does not display on mobile, but the simple lit shader does. Again, they work fine on PC. I’ve searched high and low for why this could be. I figured that the mobile devices are not enabling shadows for additional lights and so the keywords aren’t enabling, but I don’t quite get why the shaders don’t display at all. Do we have to accept that mobile devices aren’t capable of displaying real time shadows via WebGL or am I missing something?

Any assistance is much appreciated, having been at this for some hours now!

Unity Version: 2023.2.7f1

EDIT: It seems there is an issue with addressable bundles as I can place the character in scene and it will display on mobile (without shadows however), but when loaded via an addressable, the character is nowhere to be seen on mobile. It will display if I comment out the line:

#pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS

I’m guessing that I’m getting a similar problem to the one described here? Looks like there is a potential solution:

Now I can see the character, I can confirm that the shadows are working on my ipad, but not the phone. I can accept that some devices will not have the capability, do we know what the requirements are for shadows to display?

I managed to solve the issue I had with shaders disappearing on mobile. 2 things:

  1. The shader I had developed missed out one crucial keyword in the forward pass:
    #pragma shader_feature_local _RECEIVE_SHADOWS_OFF

This keyword appears to be enabled if the device cannot display shadows and is necessary to ensure that we don’t execute statements that are not supported by the device (in my case, the execution around additional shadows from spot lights).

  1. Addressable objects using the shader still didn’t work. I figured the issue might be that the keywords are geared towards the device that the addressables were built on (i.e. PC) rather than the device they were being loaded onto. So I added a small bit of code to swap the shaders in the addressables to use a local version of the same shader:
            List<Renderer> renderers = obj.GetComponentsInChildren<Renderer>().ToList();
            foreach (Renderer renderer in renderers)
            {
                Material[] materials = renderer.sharedMaterials;
                for (int i = 0; i < materials.Length; i++)
                {
                    if (materials[i].shader.name == shaderReplace.name)
                    {
                        materials[i].shader = shaderReplace;
                    }
                }
                renderer.sharedMaterials = materials;
            }

And this works! I now get shadows on my ipad and pc, but not on my phone… but that’s a fair compromise over getting nothing at all :slight_smile: