Unreal take on Loft.

The default Lightmass settings error on the side of reasonable build times, but relying on a fair amount of smoothing to hide noise. As you said, this destroys indirect shadows. We intend archvis users who want maximum quality to lower IndirectLightingSmoothness (.6 to .8) while simultaneously jacking up the quality with IndirectLightingQuality (4-10). This will increase build times a lot, but you get your indirect shadows back. Also make sure you disable lightmap compression and have sufficient resolution + good unwrap (generic requirements for anything lightmap quality related).

Unfortunately it’s quite difficult to implement variable quality in this way. There would be seams at the edges of the volumes. In general, we try to make algorithms that automatically detect where more work is needed instead of making it a manual process. Some examples of this are photon mapping (which tracks where photons successfully bounced and emits more there, instead of requiring you to setup ‘portals’), irradiance caching, and importance sampled final gathering.

Different lightmass settings per volume is also difficult to implement, you’d have to know where you were in the world before querying settings. The direction we want to go in is algorithms that ‘just work’, rather than overcoming flaws by giving you manual control.

The problem with supporting exporting is that the lightmaps are in a special format which can’t be directly modified. It stores directional color, as well as other attributes like sky shadowing. These are required to implement various features like directional lightmapping + stationary skylights (where you can swap the cubemap at runtime).

This is the C++ class to demonstrate. Primary lighting is in a spherical harmonic which has negative floats - you can’t edit that in a meaningful way.

class FGatheredLightSample
{
public:

/** World space incident lighting. */
FSHVectorRGB2 SHVector;

/** Incident lighting including dot(N, L) where N is the smoothed vertex normal. */
FLinearColor IncidentLighting;

/** Correction factor to force SH as applied to a flat normal map to be 1 to get purely directional data. */
float SHCorrection;

/** Sky bent normal, points toward the most unoccluded direction, and the length is the visibility amount (0 = occluded, 1 = visible). */
FVector SkyOcclusion;

float AOMaterialMask;