How Game Engines Decide Which Volumetric Light Beams to Fake Versus Partially Calculate
You're standing in a cathedral level. Dust motes drift through a shaft of gold light cutting down from a broken stained-glass window. It looks stunning. It feels physical. Almost none of it is real.
That beam didn't bounce off actual particles. The engine didn't simulate photons scattering through medieval stonework. What it did is considerably stranger and, honestly, more impressive: it made a very fast, very specific decision about how little physics it could get away with while still fooling your visual cortex completely.
This is the central problem of volumetric lighting in real-time graphics. Full physical simulation is too expensive for interactive framerates. Pure fakery looks flat the moment anything in the scene moves. So every major engine sits somewhere on a spectrum between the two, and the logic that determines where is worth understanding.
The cost of doing it honestly
Light scattering through a medium, whether fog, smoke, or dusty air, is called participating media rendering. Done rigorously, it involves ray marching: casting rays from the camera into the scene, sampling the density of the medium at dozens of points along each ray, checking whether each sample point can see the light source, and accumulating the result. For a single 1080p frame, that's potentially millions of sample evaluations per light, per frame, at 60 frames per second.
Even on modern hardware, running full ray-marched volumetrics for every light in a complex scene would tank framerates into single digits.
So engines don't.
What they do instead is a tiered system. The tier a given light beam lands on depends on four factors: the light's screen-space footprint, its distance from the camera, whether it's the dominant light in the scene, and whether it's casting a shadow that a player might actually notice cutting through.
The fast lane: post-process god rays
For most beams most of the time, the answer is a post-process screen-space trick called radial blur, or in more polished implementations, screen-space light shafts. The engine renders the scene normally, then identifies pixels where the light source is visible, then blurs those pixels radially outward from the light's screen position in a series of passes that smear bright areas away from their source like ink bleeding through wet paper.
The result looks convincingly like scattered light. It costs almost nothing by comparison. And it falls apart completely the moment an object passes between the camera and the light, because the effect is purely a 2D image operation with no knowledge of scene depth.
Unreal Engine's legacy light shaft system works this way. So does the basic volumetric fog in Unity's built-in pipeline. Fast, cheap, good enough for a sun on the horizon or a streetlamp in the distance. The visual artifact is that these beams exist only from the camera's perspective: walk around the light source, and the shaft rotates with your view, not with the geometry.
The middle tier: half-resolution ray marching
When a light actually matters, when it's the key light in a room the player spends twenty minutes in, engines step up to actual ray marching. Just hobbled on purpose.
The standard approach is to run the volumetric pass at quarter resolution (half in each dimension) and reconstruct the full-resolution result using temporal reprojection. Each frame, you use the previous frame's samples plus a jittered sample pattern to fill in gaps. Over four to eight frames, you accumulate a full volumetric picture.
This is how Unreal Engine 5's volumetric fog works by default. It allocates a 3D texture (a voxel grid) over the camera frustum, typically 200 froxels deep and around 160x90 in screen coverage, each froxel representing a small volume of space. For each froxel, it calculates how much light reaches it from each participating light source, accounting for shadows. Then it ray marches through that grid at render time.
The critical constraint is the froxel grid's depth range. By default, UE5's volumetrics only calculate accurately out to about 6,000 units from the camera. Beyond that, you get falloff or nothing. This is a deliberate budget decision, not a limitation anyone forgot to fix.
Here's a concrete example of that logic at work. A developer ships a dungeon level with a single dramatic torch near a barred window. The torch is the dominant light, it's within three meters of the player, and the light shafts through the bars are a designed moment. The engine assigns that light full froxel-grid participation. The ambient fill lights on the ceiling get the screen-space pass. The player never notices the inconsistency, because they're looking at the bars.
The real decision logic: what engines actually check
The decision tree, simplified, goes like this.
Is the light a directional light (sun, moon)? Directional lights almost always get the dedicated volumetric path because they affect the entire scene and the cost is amortized across all geometry. Unreal, Unity HDRP, and id Tech 7 all special-case directional lights this way.
Is the light within the volumetric fog bounds? If a point light or spot light sits outside the froxel grid range, it simply doesn't participate in volumetric calculations. It gets the screen-space pass or nothing.
Does the light cast shadows? Shadow-casting lights are vastly more expensive in volumetrics because each froxel sample has to do a shadow lookup. Engines cap the number of shadow-casting lights that participate in the volumetric pass. Unreal's default cap is four. The fifth shadow-casting light you add carelessly gets silently excluded from volumetrics, with no warning, no flag, nothing.
What's the light's intensity relative to scene exposure? Very dim lights don't contribute visibly to volumetric scattering. Engines apply a contribution threshold and skip the calculation entirely if a light falls below it. This is why a candle three rooms away doesn't generate a god ray even if it theoretically should.
What people consistently misread here
The common assumption is that better hardware means more physically accurate volumetrics. It mostly means more of the same tricks running at higher resolution with less temporal ghosting. That's not a cynical observation, it's just how the field has moved, and I think it's the right call.
Path tracing, which is showing up in games with hardware ray tracing support, does handle volumetrics more honestly. But even path-traced implementations in current games use denoising and temporal accumulation so aggressively that they're still a statistical approximation, just a much better-sampled one. The line between "faked" and "calculated" is blurry by design: the goal was never physical accuracy, it was perceptual accuracy.
The other thing that trips people up is conflating the beam itself with the particles inside it. Visible dust motes, the kind that drift and swirl, are almost always a separate CPU or GPU particle simulation layered on top of the volumetric pass. The beam is one system. The motes are another. They look unified because both respond to the same light position, but the engine is running two entirely separate budgets to produce that cathedral moment.
Turning the knob yourself
If you work in a game engine, the volumetric quality settings in your project aren't abstract sliders. Each one maps to a concrete budget.
In Unreal Engine 5, the console variable `r.VolumetricFog.GridPixelSize` controls froxel density. The default of 8 means one froxel per 8x8 pixel block. Drop it to 4 and you double the sample count in each dimension, quadrupling the cost. `r.VolumetricFog.GridSizeZ` controls depth resolution, default 128 slices. These two numbers are where most of your volumetric budget lives.
In Unity HDRP, the Fog volume component exposes "Volumetric Fog Budget" directly, and the "Screen Resolution Percentage" slider is the half-resolution switch described above. Set it to 100% and you're doing full-resolution ray marching. Your framerate will tell you immediately whether your target hardware agrees with that decision.
Ask yourself: if your fog budget is below 50% and you're still hitting your target framerate, why are you leaving that headroom untouched? Most projects ship with the defaults and never look back.
The cathedral beam that caught your eye in a trailer wasn't an accident of good hardware. Someone made a specific technical choice to spend the volumetric budget on exactly that moment, and let the rest of the scene run on two-dollar screen-space tricks. That's not cheating. That's direction, and it's a better skill than knowing the physics.