Imagine a scenario where you have a street with numerous streetlights (over 20) and you position an object nearby, expecting to see a shadow.
The lights are represented as:
var light = new THREE.PointLight(0xffffff, 0.5, 6.0);
Only the street has .receiveShadow = true
and only the car has .castShadow = true
(in addition to later including the lights)
https://i.sstatic.net/y7ORZ.png
In three.js, setting .castShadow = true
for all the lights leads to the following error:
THREE.WebGLProgram: shader error: 0 gl.VALIDATE_STATUS false
gl.getProgramInfoLog Fragment shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (16).
Fortunately, in our scenario, we only require a few lights (maximum of 4) to cast shadows, as most of the lights are out of range anyway.
I attempted two approaches:
Iterating through all the lights and dynamically setting
.castShadow = true
or.castShadow = false
.Additionallly, adding and removing the lights completely while configuring them with or without shadows.
Both methods resulted in the same error message.
Is there another approach that could be effective?
Update
@neeh created a Fiddle demonstrating this issuehere (to replicate the error, adjust var numLightRows = 8;
to a higher value). Note that there will be a separate error when too many lights are added, which is not related to the initial problem.
It was also noted that from the source code found here, a pointShadowMap
is generated even if not utilized. This clarifies why there is no improvement with a more efficient method. This issue directly relates to the GLSL code.
Therefore, we are restricted by the GPU, which in some cases may only support 16 IMAGE_UNITS (though different GPUs may vary - my CPU functions well with more). You can verify your system's capabilities using
renderer.capabilities.maxTextures
. Nonetheless, as mentioned earlier, only 4 lights are truly necessary.
The challenge persists.