27
\$\begingroup\$

In some games, I see lights shining through walls, even if I set video quality on high levels.

A couple of examples of games I recently played are Borderlands 2 (missile explosions) and Call of Cthulhu (lanterns; the game even uses Unreal Engine 4).

Is this a bug or there are performance reasons?

Example Borderlands 2: https://youtu.be/9bV83qA6_mU?t=419 (few times, but quickly)

Bonus question: in the latter case, is there any way ray tracing could be cheaply used to solve the problem? I guess that expensive RT definitely solved the problem, but I wonder if it can also be used in a "cheap" form to solve this specific problem.

\$\endgroup\$
  • 21
    \$\begingroup\$ A picture is worth 1000 words. \$\endgroup\$ – Evorlor Jun 21 at 3:18
  • 8
    \$\begingroup\$ I'd have to go play to test, but is it actually light that's leaking through, or might it be a glowing particle effect? Particularly your example of a missile explosion, I could imagine an additive "fire" particle effect which is quite likely to ignore collisions. Lanterns could also do the same to create a visible halo, I suppose... \$\endgroup\$ – A C Jun 21 at 4:21
  • \$\begingroup\$ @Evorlor added one example. \$\endgroup\$ – Marcus Jun 26 at 12:40
43
\$\begingroup\$

Expanding on TomTsagk's correct answer, I thought it might help to describe a bit more about why games work like this.

Light in games doesn't really "travel" from the source, to the surface, to the camera, getting obstructed along the way.

To figure out how bright to draw each pixel of a surface based on a given light, we use (or approximate) a math formula that uses the facing direction of the surface and the direction from this point on the surface to the light source. That's it, just the direction it's shining from — we don't typically cast a ray to check if the light actually reaches this pixel, because doing that for every pixel on the screen and checking the ray against all the detailed geometry in the scene is usually still too expensive for realtime games.

So, by default, no game lights cast shadows. The direction to a light stays the same even if there's a shadowcaster in the way, so the math gives us the same brightness value.

If we want to simulate shadows, we have to do that separately. One common way is with what's called a Shadow Map. In this version, before we shade our scene, we first render the scene from the perspective of each light, as though that light were a camera, storing the depth of each pixel it sees into an off-screen texture.

Then, when we shade the scene, we can compare the mathematical distance of this pixel from the light source vs the depth we recorded at the corresponding pixel in the shadow map. If the shadow map depth is smaller, then it means there's another surface between here and the light, and we draw this pixel in shadow instead.

There's a whole lot of cool techniques to make these map-based shadows look nicer, with fewer artifacts/aliasing, but I'll gloss over them for now. Suffice it to say, they're generally not free either.

Because this requires rendering (up to) the whole scene again from each light's perspective — up to six times if it's a point light that shines in all directions {north, south, east, west, up, down}, and we need to re-render the shadow map anytime something moves, this can get very expensive.

So games will often focus their rendering budget on the most important lights in the scene — like the directional sun light — to ensure they have good-looking shadows. Small, short-lived, minor lights like the flash of an explosion are often forgivable if they leak past occluders a little. Often this is more palatable to players than a hitch in the framerate due to a sudden increase in rendering cost from all the extra shadow map rendering and calculation. Especially if it's a busy action scene where fluidity matters more than pixel perfection.

\$\endgroup\$
  • 2
    \$\begingroup\$ Another wrinkle is that while it's trivial to figure out whether a light source is in front of or behind a surface, preventing surfaces from glowing when lit from behind will often yield weird looking results. \$\endgroup\$ – supercat Jun 20 at 19:21
  • \$\begingroup\$ And this is especially true with particle effects (which the explosion probably is, at least partially), since particles need to be especially cheap to handle to be very useful. \$\endgroup\$ – Luaan Jun 21 at 7:37
  • 2
    \$\begingroup\$ Lights and particles are two different things. A particle can also "leak" through an obstacle, but for completely different reasons. Sometimes a particle system will also include a light to help sell the effect (think a campfire or swarm of fireflies), but a light inside a particle effect is still just a light, usually not any special variant. \$\endgroup\$ – DMGregory Jun 21 at 10:17
  • 2
    \$\begingroup\$ An alternative approach to shadow maps is shadow volumes, which fixes the aliasing problem, but is more expensive: requiring extra geometry to be rendered (a new polygon per silhouette edge of each object for each light source), as well as extra rendering passes. I'd expect the mapping approach is good enough for most situations, though. \$\endgroup\$ – DarthFennec Jun 21 at 18:18
22
\$\begingroup\$

Long story short, this happens for performance reasons.

When there's a light on the screen, by default it shines on all objects (obstructed or not), so the game would need to make extra calculations to see which object is affected by what.

This is easier to solve on static objects by using static and baked lighting, but this is not the same on dynamic lights, like explosions as you noted.

For your bonus question, ray tracing and cheap do not go together on the same sentence. The only reason ray tracing hasn't been mainstream up until now is performance. Assuming all lights use ray tracing, then this problem would be "solved", but at the expense of performance.

\$\endgroup\$
  • 6
    \$\begingroup\$ So is ray tracing more of a thing for CGI movies than real-time games? \$\endgroup\$ – Acccumulation Jun 20 at 20:31
  • 21
    \$\begingroup\$ @Acccumulation That's correct. A single frame of a movie can take hours to render, while a game only has milliseconds. \$\endgroup\$ – NobodyNada Jun 20 at 21:28
  • 16
    \$\begingroup\$ That said, games are increasingly exploring using raytracing or raymarching in tandem with rasterization techniques, letting the rasterizer do what it's good at and the rays do what they're good at. It's not full raytracing of every pixel, but you can still get some great effects that way. \$\endgroup\$ – DMGregory Jun 20 at 21:39
  • 2
    \$\begingroup\$ @DMGregory Indeed, games like Duke Nukem 3D already used a very simplified variant of raytracing - though it wasn't used for dynamic lighting, and it definitely didn't trace every single pixel on the screen (usually, it was done for each column of pixels), and reflections and transparency were still a special case rather than the default. Software 3D rendering has always played with similar approaches, it was the hardware 3D that closed off that avenue (until now). \$\endgroup\$ – Luaan Jun 21 at 7:36
  • \$\begingroup\$ @Acccumulation Raytracing comes at different levels, so while games can on top of the line hardware shoot primary rays they still dont do enough secondary bounces or multiple bounces per pixel. So even if you were to raytrace youd still have performance tradeoffs much like this. So ability trace main lights still does not mean you can afford to render all secondary lights. \$\endgroup\$ – joojaa Jun 22 at 9:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.