Hey, I'm Simon and I'm making a game!! :)
Support me: Wishlist & Play Demo on Steam

Doom 3 is known for its shadows but in the last days something different got my interest: the  volumetric effects around lights.

Before we start, let me point something out: The aura around light is called many things. Here’s some terminology (please correct me if got this wrong):

Glare occurs when light is too bright and disables seeing sharp. Disappears when the light source isn’t seen directly.

Haze is basically fog and in our case lit by some light. You can see this even the light source isn’t visible!

Lens flare  is an effect caused by the imperfection of the camera lens. And it’s an
Photoshop effect which was heavily overused after it was
implemented.
Below you can see clearly that the Doom 3 light has a nice aura (like haze, since it’s not too strong) and that this aura disappears without directly sight to the light source (acts like glare). ID calls them “flare” in their materials.

Source: Doom 3

I alread knew three ways of doing these light effect.

  1. Render every glow of the frame into a big texture, blur it and overlay it with the the current frame. This costs memory but no special setup by artists. The glow is reduced automatically if the visible light area gets smaller or disappears (like glare).
  2. Place planes with a glowtexture around the light (the planes would have to fade out if you look in a narrow angle at them). This costs not much more memory but the effect stays even you don’t see the source of the light (like haze). Also it takes some time for artist to create these planes around every glowing area.
  3. Place a big glowing sprite which rotates always to the camera. But this wouldn’t work well at rectangular light areas which you find very often in Doom 3.

I created a test object with just a polygon like said in the documentation of D3 and added a material you find e.g. on the Doom 3 desk lamps:

Source: Doom 3

The effect behaves a bit “weird”, because when you walk near a light source there’s some movement in the aura. Another artifact cen be seen in the first image (orange lights): the lower light cuts into the wall and this cut “moves”. This wouldn’t happen if you place the planes by hand (because they don’t rotate to the camera).

How did ID this effect?  I have no idea and also the Internet does know too much. Only one other guys asked himself the same question but the answers weren’t satisfying. We can at least look at the wireframe:

Source: Doom 3

Isn’t that beautiful? They fold and unfold a (i think) vertex colored mesh in a way, that you always get a volumetric look. I love it!

Source: Doom 3

They draw this geometry only when you’re in front of the light source. If you lose direct sight, it  disappears:

Source: Doom 3

Depending on the angle they fade out the light by turning down the vertex colors. At least i think it’s done via vertex color. Anyway, they fade the effect out in a smooth way – i like it!

Source: Doom 3

If you don’t have much graphic memory and you don’t want to let artist spend a lot of time in  creating this effect by hand, i think this technique is awesome. You only have to create a polygon  (quad) and add a predefined material to it. Also you can set the parameters right in the material which gives you a good control.

Have a nice day!

Update 1
Update 2
Update 3
Yzer did a Doom glow implementation a while ago (see Update 2) and based on that, Hollowdilnik did one too! How cool is that?

Source: hollowdilnik
Update 4
Michael made a WebGL Implementation of the Doom glow! And even better, you can also find the source code on github! :)

21 thoughts on “Doom 3 – Volumetric Glow

  1. Simon

    He he, that’s right. But I’m just a small artist and don’t understand the code. But maybe we get lucky and a programmer will have a look on it :)

    Reply
    1. Anonymous

      You understand the way the algorithms and problem solving works.
      Most importantly you understand the aspect of what kind of property you want to be able to represent, and that you need to abstract it in order to render it with a GPU.
      It’s a small step from there to actual code.

      Reply
  2. Chev

    I haven’t looked at the source but from what I can see on those images, basically what it does is calculated the silhouette (ie a list of all the edges that don’t have a visible face on both sides from the POV of the player) and are thus the borders of the drawn object, and then “expand” them, drawing a polygon strip around them.

    Normally determining the silhouette and dynamically creating that strip would be somewhat complex and developers wouldn’t implement it just for the sake of that effect, but for Doom 3 it wasn’t a problem because it *already* uses silhouettes with polygon strips for its shadowing system (same principle, but from the POV of the light that’s casting a shadow), so they just recycled the algorithm for an extra effect.

    Reply
    1. Simon

      That sounds logic to me but i think they must have extended the tech a bit because the base geometry for the light plane is just a quad. But the generated glow geometry is “round” at its corners. A shadow volume if the plane would be “hard-cornered” if you know what i mean.

      But i really like the idea that they used their shadow tech for doing these volumes.

      Reply
    2. Chev

      True. Actually, as long as the polygon is flat you can precompute the silhouette (all edges are always gonna be visible if the poly is) and if it’s convex you know you need the extra two triangles for each corner, so you can precompute the mesh for all convex shapes and then it’s just a bit of vertex shader tinkering to get the effect (all lines orientations for a corner mesh are just dependent on the screen space positions of the two segments that form the corner. The two “exterior” lines are each perpendicular to a segment, the “interior” line is at the halfway angle between them)

      Reply
  3. Neodroid

    simply beautifull.

    I love ID just because they solve usual and common problems just in their very own way. This use to make them very creative and technically alternative.

    Anyway I should recognize that sometimes they’re right and sometimes not so…

    Reply
    1. Simon

      Thanks man! I saw some clicks coming from reddit in my statistics and found it :) But it’s very nice that you gave me the link! :)

      Reply
  4. Anonymous

    This is one of Doom 3’s effects that i also paid attention too since it provides “clean” results even without HDR.

    I haven’t implemented it yet, but i think the idea is very simple: the polygon edges are projected in screen space and then they’re extruded with a constant (screen space) distance from the (2D projected) center with one additional vertex for each corner (so they’re round).

    Since Doom 3 does that only for visible “light” surfaces which face the camera (which is a very cheap test) and those lights are convex shapes, the geometry for this can be calculated at realtime).

    ~badsector

    Reply
  5. Anonymous

    Addendum to above:

    So i decided to try and implement this. Here it is running in RobGetOut’s forward render path:

    http://badsector.minus.com/lbnqk1Rovw2adt

    and in the deferred render path:

    http://badsector.minus.com/lbgZeGZMVviPKX

    The forward path looks more like Doom 3’s while the deferred looks more as if there was some blur pass with HDR (the light “bleeds” out thanks to the contrast filter).

    As an extra note, i had to bring the vertices back to camera space in order to do depth testing. Which makes me wonder if it would be easier to simply calculate scale from the projection matrix and do everything in world space.

    Reply
    1. Simon Post author

      Of course, no problem! :) I added your link to the article as Update #2. I hope that’s ok for you :) Really cool to have a code example (which i can’t understand since i’m not a coder) but i’m sure this will help a lot if other programmers try to implement this tech.

      Thanks for sharing!

      Reply

Leave a Reply to Simon Cancel reply

Your email address will not be published. Required fields are marked *