Complex app, turning on shadows gives shader error -- any help appreciated!

I have a complex app using three.js r112.
It uses NGL (molecule viewer) and imports glTF objects into a complex scene. I tried enabling shadows today and my model disappears, due to shader problems. I recognize that the bug could be almost anywhere, but since the error appears in three.js, I’m hoping for some help on this forum.

I’m doing

.renderer.shadowMap.enabled = true
.renderer.shadowMap.type = Three.PCFSoftShadowMap

to enable shadows, and so far that works (but does nothing because no objs or lights cast or receive them). The problem starts when I run this code on my lights: I get a shader error.

  enableShadowForLight(light: Three.Light) {
    light.castShadow = true
    light.shadow.mapSize.width = 512
    light.shadow.mapSize.height = 512
  }

the shader error is this:

three.module.js:19048 THREE.WebGLProgram: shader error:  0 35715 false gl.getProgramInfoLog No compiled fragment shader when at least one graphics shader is attached.
\0  THREE.WebGLShader: gl.getShaderInfoLog() fragment
ERROR: 0:692: 'SpotLightShadow' : undeclared identifier
ERROR: 0:692: 'spotLightShadow' : syntax error
\01: #version 300 es
2: 
3: #define varying in
4: out highp vec4 pc_fragColor;
5: #define gl_FragColor pc_fragColor
6: #define gl_FragDepthEXT gl_FragDepth
7: #define texture2D texture
8: #define textureCube texture
9: #define texture2DProj textureProj
10: #define texture2DLodEXT textureLod
11: #define texture2DProjLodEXT textureProjLod
12: #define textureCubeLodEXT textureLod
13: #define texture2DGradEXT textureGrad
14: #define texture2DProjGradEXT textureProjGrad
15: #define textureCubeGradEXT textureGrad
16: precision highp float;
17: precision highp int;
18: #define HIGH_PRECISION
19: #define SHADER_NAME ShaderMaterial
20: #define GAMMA_FACTOR 2
21: #define USE_FOG
22: #define USE_COLOR
23: #define USE_SHADOWMAP
24: #define SHADOWMAP_TYPE_PCF_SOFT
25: uniform mat4 viewMatrix;
26: uniform vec3 cameraPosition;
27: uniform bool isOrthographic;
28: 
29: vec4 LinearToLinear( in vec4 value ) {
30: 	return value;
31: }
32: vec4 GammaToLinear( in vec4 value, in float gammaFactor ) {
33: 	return vec4( pow( value.rgb, vec3( gammaFactor ) ), value.a );
34: }
35: vec4 LinearToGamma( in vec4 value, in float gammaFactor ) {
36: 	return vec4( pow( value.rgb, vec3( 1.0 / gammaFactor ) ), value.a );
37: }
38: vec4 sRGBToLinear( in vec4 value ) {
39: 	return vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.a );
40: }
41: vec4 LinearTosRGB( in vec4 value ) {
42: 	return vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a );
43: }
44: vec4 RGBEToLinear( in vec4 value ) {
45: 	return vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );
46: }
47: vec4 LinearToRGBE( in vec4 value ) {
48: 	float maxComponent = max( max( value.r, value.g ), value.b );
49: 	float fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );
50: 	return vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );
51: }
52: vec4 RGBMToLinear( in vec4 value, in float maxRange ) {
53: 	return vec4( value.rgb * value.a * maxRange, 1.0 );
54: }
55: vec4 LinearToRGBM( in vec4 value, in float maxRange ) {
56: 	float maxRGB = max( value.r, max( value.g, value.b ) );
57: 	float M = clamp( maxRGB / maxRange, 0.0, 1.0 );
58: 	M = ceil( M * 255.0 ) / 255.0;
59: 	return vec4( value.rgb / ( M * maxRange ), M );
60: }
61: vec4 RGBDToLinear( in vec4 value, in float maxRange ) {
62: 	return vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );
63: }
64: vec4 LinearToRGBD( in vec4 value, in float maxRange ) {
65: 	float maxRGB = max( value.r, max( value.g, value.b ) );
66: 	float D = max( maxRange / maxRGB, 1.0 );
67: 	D = clamp( floor( D ) / 255.0, 0.0, 1.0 );
68: 	return vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );
69: }
70: const mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );
71: vec4 LinearToLogLuv( in vec4 value )  {
72: 	vec3 Xp_Y_XYZp = cLogLuvM * value.rgb;
73: 	Xp_Y_XYZp = max( Xp_Y_XYZp, vec3( 1e-6, 1e-6, 1e-6 ) );
74: 	vec4 vResult;
75: 	vResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;
76: 	float Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;
77: 	vResult.w = fract( Le );
78: 	vResult.z = ( Le - ( floor( vResult.w * 255.0 ) ) / 255.0 ) / 255.0;
79: 	return vResult;
80: }
81: const mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );
82: vec4 LogLuvToLinear( in vec4 value ) {
83: 	float Le = value.z * 255.0 + value.w;
84: 	vec3 Xp_Y_XYZp;
85: 	Xp_Y_XYZp.y = exp2( ( Le - 127.0 ) / 2.0 );
86: 	Xp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;
87: 	Xp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;
88: 	vec3 vRGB = cLogLuvInverseM * Xp_Y_XYZp.rgb;
89: 	return vec4( max( vRGB, 0.0 ), 1.0 );
90: }
91: vec4 linearToOutputTexel( vec4 value ) { return LinearTosRGB( value ); }
...

Do you enable lights at runtime? Since you’re using shader material it is hard to help without an example where and how you use it, with the full shader code. Did you enabled lights for the material?

Yeah, everything’s at runtime, driven by external models. I guess there are shader materials involved – not mine but probably NGL’s. Do you have a pointer to how to enable lights for a material? (I did grep for [sS]potLightShadow in my code and all dependencies, the only place I see it is in three.js.)

I don’t know this NGL, it might be better to ask the author for help in this case unless you provide the full code to inspect, other than that we can just make guesses. (the full shader code you get in the console might be enough already)