• 3D
  • How to keep light sources on?

Hi! I'm struggling with light sources (SpotLight, if that makes a difference) for my first 3D game. I have programming experience but game development, and in particular 3D, are new to me. I have tried reading up on Godot 3D lighting stuff but I still don't know what to search for or what's wrong.

I'm making a game in which there is a character going along a "road". The road is relatively long and I want to add streetlights along the sides. It's not super important that all streetlights are on the whole time, but it's of course important that any streetlights visible to the player at any given moment, are on.

I have tried placing SpotLight objects where I want them, but the problem is that after a couple of seconds, as the camera (which follows the player) moves away from the start of the road, all lights turn off, seemingly at the same time. I have tried adding a big GIProbe object and bake the lights, but I still have the same problem.

Any ideas what might be wrong, and how to solve it? Is there a fundamental problem with my approach?

I'm not sure what is causing the problem per say, but what I would consider doing is turning the spot lights on and off based on their distance from the player/camera. Godot has a limit of 8 active lights per object (OpenGL restriction) in Godot 3.2, so it could be that you are exceeding this limit and that's why the lights do not appear to be working.

I would try attaching an Area node to each of the lights, have the lights disabled by default (visible=false) and then use the body_entered signal to turn the light on (visible=true) and the body_exited signal to turn if off again. Then you can give each of the Area nodes collision shapes that are large enough that the lights turn on when expected, but small enough that they will turn off was the player leaves. This should, hopefully, fix the issue.

Oh, thanks so much! I'll give that a try. It will probably take me a little time because I'm generating the position of the lights with a script so I will have to tweak it and see how I generate the areas, collision shapes, and signal handlers.

@TwistedTwigleg said: Godot has a limit of 8 active lights per object (OpenGL restriction) in Godot 3.2, so it could be that you are exceeding this limit and that's why the lights do not appear to be working.

Does "per object" here mean that because the road is a single object, only 8 lights can affect it at the same time?

@HNarrativist said:

@TwistedTwigleg said: Godot has a limit of 8 active lights per object (OpenGL restriction) in Godot 3.2, so it could be that you are exceeding this limit and that's why the lights do not appear to be working.

Does "per object" here mean that because the road is a single object, only 8 lights can affect it at the same time?

Yeah, if the road is a single object than it can only be lit by 8 dynamic lights at a time. I think this limit has been increased to 64 in Godot 4.0 or Godot 3.2+ though.

Also, something else that just occurred to me: If you can break your road down into smaller chunks, smaller meshes that each are a portion of the road, then you may be able to work around the limit as long as no one road mesh has more than 8 lights on it at a time.

I still have to have a more complete solution, but doing a very quick and dirty test it seems to work great!

In my case, I keep track of how far ahead in the road the player is, so I made a very quick (and wrong) estimation of when I should turn on/off the lights. The lights currently turn on a bit too soon or too late, and solving it like this might prove to be a bad idea, but at least I can confirm that the general approach of turning them off and only turn on the ones in front of the player seems to do the trick.

Thanks a lot again, I was losing my patience with this ?

17 days later

In 3.2.4beta4 and later, a single mesh resource can be lit by 32 OmniLights and 32 SpotLights at once (instead of 8 in 3.2.3). This limit can be increased in the Project Settings at the cost of performance and shader compilation speeds.

In 4.0's Vulkan renderer, a single mesh resource can be lit by as many lights as you'd like thanks to clustered forward rendering.

I have tried adding a big GIProbe object and bake the lights, but I still have the same problem.

GIProbe only bakes indirect lighting. It's not meant to be a replacement for real-time lights, unlike BakedLightmap which can act as one by using lights with the bake mode set to All instead of Indirect.

9 months later

@TwistedTwigleg said: I'm not sure what is causing the problem per say, but what I would consider doing is turning the spot lights on and off based on their distance from the player/camera. Godot has a limit of 8 active lights per object (OpenGL restriction) in Godot 3.2, so it could be that you are exceeding this limit and that's why the lights do not appear to be working.

I would try attaching an Area node to each of the lights, have the lights disabled by default (visible=false) and then use the body_entered signal to turn the light on (visible=true) and the body_exited signal to turn if off again. Then you can give each of the Area nodes collision shapes that are large enough that the lights turn on when expected, but small enough that they will turn off was the player leaves. This should, hopefully, fix the issue.

thanks this one helped me out.