Devlog · all posts

50 levels of lights, and what they taught me


I wanted a stress test for the lighting audit, so I pointed it at every Unreal sample project, marketplace pack, and open template I could legally get hold of. 50 levels in the end, ranging from City Sample down to a single-room interior.

The audit checks four things, conservatively:

  1. Lights with intensity outside a reasonable range for their type
  2. Lights affecting hidden or unrendered geometry
  3. Orphaned lights — no parent actor, no purpose
  4. Lights duplicated within a tight radius (likely accidental)

Half-expected to see nothing interesting. What came back was more useful than I’d hoped.

The numbers

Across the 50 levels, the audit flagged 1,240 issues. Distributed roughly:

  • 47% intensity drift (lights set 5–250× recommended for their type and range)
  • 22% orphaned lights — most often from BP demolition that left children behind
  • 18% affecting hidden geometry — usually old whiteboxing left in
  • 13% near-duplicates — typically from copy-paste setups during blockout

Three of those numbers don’t surprise me. The intensity drift one does, and it’s the one that costs the most at runtime.

Why intensity drift is the silent killer

When you set a point light to 50,000 candelas because a windowed scene needs to read at midday, then someone scales the room down by a factor of three, the intensity stays. When you copy that light into another room with a different ceiling height, the intensity stays. When the level gets baked, the intensity stays. The result is a project full of lights doing five times the work they need to.

The audit catches this by comparing the intensity to the light’s range and a reference table per light type. A directional light at 50 lumens would get flagged as low. A point light at 80,000 candelas in a 200cm radius is probably an accident.

What I changed in the audit after this run

Two things.

One: the audit now reports a “fix-cost” per issue. Some flags are cheap (delete the orphan, move on). Some are expensive (the intensity is wrong but it’s tied to a hand-tuned art direction that took someone three days). The audit shouldn’t pretend they’re equivalent.

Two: orphan detection got softer. A “child of nothing” is sometimes intentional — a lit prop on a moving train, for instance, where the parent is the level itself. The first version flagged these as bugs. The new version flags them as “review”, which is closer to the truth.

The bit I’m still working on

What I haven’t cracked is baked lighting drift — where the lighting was right when it was baked but the level has changed underneath it since. The bake itself is the source of truth, and the audit can’t tell whether the bake matches the current state without re-baking. I’m experimenting with a hash of the relevant scene state, but it’s brittle. If you’ve solved this elegantly, please email me — I’d rather steal a good idea than spend another week on a bad one.

> audit lights in current level --report fix-cost
✓ scanned 142 lights · 11 issues found
  · BP_Streetlamp_03 — intensity 250× recommended      cost: low
  · DirectionalLight_01 — affecting hidden mesh        cost: low
  · PointLight_19 — orphaned, no actor                 cost: low
  · LightSet_Hero_03 — intensity tuned, scale changed  cost: high (review)

Takeaway for tech artists reading this

If you take one thing from this: run an intensity audit on your project tonight. Even rough thresholds catch the worst offenders, and the worst offenders cost real frame time. PerfectPolaris will do it for free — that audit is in the read-only side of the plugin, no subscription needed.