
Performance Audit
A measured optimisation pass on a scene I did not author: 30.45 → 22.60 ms GPU frame time at native 1440p, with the method and the missed target reported in full.
Personal project
The scene shipped lit exactly one way: baked, static, night. Making it a second time of day was not a slider — it was a second bake. So I removed the bake entirely and replaced it with a system.
Ownership: Personal project, worked on alone. The environment is “Dreamscape: Stylized Environment Tower” by Polyart Studio (Fab), used as-is — the models, materials and level layout are theirs, not mine, and this is not presented as my environment work. What is mine is the conversion from baked to dynamic lighting, the C++ Time of Day system, both lighting presets, and the optimisation described below.

Assets: The environment is “Dreamscape: Stylized Environment Tower” by Polyart Studio (Fab), used as-is — models, materials and level layout are theirs. The lighting conversion, the C++ system, both presets and the optimisation are mine.
The level arrived fully baked: 1.1 GB of lightmap data, a Static directional light at 1 lux, and a Post Process Volume that explicitly forced Lumen global illumination and reflections to None. The project was also running DX11 with Shader Model 5, so Lumen and Virtual Shadow Maps were not merely disabled — they were unavailable.
That rules out the obvious approach. You cannot brighten a baked night into a day, because every bounce you can see is stored in a lightmap that was solved for one sun position. A day version means a second bake, and a second bake means every subsequent tweak costs hours.
I moved the project to DX12 / SM6 and enabled Virtual Shadow Maps, then set the sun, the sky light and all 49 local lights to Movable, with the sky light on Real-Time Capture. The 1.1 GB of built lighting data had to leave the content directory entirely: with the sun Movable it no longer contributes, but Unreal will still apply the stale baked night on top of Lumen if the file is present.
I chose software Lumen over hardware ray tracing. Switching to DX12 would have silently activated the project’s dormant ray-tracing flags across every level, and the target here was a playable frame budget on a mid-range GPU, not a maximum-quality still.
The important constraint was blast radius. This project contains around thirty other levels that are still baked, so Lumen is enabled only on this one, through its own Post Process Volume overrides, rather than by flipping the project-wide default. Nothing else in the project changed appearance.
The controller is a C++ actor holding two instances of one struct. A preset describes an entire look: sun angle, colour, intensity and volumetric scattering; sky intensity and colour; height fog and volumetric fog; the post-process grade; multipliers for the level’s local lamps; and which particle systems are visible.
Apply Day and Apply Night are exposed as editor buttons, so the viewport updates live while you tune, and the same code path runs at runtime. Because a look is data rather than a saved level state, blending between the two is a lerp across the struct.
One design detail mattered more than it looks. The local lamp multipliers scale relative to a saved record of what is already applied, not to a sampled baseline. The first version sampled live intensities on load — which meant every reload treated the already-scaled values as the new baseline, and the multiplier compounded silently. The lamps had reached 2.7× their authored brightness before I caught it.
The pack’s candle Blueprint carries a point light with dynamic shadows enabled. That is invisible in a baked scene and ruinous in a dynamic one: 132 candle instances meant 132 shadow-casting lights, each of them a 10-lumen source with a 200 cm radius — the kind of light whose shadows nobody will ever see.
Turning shadows off on that one component took the level from 143 dynamic shadow casters to 11. I applied it as a per-instance override rather than editing the shared Blueprint, because other levels in the project use the same asset and none of them asked for a lighting change.
Renders came out white while the viewport looked correct. The editor viewport applies physical camera exposure — f/4, 1/60 s, ISO 100, about 9.9 EV of it — and Movie Render Queue does not. Every value I had tuned by eye in the viewport was roughly ten stops too bright when rendered. Pinning that setting off in both paths and re-baselining the exposure bias closed the gap. I was wrong twice before I found it.
Volumetric fog effectively only exists at Cinematic scalability. Movie Render Queue forces Cinematic through its Game Override settings, so fog I had tuned in a default viewport — where volumetric fog is quietly off — rendered as an opaque white-out. It was around seventy-five times too dense. Fog tuning now happens with the viewport pinned to Cinematic, which is the only way what you see matches what renders.
The blend flashed magenta at its midpoint. Interpolating light colour with Unreal’s HSV lerp takes the long way round the hue wheel between a warm sun and a cool moon, and passes straight through magenta on the way. Linear RGB fixed it, and the midpoint now reads as a believable dusk.
Breakdown
What the night preset is built around. The brightest, highest-contrast point in the frame is also the narrative focal point, which is why the door needs no signposting — and why the lamp multipliers rise at night rather than the sun.
Demonstration
Two opposed lights orbiting a single form. The warm key reads as the door lamps, the cool fill as moonlight — the split the night preset is built around, and the one the day preset inverts.
Shown as a live 3D view on larger screens with motion enabled.
Gallery





Next

A measured optimisation pass on a scene I did not author: 30.45 → 22.60 ms GPU frame time at native 1440p, with the method and the missed target reported in full.

An Unreal Engine 5 master material driven by ID masks, so one mesh can swap between wood, painted metal and emissive trim without leaving the engine.

A large-scale sci-fi hangar built from a custom modular kit, lit with Lumen and textured almost entirely from a single trim sheet.