Light object can be spawned once only ?!

In my game (The Lost Relic) I have a lot of lanterns to lighting the dungeons and after testing an alpha version, someone has suggested me to spawn light only near the player because the game is lagging too much.

So… during optimizing my game by making different tests I discovered that if you spawn a light object, it can be spawned only one time so I don’t have to make a script for spawn/unspawn/respawn for light… only a Near sensor and addObject actuator to spawn the lantern light near the player :slight_smile:

I mean, if you spawn the same light in another place, the previous instance is automaticly destroyed.

It works very well and the game is really much more fluid, but I wonder if it’s a good technic or if it’s a bad hack to do that (or a bug in the 2.77 version of Blender) ?

dynamic lighting manager is what you are looking for

you can only have 1 instance per lamp in forward rendering, and each lamp decrease performance

so use a dynamic lighting manager to shift the same X lamps between a stored list of lamp hooks,

spawning a new instance, does not remove the game object of the lamp,
it only produces light with the new lamp, the old one does still exist, but does not produce light*

Dear BluePrintRandom,

Thanks for your answer but maybe it’s because my English is not good enought or maybe because I’m a noob, I don’t really understand what you mean.

Anyway, you mean it’s ok to do what I’m doing in my game (about performance) ?

:cool:

Maybe I have to look for this famous dynamic lighting manager… ?

I use a kdtree, to populate the closest X lamp hooks with lamps

its very fast.

http://www.pasteall.org/blend/42405

note: this generates a maze on frame 0 so it takes a moment to fire up :smiley:

also note - this uses a kdtree for physics and for dynamic lighting manager :stuck_out_tongue:

Wow… too hard for me, actually. But thank you very much for your help. I will study that later. :slight_smile:

Why does this happen:
Lights are compiled into the shader for each material. Compiling the shaders is quite time consuming (and I believe has a memory leak as well, though I can’t prove it), so it is done in only a few situations:

  • Starting the game
  • Adding new scenes
  • Libloading in external resources

In all other cases, only the most recent location for the light is used although the light objects in other places still exist, and if the new light may return to one of the previous positions. It would be better to remove the old lights. You could do this by when the near sensor triggers, sending out a ‘kill’ message to all other lights.

The solution
What I do when I need lots of ights is to have some sort of lighting manager. It has some number of lights (eg 10), and moves them between all the places light can be as they are required. You can go as simple or as complex as you like. Near sensors and end sensors work, but you’ll find that near sensors are rather expensive when you have lots of them. In previous lighting managers, I’ve used shadow-only lights to create the illusion of point light shadows:

In that video there are something like 5 point lights and 2 shadow lights moved around dynamically and faded in/out

Very interesting, thanks to all of you.

@sdfgeoff

How did you make the shadows fade in? Did you animate some values?
Also are you using near sensors on every point where a light can exist or something like a kdtree?

I am using obj.getDistanceTo(scene.active_camera).
Seriously, unless you are doing thousands of lookups from static locations, the performance gain from a kdtree is negligible. (BPR likes things with fancy names, like barycentric transforms, kd-trees, bvh-thingamies. They often aren’t the best way)
But near sensors will be incredibly slow when you get more than 5-10 of them, depending on CPU hardware. They also require the objects to be physics objects, which doesn’t really make semantic sense for a light.

I fade them in using the lamp energy. Because there is a separate lamp for the shadow (a shadow only spot light), I can fade the shadow separately to the actual light.

The process goes something like:

Init
0a) Libload required number of lights from an external blend (because lamps on a hidden layer are still processed, but not shown)
0b) Libload level (Has to come after 0a so that the shaders are compiled with the previously libloaded lights
0b) Libload player and other props as the level requires

You can skip this if you are happy with a set number of lights (ie not being able to have a settings menu with a graphical quality slider)

Every few frames

  1. For all unused lights, find the best place to put a light that isn’t already lit. Put it there with energy=0
  2. For all lights:
    -----if energy < target_location_energy, increase energy
    -----For all lights, if no_longer_best_location, decrease energy
    -----If energy == 0, mark light as unused
  3. Repeat above for shadows

I use a kdtree, because I have no idea how big my game world will be, and I don’t want to rewrite it in the future, and it’s not like it cost money… its free.

and the getObjectDistance thing per frame can get brutal, not on getting the distance, but when you sort a very large list it’s cpu heavy.

https://wiki.python.org/moin/TimeComplexity
sort takes exponentially more time the longer the list.
and I would personally use kd tree method for static objects, and something like what sdfgeoff used for dynamic actors that are inside a cull range

@bpr:
Have you ever tried to see how many it will take to hit any kind of performance barrier with sorting lists? Particularly because … you don’t need to sort them in this case, you only need to extract the lowest ‘n’ values, which is less computation.
Have you analysed the cost of building a KD tree? How do you deal with moving lights (eg on trains)? etc. etc.

How to find lowest values in a list:


light_locations = [(dist, obj), (dist, obj),....]
best_locations = []
for i in range(num_lights):
    next_best = min(light_locations)
    best_locations.append(next_best)
    light_locations.remove(next_best)

I’d actually like to do a performance comparison of several methods some day.

I also score lights not only on distance. The player view angle is a good one to include, as is the light intensity and radius. In one manager I wrote, I calculate the approximate light energy at the player location. If you’re doing that though, make sure the computation you do for each light doesn’t outweigh the performance gain of not having said light.

@sdfgeoff

Thanks for the explanation!
I didn’t know lights on the hidden layer are still processed so that’s a new. Haven’t really gotten my feet wet with libloading, guess I’ll have to try it out.

Thanks.

I have many systems competing for cpu cycles,
like the component logic mind, and the compound dynamic armature physics systems, and lamp LOD that are all actually going to be 1 module, with dictionary of function calls.

so, I am using the kdtree and dynamic entity lists for a bunch of overlaping tasks.

I am actually thinking of using a grid of many small kd trees and when the root of the kdtree is out of range, ‘collapse’ the tree back into saved data.

and have some method to dynamically load the tree structures.
however most game objects will be duplicates of the same 36 objects.

also, for a* etc, its quite easy to get the closest N navigation tiles.