Graphics/3DMar–Apr 2026
Passenger
A cinematic Unreal Engine 5 short: a canyon, a train swallowed by roots, and hand-written painterly shaders that make real-time frames feel oil-painted.
Overview
Passenger crosses a canyon of sandstone walls scorched by a sun that has done this ten million times before. At the canyon's edge he finds a train, stopped long enough ago that birch trees have grown up through the floor, vines have claimed the grab rails, and wildflowers cover what was once the aisle. Inside, an apple — still quiet. He picks it up, and the world opens somewhere else.
Built entirely in Unreal Engine 5, with character rigging and animation from Maya. The two environments, a sun-scorched Utah canyon and an overgrown subway car, share one lighting approach: real-time global illumination grounds each scene in believable light before the stylized shaders go on top.
Scene 01 · Canyon
Building a Utah canyon in Unreal Engine 5
The canyon is assembled from Megascans photogrammetry (high-resolution rock faces and desert scatter), arranged to feel like it had always been there: no obvious tiling, no floating rocks, a sense of geological weight.
Lumen global illumination handles the bounce that wraps into the walls from the sun angle. As the virtual sun nears the horizon, Lumen re-solves the GI in real time: deep amber shadow on one side, burnt orange on the lit face. No baking, no lightmaps; the lighting reacts as the camera moves.
Lighting studies
Scene 02 · The train
A subway car swallowed by a decade of growth
The train is built on a modular NYC-style kit (car shells, doors, ceiling marquees, grab rails), then stripped of every sign of function. Birch trees push through the floor, hornbeam foliage fills the door frames, meadow grass covers the aisle, vines loop the rails. The LED marquee still cycles “DELAYS AHEAD” — but there are no delays, because there is no train anymore.
All of the interior light comes from the sky through the broken canopy above. Lumen computes the soft, diffuse fill of overcast light filtering through leaves, with thin god rays catching mist scattered through the volume.
The train
Shaders
Hand-written post-process for a painterly look
The signature look is a custom anisotropic Kuwahara line shader: a Sobel operator detects the local edge gradient and its direction, which rotates four sampling quadrants to align with surface features. Each quadrant's mean and variance are computed, and the mean of the lowest-variance quadrant is returned, so flat areas resolve into coherent oil-paint patches while edges stay sharp. It's parameterised by brush radius, painterliness, and line thickness.
A second toon/cell pass samples BaseColor from the GBuffer and quantises the scene into tonal bands with separate shadow/highlight tints. Both materials read real GBuffer channels (BaseColor, WorldNormal, SceneDepth) through SceneTexture nodes, so the stylisation responds to actual geometry, not just the final pixel.
Cell shader · off / on
Technical breakdown
GBuffer passes: what the renderer sees
Unreal's Movie Render Pipeline can output individual GBuffer passes alongside the final composite, showing how the deferred renderer decomposes the scene before lighting. I used them to validate material authoring and debug the post-process shaders.
GBuffer
Maya pipeline
The stylised low-poly passenger was modelled, rigged, textured, and animated in Maya. The rig uses IK limb chains, a spline-IK spine, and foot orient constraints, driven by NURBS control curves. Core cycles (idle, walk, jump, sit, push-up, pickup) export as FBX clips into an Unreal Animation Blueprint that blends between them with a locomotion blend space and procedural secondary motion.
Character
Maya rig
Render
The film renders through Unreal's Movie Render Pipeline rather than a viewport capture. Temporal Super Resolution accumulated over 64 samples per frame kills real-time shimmer, output at 2560×1080 (2.4:1) to push the eye wide, with hardware ray tracing for reflections and shadows over Lumen GI.
Reflection
Writing the shaders by hand, rather than reaching for a plugin, is what made the look feel like mine, and reading the GBuffer directly taught me more about the deferred pipeline than any tutorial. The lesson that stuck: a real-time engine gives you a filmmaker's iteration speed, but only if you understand what it's actually computing each frame.
Outcome