Limit to number of spotlights

There is an odd effect, when you add more than 4 total spotlights:

Note that the last yellow spotlight does not show up.
However when you decrease the external ones to 2 instead of 3, everything is fine.

Is there a maximum number of 4 spotlights? If, so this should be documented, e.g. in Spotlights.
Can one increase this number?

I did find now in the documentation

That 4 is the limit to the number of lights. It mentions that this can be increased, but not how.

… some warning “Total number of lights exceeded” may be quite useful…

To increase the number of lights available at one time for some material, use

material.maxSimultaneousLights = 8;
1 Like

Hi everybody,

I have the same problem than @RainerHeintzmann . In the docs, the max number of lights is precised for a standard material. But which max number of lights could we use for a PBR Material. Is it the same ?

See also this thread for the maximum value you can put in maxSimultaneousLights :

May be the documentation is not clear to me. I assume that I’m able to give a maxSimultaneousLights value to each material.

Here’s a PG :

there are 20 spots and 1 natural lights on 2 grounds with two different materials. Each material has a maxSimultaneousLights value equal to 10.

The first ground is well enlighted, there are 9 spots and the natural light


Why the second ground is not enlighted with the spots ?

Second example :

each ground is enlighted BUT the total number of lights is still 10

It seems that the TOTAL number of lights has to be equal to 10 but not for each material…

As an additional remark: Spotlights (with procedural textures) not showing up, as in my case can sometimes cause errors, which are extremely different to trace to the origin. The effects caused in the scene can be very indirect. If this had been an error showing up (Max number of spotlights exceeded) or at least a warning (which I might have overlooked), this could have saved me days of work. So maybe one can think about this in a future version?

@bvaisman ground2 is still impacted by the spots 1-10, and because max lights is 10, spots 11-20 don’t impact it.

You should indicate that spots 1-10 only impact ground, and 11-20 only ground2:

Yes, it’s the same for all types of materials.

We can’t really do that, because having more lights than maxSimultaneousLights could be done on purpose. For eg., you could define 10 lights and set maxSimultaneousLights=4 for a material, knowing that only the first 4 lights will be used.

Could you elaborate on this one? I don’t see the link between spotlights and procedural textures (?)

I don’t quite understand why one would want to do this. But even if so, a warning would not really hurt, and one could also put in a way to disable the warning. I honestly think a default warning or even a default error would be the best, as I suspect many users already fell into this trap and many more will.

As for the remark to procedural light being even more difficult to detect: In may case, I blamed not seeing the effects caused one of the two procedural light always to some error of calculating them and it took me ages to understand that simple the whole spotlight was not showing. I actually fell into this trap now multiple times with a few month in between, which triggered me to suggest to raise a warning /error. In fact, I even read somewhere that it would raise an error, which it does not.


Ok, I think I understand a little bit better. A light impacts a mesh even if it is not directly enlighted, is it true ?

If i’m right, maybe the documentation (Limitation chapter) should be a little bit more precise.

2 precisions :

  • Speaking of “Standard material” in the Limitation Chapter is not useless because all materials have the same behavior about the maxSimultaneousLights limitation.

  • Writing that a mesh is impacted by a light EVEN if it is not directly enlighted and give a piece of code with the includedOnlyMeshes property.

Maybe I can contribute to the doc if you think it is useful. Tell me…

To be more exact, a light impacts the material of a mesh.

@labris, you’re right, a light impacts a material, that’s why all meshes are “impacted” even if they are not directly enlighted. Am I right ?

I feel your pain, but I’m reluctant to add a new check in the hot path, as it’s only for validation purpose, and in Babylon.js we generally don’t validate inputs for performance reasons… I think improving the doc should be a good workaround.

Let’s cc @sebavan to get his feeling.

By default, all lights (up to material.maxSimultaneousLights ) affect all meshes. It would be too time consuming to calculate if a mesh can be lit by a light. It’s the user responsibility to do a better job if they know which lights are going to affect which meshes.

Yes, please, improving the doc is always a must!

No, a light impacts a mesh, but only the first material.maxSimultaneousLights lights. You can explicitely define the meshes that are impacted by a light by adding the meshes to light.includedOnlyMeshes. If you don’t do it, the first material.maxSimultaneousLights created lights will impact the mesh.

Let s not add more code in the hot path and those lights scenarii are fully dynamic as you could rely on inclusion/exclusion to ensure a scene with 20 lights only contains materials impacted by 4 lights max for each of them so the check is more dynamic than simply at the scene level

I am not sure, but I can imagine that the current code anyway needs to check for exceeding the spotlight but the “else branch” just ignores further spotlights. For this reason the overhead of throwing a warning or error may be minimal.
But then there may also be a chance to add code that checks this condition at the point of creation of the spot, which would then not be in the hot path and have the big advantage that the error/warning is only produced once. Since I fell into the same trap already twice, and it cost me days to find out, I think it may be a good decision to have such an error/warning.

No, the code is:

We can’t do that, you could create 100 spots and assign them any way you like among your meshes (thanks to light.includedOnlyMeshes).

Thanks for looking into this. So “BindLights” sound like a function, which is not really called on every rendering pass.

If this is true, it would not be a big problem to add just the check. Math.min, anyway calls something like an if, so it probably does not even add time to replace the Math.min with
let warn_once = true; if (mesh.lightSources.length < maxSimultaneousLights) { len = mesh.lightSources.length} else { len=maxSimultaneousLights; if (warn_once) {console.warn("You used more lights than allowed by maxSimultaneousLights."); warn_once=false;}}
or something along those lines.

it is called for all submeshes/materials on every frame which is on the hot path.

1 Like