LibLoad, Linked objects and Lights, looking for examples

LibLoad, Linked objects and Lights. It sounds nice but it seems they don’t mix very well.

I was hoping to build a nice lighting setup where I could assign different lights that should affect different objects to optimize real time performance by baking complex lighting setups and having only selected group of objects cast shadows. There are couple of alternatives for selective lighting such as layers and lighting groups that should enable me to do so but turns out when you have a file structure that involves linking, addObject() and LibLoad the performance is less than ideal.

I thought I have quite a standard plan to my game architecture:

  • There’s a base.blend that adds levels via LibLoad. Mainly contains one empty and overlay scene containing HUD.
  • There are level.blends that has level meshes (mostly linked), colliders, prop objects, lights and game entity spawn points.
  • Characters are in their own .blend files that are added via LibLoad to base.blend. (also tried to add them linked in each level but doesn’t work any better)
    => I need to have lights in the level.blend illuminate linked/LibLoaded meshes in character.blend when everything comes together in base.blend.

What works in terms of selective lighting:

  • lighting groups when light and meshes (or material?) are in the same .blend.
  • “this layer only” when light and meshes are in the same .blend
  • “this layer only” when meshes are linked from different .blend and linked object link is on the same layer as the light

What doesn’t: (tested on 2.71)

A1) Lighting groups when you link object into another .blend. Even if you check “Local” that is specifically there for this functionality doesn’t work in BGE. The object simply receives no lighting from a light that you can see is in it’s lighting group. It works for rendering (F12) and after that also for game until you reload the .blend file so I think there’s some slight hickup.
A2) Lighting groups when you LibLoad. The matching groups aren’t recognized.
B1) “this layer only” when meshes are linked from different .blend and linked object link is on an inactive layer and you use addObject() to bring the object to visible layer.
B2) “This layer only” when you LibLoad. Matching layer in the different .blend files isn’t recognized. In fact only way to get working lights with LibLoad is to have them illuminate everything.

So I’m a bit confused how I should go about this after couple hours trial-and-error. There’s not enough pieces to assemble a selective lighting system in this environment. I can’t place a link to my player and enemies on an active layer, I need to be able to put them on an inactive layer so I can spawn them to certain locations when appropriate.

Did I get some part of what doesn’t work wrong by screwing something on my own?

More importantly I’m asking: Does anyone have a working selective lighting setup in distributed .blend system I could take a look at? I can change some things around in my architecture, I’m still in proof of concept phase (and it’s not looking good :P) but I wouldn’t think it’s too much to ask?

So does anyone have any insight in using lights where you load content from other .blends? Monster, sdfgeoff, SolarLune, goran, kupoman, moguri, plus all the other veterans I forgot, I’m kinda looking at you? :smiley: Do you have a hunch on whether this stuff should work or has some of it perhaps worked in some earlier versions?

EDIT: Finally I find something: https://developer.blender.org/T40086

Low priority? This basically means you can’t use BGE if you want to use lights and don’t want to keep all your content in one .blend. The BGE really needs a working light group system and shading model that supports changes in which lights are present and active.

Dynamic lighting is very important. You don’t need to make fancy UIs for this but just have a function to recompile shader with changed light information (that you can trigger after libloading a new level for example, doesn’t matter if it takes some time) or find a way to read light data somewhere that is exposed and allows changes.

If light groups or “this layer only” is hard to implement I’d be happy to script my own light culling system if this stuff was exposed enough.

Unfortunately I can’t tell about lights.

I know a solution, but don’t have time right now to explain it properly. (Sorry, only read part of the first post before I wrote this)
Pretty much, you have to write a lighting manger for the base.blend. So on a hidden layer in base.blend, have 8 point lights and 8 spot lights without shadows and 4 spotlights with shadows only. Then, on loading the level, replace the lights with empties containing the light information. Finally, every couple of frames, find the closest lights, and substitute them back in. (The shadpw only lights are added to the closest 4 lights as well). If you want to do fancy stuff, have a look at my point-light shadows using wide angle rotating spot lights. You can then also have a graphics setting so people with different spec computers can still play.
It also means the level designer doesn’t need to worry how many lights he’s using.

Unfortunately, I’ve no idea how to adapt this for selective lighting. Because I’ve never used it. What do you want selective lighting for? I honestly can’t see any reason for it to exist.

Bear in mind that the game engine doesn’t know about layers, only active objects, inactive objects, and apparently some lighting stuff. I’m not surprised that when you merge two blends with libload the layer infirmation gets lost.

Would you believe this is exactly what I had as my backup plan? :slight_smile:

Unfortunately, I’ve no idea how to adapt this for selective lighting. Because I’ve never used it. What do you want selective lighting for? I honestly can’t see any reason for it to exist.

I had an idea about that. Since lighting groups are tied to material, I figured if I can keep them in the base.blend where the functioning lights are, maybe it will work. I’ll have to do some testing…

Bear in mind that the game engine doesn’t know about layers, only active objects, inactive objects, and apparently some lighting stuff. I’m not surprised that when you merge two blends with libload the layer infirmation gets lost.

Yes, I was aware of the lack of layers and impending unforeseen consequences adding objects on runtime with libload but then it struck me weird that the lights have “this layer only” option and it seemingly works in some cases. Probably the it is evaluated prior to running the game and passed to the BGE? But then light objects also have this which make things interesting:

KX_LightObject(KX_GameObject)layerThe layer mask that this light affects object on.

[TH]Type:[/TH]
bitfield

How are we supposed to use it in-game? :stuck_out_tongue:

Well that looks promising. It’s a bitfield. Meaning you pass a bunch of bits to it. If it’s a 1, then it will act on the layer represented by that bit. If it’s a zero, then it won’t. No idea how many bits it has or the exact syntax for passing to it. There is also the strong possibiliy it is only used at game engine start-up.

Good luck, you’re outside my field of experience. But I’d love to have a look at your solution when you finish!

I know how to use bitfield. It’s only the fact that BGE doesn’t have layers and you’re able to adjust the light layer mask on runtime that confuses me.

Yeah it’s definitely something I’ll share after looking into it seeing I’m apparently pioneering the field.

Why I “need” selective lighting is because I want to bake lighting (which I hope will be very detailed) in my scenes but still use some simplified lights so that the moving parts receive correct shading. The baked surfaces I can’t set shadeless because I want spot shadows cast on them. But I’m always prepared to downscale if it gets too hard.

I really like the distributed .blend approach although I work alone and I would never go back to single .blend solutions.

Done some testing and I’m much wiser.

For Light Groups in BGE: this is so trivial. The “local” option works by replacing group reference in a material light group with identically named one from current .blend. BUT it does this only when you start rendering. After this the linked material with light group works in BGE like a charm. You won’t be able to save the changed reference since the material is loaded from the source.blend. each time you open the .blend with link. It also causes render preview not working so ideally Blender should do the replacing right after it loads the linked material. Or include the magic switcharoo for BGE initiation as well.

I probably submit this to the tracker since it shouldn’t be that hard to fix compared to how big difference it makes. Light Groups can play important part in optimizing where you can do something like disable shadows for everything else but the player.

Seems like characters can’t be included in the top level base.blend because they don’t receive any lighting from lower level ie. the map.blends. So the rule is that any light and material must be in the same .blend if you LibLoad but provided that they are, full support for “this layer only” and light groups (with the above hiccup) seems to be offered.

For now I’m going to be make temporary local copies for my character materials that I use to override the character materials after linking and hope material light group linking gets fixed ASAP.