Adding lights to a scene does not scale

Hey there,

I am playing with clustered lights and came across some kind of perf issue, which could be just me not using the API correctly honestly :laughing:

Basically, you can either create a ClusteredLightContainer with an array of point lights, or you can add them as you go later with addLight. Using one big array at construction time simply uses addLight under the hood so you wouldn’t expect any difference here.

However the time it takes to execute becomes massive when creating the point lights upfront (takes 50s on my laptop):

https://playground.babylonjs.com/#CSCJO2#73

While adding the point lights as we are creating them is almost instantaneous:

https://playground.babylonjs.com/#CSCJO2#74

After skimming a bit in the code, it seems like scene.addLight is doing some stuff that does not scale well as we are adding more lights to the scene (complexity looks roughly O(#mesh * #light), so adding N lights yeilds O(#mesh * #light^2)). Adding the lights progressively to the container does not have the same issue because the lights are being removed from the scene at the same time, thus scene.addLight never explodes (complexity is more like O(#mesh) so adding N lights is linear: O(#mesh * #light)).

Maybe changing lightSources could help a bit to avoid the O(#light) from indexOf :thinking:

If you want a mesh acting as a light source and use many of light sources, you will want to use clustered lighting and thin instancing at the same time, but:

  • thin instancing is faster when uploading the entire buffer at once
  • clustered lighting is slower when uploading all new lights at once

If that’s the intended behavior, then maybe I can add some doc :+1:

@Evgeni_Popov, can you have a look ? if not, I ll do.

1 Like

At a first glance it would be more a doc issue but I will let @Evgeni_Popov have another look into it

1 Like

I think that lights that are to be used in a clustered container should never be added to the scene, as these lights don’t need all the setup we do for regular lights.

So, I created this PR that let’s you pass a flag to the light constructor so that the light is not added to the scene:

It makes your first PG even faster than the second one (after you update the creation of the point light to pass true for the 4th parameter)!

[EDIT] I also updated the documentation:

Yeah that makes a lot of sense! Thanks for the PR that works for me :ok_hand:

It will run so fast, looking forward to the next engine update :slight_smile:

1 Like