Download

Level streaming lighting issue

We’re trying to make a procedurally generated level using level streaming. The level consists of sublevels (rooms) which are spawned into level using level instances. When a room is spawned it’s transformed.
The lights are stationary.
The walls in rooms are static, but it doesn’t work with movable either.


Room after Build but before being transformed in Persistent level looks fine

After levels are spawned, the lighmaps on objects in room seem to break. The indirect lighting cache doesn’t work either. The shadows on movable objects is too dark (indirect lighting doesn’t work)

The lighting breaks differently depending on room rotation

Is there a possibility to make all the lighting work right?

If an engine dev or expert could give advice here that would be super helpful to both of us.

I’m working on the exact same problem and I have to say, it’s pretty difficult. I’m pretty sure I’ve figured out all the things I need to do to make the lighting work properly, but it’s a lot of learning. I found these major problems with lighting in instanced levels.

Rotation of lightmap SH:
This isn’t super easy to fix, but I can see two potential solutions. One is to change lightmass to bake SH in the meshes local space rotation instead of global, and rotate the SH sample vector in the shader since we usually always have the local space uniform available (right?). I don’t know where to implement the change in lightmass though. Other solution is to accept lower quality lightmaps and reduce the 2nd order SH to a 1st order SH which doesn’t depend on rotation. I think UE4 already has low quality lightmaps like this as an option but I don’t know exactly how to make it work.

Indirect lighting cache transform and resulting sampled SH rotation:
This one isn’t so bad I don’t think. If I add a transform matrix member to the Indirect lighting cache object I can transform any sample locations into the “lighting cache space” and sample that location, then inverse rotate the sampled SH coefficients back into global space. Don’t have to change anything in the shaders for this but it does add a bit more CPU load. The upside is that the level transform won’t change so we can precompute the 2nd order SH rotation matrix to speed up sampling. I could instead maybe duplicate the actual lighting cache data for each instance and pre-rotate all the SH, trading memory for speed. Since I happen to only need 90 degree rotations on Z, I’m hoping that it will be easier to implement the actual math though I am still way out of my depth here.

Reflection probe rotation:
This one seems rather simple for rectangular probes, it’s a one line change to the shaders sample function which rotates the sample vector into the probes local space, making the reflection environment rotate with the actual reflection probe component. For spherical probes it’s a bit harder because I need the component rotation in order to transform the sample vector. Problem is I don’t know how or where to retrieve that value and pass it as a uniform into the shaders.

Also you’ll find that BSP meshes don’t work properly, but that’s not a big deal and it’s easy to fix (see how the world composition streaming does it). I haven’t even researched how this effects navmeshes yet but I’m sure it’s going to be full of problems as well.

So I’m working on a solution that I might be able to share with you, but I still need guidance from an engine dev or some other expert on the best course of action here.

1 Like

Same issue for me, waiting to see how we can solve this.

  • think im having the same issues? When I steam in and out of a level, it turns some meshes black, but I have a light right in front of the door and it still turns black unless I stream the level behind it*

I have the same issue.

I have 3 sub-level using blueprint to turn ShouldBeVisible on/off
I created a vase in sub-level-A, it looks normal (white)

Then I turn sub-level-A ShouldBeVisible false and turn sub-level-B ShouldBeVisible true.
Then I switch back sub-level-A ShouldBeVisible to true and sub-level-B ShouldBeVisible to false, my vase in sub-level-A becomes dark(Black)
Have no idea…:frowning:

It’s now 2021 and I’m having this same issue and can’t seem to find a fix. I have loads of sub-levels and every one of them is dark on moveable objects and blueprint actors. what in the world is going on??

I’ve got the same issue as well. Can anyone please help with this?

I am not an expert, however volumetric lightmaps do not play nice with level streaming, so use sparse volume lighting samples or hack a solution in.

Looking into this same topic right now. @The_Beej was on the right track as I’m finding the same information.

I can live without reflections in my scene. I just need the static light and the volumetric light for the moveable actors. The volumetric seems to be simple enough to fix since it’s a group of probes that you can rotate. Indirect lighting cachevolumetric lightmap notes - Gamedev Guide (bebylon.dev)

No idea about static lighting yet, haven’t looked into what kind of data that even is. I imagine a generated texture or something.

honestly I’m not sure why this isn’t natively handled by the engine. This seems like something that should be in there already since you can make instances. When loading levels there’s functions for each step of the process that can be overridden or broadcast out like this one FLevelUtils::ApplyLevelTransform() and the volumetric lighting data even has functions built in for transforming it GetLevel()->PrecomputedLightVolume->ApplyWorldOffset(GetActorLocation());. So beats the hell out of me why this thought process was never finished by Epic.

Anyway, since there’s things in there you piggy back off of it’s got to be possible to manipulate this data.

In my case I only ever have a few rooms loaded at a time so not too worried about memory if I need to stash a cached copy of the transformed data somewhere. I just don’t know what to do about the static lighting yet. Please please please if someone figured it out, let me know.

Had same problem and fixed it pretty easily. I got only one lighting scenario so not sure whether it will work with lights on different scenes. I solved it by making completely new empty level - persistent one. Then I attached my rooms to this empty level and I steam it from there. All lights and reflection probes are on another lighting scenario level. Now when I stream/unstream levels lights does not change at all.

my issue probably wouldn’t work with that since it’s about spawning instances at different rotations etc. The fact they are instances will already screw up lighting as both instances will try to fetch light info from the same place and they are likely facing different directions. Other issue being that the current (new as of like 2016) volumetric light info is store in world space, not relative to the placement of that level so it will always be in the wrong spot if you’re spawning that level in a location that the lighting wasn’t baked at.

I have a pretty good idea of how to solve the issue in the engine, but it sounded like too much a pain to manually memory manage and stitch and blah blah all the incoming light map stuff so I opted for lighting my scene via unlit materials with a fake light system via custom data and vertex color.