
Time of Day: Runtime Day/Night Lighting System
A baked, night-only Unreal scene rebuilt as a fully dynamic Lumen environment, with a C++ controller that switches or blends between two complete lighting looks at runtime.
Personal project
A technical-art study in removing the re-bake from the iteration loop — built so an artist can retexture an asset with a dropdown instead of a round trip to Substance.
Ownership: Personal technical study. The master material, the layer set, the ID-mask logic and the exposed parameter interface are entirely my own work.

Assets: Material graph and layer set authored by me.
The default way to change how an asset looks is to go back to Substance 3D Painter, re-texture, re-bake and re-import. That is a slow loop, and it gets slower the more assets share a look, because a single art-direction change fans out across every texture set in the environment.
It is also expensive at runtime. Unique texture sets per asset is the single easiest way to spend a memory budget without meaning to.
So the goal was a system where colour and material changes happen in-engine, in seconds, and where a whole environment shares a small number of textures.
The system is built around one master material that blends several material layers — base wood grains, painted metals, emissive trims — all resolved inside a single material instance.
Working in layers rather than in a monolithic graph means each surface type is authored once and reused everywhere. Adding a new surface to the environment is adding a layer, not rewriting a shader.
The part that makes it useful is the ID map. A mask texture assigns different material properties to specific regions of a mesh, so I can address "the handle" or "the panel" independently inside one material.
That is what allows a wood layer to be swapped for a metal layer instantly, with no re-bake and no leaving the engine. The mesh does not change; the mask tells the shader which layer belongs where.
A system nobody else can drive is not a system. I exposed the parameters that actually get adjusted in practice: colour tint, roughness and metallic scalars, and static switches for optional features like surface wear.
Static switches matter specifically because they compile out. An artist gets the flexibility of an optional wear pass, and assets that do not use it do not pay for it in shader complexity.
The optimisation argument is straightforward: this approach significantly reduces the number of unique texture sets a scene needs. Shared tiling textures plus channel-packed masks carry the detail, so high-fidelity results come with a much smaller memory footprint.
I have not published percentage figures for the saving, because I have not measured it under controlled conditions — the honest claim is the structural one, not a number.
Breakdown
The mask and the layer set both feed the master material; the instance exposes only the parameters worth adjusting. The mesh never changes — the assignment does.
Demonstration
The same geometry cycling through wood, painted metal and emissive trim. Nothing about the mesh changes between states — only which material layer the mask assigns to it.
Shown as a live 3D view on larger screens with motion enabled.
Gallery







Next

A baked, night-only Unreal scene rebuilt as a fully dynamic Lumen environment, with a C++ controller that switches or blends between two complete lighting looks at runtime.

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.

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