Light.dispose causes WebGL-errors

Hello!

This is either a bug or a suggestion to improve the documentation around the light.dispose() function.

My question: Is it ever ok to dispose a used light source? If so, when?

I have a playground example here with a typical use case where the user has a scene and removes a light:
https://playground.babylonjs.com/#L1K8ZC#1

It results in a WebGL-error in the console.

Maybe garbage collecting will collect it eventually if I do removeLight and then removes all my references to it, but then at least documentation should say that light.dispose() is a forbidden method! Sorry if it is there in documentation, I’ve mostly looked at the API reference.

Related posts here on the forum:

  1. Adding / Destroying point lights (maybe it shall be in Bugs section ?)
  2. Mesh.light.dispose(); WebGL warning: drawElements:

In 1 it has exactly the same issue as I do but that post focuses on the blinking and not the GL-error.
In 2 the user is satisifed with keeping the light around (they probably need it again later anyway).
But what if I really want to get rid of the light?

Hello this is a known constraint. The light can be removed and you can either accept the webgl error which is just a message or there is another solution (but a bit more heavy duty)

But before talking about the second solution, a quick explanation of why we get this message. The main reason is that we try to avoid blinking. If you remove a light, the shaders will have to be recompiled. That will cause a blink unless we keep the previous shader in place while we compile the new one. Problem in this case is that the old shader will NOT found the light (because it was removed :slight_smile: ) and thus WebGL will complain. But then the new shader will come and everyone will be happy

Now let’s say you do not want that error message, you can set the material to NOT allow hot swapping like here:
https://playground.babylonjs.com/#L1K8ZC#2

The relevant code is:

sphere.material.allowShaderHotSwapping = false;
3 Likes

Thanks for the explanation, I think I know what to do now on our side.

Is there some way of knowing when it is safe to dispose() all light sources that I’m keeping around?

On your side it feels like a solveable problem, but I assume that you’ve decided not to do it (now)?

I assume the situation is if a mesh is beint lit by a light that is removed… and it uses an effect with one light too much… Couldn’t engine keep one light of each type, disabled, and maybe a dummy shadowmap, that you could replace the light reference with? It wouldn’t blink then, just update WebGL-state. I realize that it could turn ugly but feels like a very solveable thing.

I guess in the end that it is about some UniformBuffer-data that you need to keep around that is killed when I do light.dispose(), and that you find it via the light-reference.

Thanks for the good answer! I’m hunting one more WebGL issue, lets see if that is also related to this! Maybe you already know btw, the error is this:

[.WebGL-0000025B6F6B6AC0] GL_INVALID_OPERATION: Mismatch between texture format and sampler type (signed/unsigned/float/shadow).

Cheers,
Anders.

Anytime, as I told you there is no real problem :slight_smile:

Well we consider this is not a real issue so we don’t want to add a lot of code to maintain:)

For your error I will need more info and a repro

Understandable. Wish there was something I could give my lights to so you could dispose them when it was safe but not biggie. I still feel that documentation of light.dispose() could be improved here though!

About my error I’ve spend a day trying to reproduce it in the playground without success but I might give it a new chance on monday!

Thanks for all the help!

Cheers,
Anders.

Please help us by adding a PR for it. Babylon.js is a collective effort :wink: