Shader fails to compile due to unresolved identifier `areaLightsLTC1Sampler`

In my application, users can dynamically add objects, including area lights. And the only selected light is enabled at any given time to avoid performance issues.

However, I found that when the user selects an area light after selecting a point light, a shader error occurs, which makes some of the materials invisible:

The console log reveals that the immediate cause of the problem might be an unresolved identifier, like areaLightsLTC1Sampleras shown below:

Error: FRAGMENT SHADER ERROR: 0:1166: 'areaLightsLTC1Sampler' : undeclared identifier
ERROR: 0:1166: 'areaLightsLTC2Sampler' : undeclared identifier
ERROR: 0:1166: 'computeAreaPreLightingInfo' : no matching overloaded function found
ERROR: 0:1166: 'assign' : cannot convert from 'const mediump float' to 'structure 'preLightingInfo' (symbol id 3295)'
ERROR: 0:1172: 'computeAreaDiffuseLighting' : no matching overloaded function found
ERROR: 0:1172: '=' : dimension mismatch
ERROR: 0:1172: 'assign' : cannot convert from 'const mediump float' to 'highp 3-component vector of float'
ERROR: 0:1173: 'computeAreaSpecularLighting' : no matching overloaded function found
ERROR: 0:1173: '=' : dimension mismatch
ERROR: 0:1173: 'assign' : cannot convert from 'const mediump float' to 'highp 3-component vector of float'

And the relevant shader fragment looks as follows:

preInfo=computeAreaPreLightingInfo(areaLightsLTC1Sampler,areaLightsLTC2Sampler,viewDirectionW,normalW,vPositionW,light1.vLightData,light1.vLightWidth.xyz,light1.vLightHeight.xyz,roughness);

From what I’ve found, the problem seems almost identical to the one that was resolved by a merged PR #16577,

Could it be fixed by a similar measure if they are the same kind of problem?

Thanks in advance!

Is there any chance you could reproduce the problem in the Playground? Without reproduction, it will unfortunately be difficult to find the reason why it crashes.

Shot in the dark => you can try adding this line of code at the beginning of your program:

BABYLON.ShaderStore.IncludesShadersStore["lightFragment"] = BABYLON.ShaderStore.IncludesShadersStore["lightFragment"].replaceAll("defined(AREALIGHTSUPPORTED)", "defined(AREALIGHTSUPPORTED) && defined(AREALIGHTUSED)");

If it works, I will create a PR with the change.

1 Like

I tested again after applying the change, and got a different shader error:

Error: FRAGMENT SHADER ERROR: 0:1138: 'computeAreaDiffuseLighting' : no matching overloaded function found
ERROR: 0:1138: '=' : dimension mismatch
ERROR: 0:1138: 'assign' : cannot convert from 'const mediump float' to 'highp 3-component vector of float'
ERROR: 0:1139: 'computeAreaSpecularLighting' : no matching overloaded function found
ERROR: 0:1139: '=' : dimension mismatch
ERROR: 0:1139: 'assign' : cannot convert from 'const mediump float' to 'highp 3-component vector of float'

And the offending line was:

info.diffuse=computeAreaDiffuseLighting(preInfo,diffuse1.rgb);

I’m sorry I can’t provide more useful information about the issue. I can export the scene if it helps, but I’m afraid I won’t be able to make a simple, reproducible test case at the moment.

Thanks much for trying to help. I just hope that the changed error message means you’re right on track to find the root cause.

Ok, so try this fix instead of the previous one:

BABYLON.ShaderStore.IncludesShadersStore["lightFragment"] = BABYLON.ShaderStore.IncludesShadersStore["lightFragment"].replaceAll("defined(AREALIGHT{X})", "defined(AREALIGHT{X}) && defined(AREALIGHTUSED) && defined(AREALIGHTSUPPORTED)");
1 Like

The error message changed again. It’s about specular light, this time:

Error: FRAGMENT SHADER ERROR: 0:1139: 'computeAreaSpecularLighting' : no matching overloaded function found
ERROR: 0:1139: '=' : dimension mismatch
ERROR: 0:1139: 'assign' : cannot convert from 'const mediump float' to 'highp 3-component vector of float'

The offending line:

info.specular=computeAreaSpecularLighting(preInfo,light1.vLightSpecular.rgb,clearcoatOut.specularEnvironmentR0,reflectivityOut.colorReflectanceF90);

Indeed, this one has a different syntax!

Try:

BABYLON.ShaderStore.IncludesShadersStore["lightFragment"] = BABYLON.ShaderStore.IncludesShadersStore["lightFragment"].replaceAll("defined(AREALIGHT{X})", "defined(AREALIGHT{X}) && defined(AREALIGHTUSED) && defined(AREALIGHTSUPPORTED)").replaceAll("#if AREALIGHT{X}", "#if defined(AREALIGHT{X}) && defined(AREALIGHTUSED) && defined(AREALIGHTSUPPORTED)");
1 Like

That finally did it! I can confirm that the line fixed my issue.

I’m glad that you not only fixed my issue promptly despite limited information, but also provided a workaround I can use until the fix lands in a new version.

Thanks very much for the help!

I’m glad it worked out for you!

cc @srzerbetto to create the PR, as I’m on vacation now.

The fix I made is to apply these changes in lightFragment.fx, but you should check if it looks ok for you:

replaceAll("defined(AREALIGHT{X})", "defined(AREALIGHT{X}) && defined(AREALIGHTUSED) && defined(AREALIGHTSUPPORTED)")
replaceAll("#if AREALIGHT{X}", "#if defined(AREALIGHT{X}) && defined(AREALIGHTUSED) && defined(AREALIGHTSUPPORTED)");
2 Likes

@mysticfall, we have merged a PR that should fix this issue. I will update here when we have a release published with the fix. Thanks for finding the bug!

2 Likes

Thanks much! And happy New Year. :slight_smile: