Baked Lighting Variation Between Static Meshes

I’m getting very inconsistent baked lighting across different static meshes. If I import the meshes as a single static mesh, the problem disappears. Any idea how to get around this without combining an entire level?

Here is a very simple test scene.

TEST DETAILS:
-Three objects, and one static directional light.
-Objects all have 256x256 lightmaps.

  • Lighting is baked via lightmass with default settings.

  • Example A has two identical static meshes.

  • Example B has the same two meshes, but imported as a single static mesh.

RESULTS:

  • In Example A, the two meshes have obviously different lighting.

  • In Example B, the combined version has very little variation.

Any idea what’s going on here? I’m aware of the “seam” problems that are common with Lightmass, but this appears to be something different.

Should be very easy for anyone else to test this in a similar scene.

These seams are caused by Lightmass processing different objects on different threads. There’s no silver bullet to this, but some things you can do to reduce the impact

  • Plan object seams to happen at corners / edges, not on a flat surface
  • Reduce the smoothing done by lightmass in WorldSettings->Lightmass->IndirectLightingSmoothness. A value of .6 or so can work well. You might also need to jack up the IndirectLightingQuality to 2 or so to compensate for this.

Hi ,

I am currently running into a simmilar issue and found this post (and hope you catch my reply)

The suggestion

somehow largely defeats the concept of having a modular level set where walls are constructed in pieces to allow for variable room sizes with a minimum of static meshes required.

If the problem is thread related (different objects in different threads), cant you not implement the following:

All objects that are grouped are treated as atomic (handled by the same thread as if they were one object).
This way walls, etc could be grouped and the lighting would be correct, without having to combine all the meshes into one…
It would be kind of using the grouping to give the engine a hint on what objects “belong together”…
Just a thought… :slight_smile:

Cheers,
Klaus

Yes that would work. It would require extra user setup to indicate which meshes to light together, and could hurt build times (if you merge everything together), but at least you would have control over the lighting seams, right? BSP actually does this already for co-planar surfaces. Static meshes can be anything so we can’t automatically merge it.

There are some other approaches to this problem that don’t require artist setup but so far none of them seem feasible.

Hi,

Thanks for your reply.

True, the more I group these things, the less “thread-separated” it becomes.
But now Im curious.
Why do different threads produce different results. Since the lighting is static, shouldnt the calculation result in the same numbers every time?
Why can two threads arrive at different solutions for (basically) the same shading task?
I naively compare this to an excel sheet where the result of a cell would depend on which thread calculated it…

Well, not quite. Sometimes I get different lighting on coplanar BSP as well. Especially when the coplanar faces are the result of a subtractive brush.
I dont have the engine or an example at hand atm, but consider the following: Create two roms that consist of hollow box brushes with a wall width of, lets say 20.
Now create a “door” brush box with a 40 width and sink it in. Inside the door, the sides of the two joining walls are lit differently, although coplanar.

Cheers,
Klaus

BSP actually does this already for co-planar surfaces.

Hi,

as I expierienced, not in all cases. (see above)
And even if its good for bsp, in my final level i will be using meshes therer.
its no good to say: Yeah the meshes have inconsistent lighting, but in the build phase with brushes it really looked cool…

Cheers,
Klaus

On the BSP merging, there are some other parameter which can prevent it from merging, for example lightmap resolution.

The algorithm used by Lightmass which reduces build times for diffuse GI by 10x is called Irradiance Caching. As you consider each shading point for whether it needs the expensive lighting computations, you look at surrounding, already-lit shading points and see if you can interpolate from any of them. If not, you compute new lighting at the shading point, which will prevent neighboring points from doing the expensive work too.

So object processed on different threads start from different shading points, and therefore end up with different Irradiance caches and once we interpolate indirect lighting from the cache you get these seams. This is all half-way through Lightmass processing so it’s not easy to ask all the other workers for their finished Irradiance caches and merge them together.

You could try to reduce the smoothing done by lightmass. This is set in WorldSettings->Lightmass->IndirectLightingSmoothness. A value of .6 or so can work well. You may have to increase the IndirectLightingQuality to 2 or so to compensate for this.

Slightly ridiculous potential fix: Building lighting on a single-core machine maybe?

Actually it would be an interesting possibility to add the “single thread only” option to the production lighting quality build, for those who have the extra time to spare. Eliminating seams in return for a huge increase in build time seems like a tradeoff that should be allowed.

Hi,

Or as I suggested, the option to group meshes together that are supposed to be lit together.
Grouping everything would yield the single-thread option…

Cheers,
Klaus

That’s a lot of extra work though, and would probably take several iterations to get it right.

Hi,

I think it would come naturally with structuring the level.
You would use grouping structures anyway to organize the parts of your level.
So, if i already have all segments of a wall grouped (so I can slide the wall more convieniently), then this information could be used to light the wall in one piece.
A current workaround is to make the wall a single mesh and not out of slabs… That is kind of grouping the the geometry level, which is even more inflexible.
Its not as much work as one might assume, or its just me that wouldnt mind a few clicks per room to make the lighting look good.:stuck_out_tongue:

Cheers,
Klaus

Sorry for bumping this old post but I’m wondering if there is a proper fix for these issues already?

Hi Madmenyo,

This proper fix is to use the methods that has mentioned above.

Adjusting the Indirect Lighting Smoothness and Quality will help in this regard.

The alternatives are to import as a single object or use other pieces of geometry to cover the edge seams.

You can also take a look at this thread here: Modular Asset Lighting Problem - Rendering - Epic Developer Community Forums

In the next week or two this will be covered on the Wiki guide that Eric and I have setup here: A new, community-hosted Unreal Engine Wiki - Announcements - Epic Developer Community Forums

I’m in the process of getting this setup and finalized in a more formal manner than the forum thread above.

Hello everyone!
Aside from all the fixes already discussed here, one of the main culprits of this kind of artifact is lightmap misalignment
make sure all your maps for the lightmap are correct aligned to the grid

see this page for a lot of fixes for common problems with light leaking/seams on static meshes, it mainly involves how the lightmaps are made

hope this helps!

Although that only works with rectangular meshes

Wouldn’t it be possible to program a system that has a shared irradiance cache across worker threads?

I would also like the option with the grouped meshes :slight_smile: I like the idea of having artist control over it and yes…it will be extra work, but it also allows for a lot of freedom. Automatic tools are not always leading to good results and yeah…I personally prefer a bit of fine control :slight_smile: Also, it sounds kind of weird to combine everything into one group anyways, so I wouldnt fear that to much. Or maybe make a special group that is called lighting group or so. It doesnt actually group the objects, it only groups them for lightmass. You could also have a visualization mode for this so stuff can be easily debugged.

just my 2 cents^^…cheers!