Wednesday, August 1, 2012

Doom 3: Blinn-Phong vs Phong

Without going into the technical and implementation details of each shading algorithms I would like to request comments from people as to which you prefer visually.

Unmodified Doom 3 uses the Blinn-Phong shading model, which is an approximation of the more computationally expensive Phong shading model. Both images are using a fixed exponent of 16.0f, however it's possible to adjust the exponent based on material type in both shading models. Currently, this is not done.

A higher exponent produces a tight specular highlight (for example chrome metal) while a lower exponent will produce a broader highlight (for example matte paint or skin tones.)

Please note that some tuning of the exponent may be required for the Phong model due differences in lighting calculation.

Doom 3: Blinn-Phong (16.0f)
Doom 3: Phong (16.0f)
Doom 3: Phong (4.0f)


  1. I think that Phong looks better too, but you should probably have made this a blind test. (not mention which image is which)
    I guess many might be biased towards teh more expensive shader, because "more expensive == better"

    1. Yes, that's a good point. I should try to round up some colleagues at the office, ask them to sit in front of a computer and run some demo loops with Blinn-Phong and Phong. Each demo would be played twice, but never sequentially.

      I could then ask them to rate each demo for visual quality on a scale of 1-10, average the results, and get a fairly objective answer.

      Any excuse to use colleagues as lab rats, right? ;-)

  2. I like the Blinn-Phong a bit more because it's less specular and more matte. I feels a bit better then the shining Phong.
    Phong gets a plus for more/better details. On your screenshot it makes the worlds less flat.

    1. Thanks, this is a helpful reply. I mentioned in the original blog post that the exponent would need to be tweaked a bit.

      I believe applying different exponents for different surface types would also greatly improve the visual fidelity. This is a very simple screenshot with a limited number of surface types; really only the wall and the gun.

  3. A semi-blind test here as I skipped to the images!
    I prefer the Phong images because:

    - The light source(s) look more like light sources. In the Blinn-Phong images the varying shade looks more like the walls colour itself changes (clean/dirty patches) rather than the change being to do with the light shining off it. In Blinn-Phong each of the three far wall panels has a very similar A shaped lighter area. In the Phong image the three panels all look different. (Are the top two shots taken from precisely the same position?).

    - The relief is clearer. Both the darker horizontals through the main light patches and the lighter horizontal highlights higher up the wall in the darker area make the wall elements 'pop' and again are more suggestive of a wall reflecting a light source than in Blinn-Phong where the wall looks like a flat texture.

    1. Paul, sorry I forgot to mention: yes, the first two images are taken from the exact same position, which is at a slight angle relative to the wall.

      With a careful eye you can see a slight difference between the right and left specular reflections in the second image, which is using Phong shading.

      The third image, which I added recently, is also using Phong shading but with a lower exponent in an attempt to more closely match the original Blinn-Phong model. However the eye is looking directly parallel to the wall, therefore both specular highlights are exactly the same.

      The real advantage to using the Phong shading model can only be seen when moving about through the world. The specular highlights respond how you would expect them to respond on real-life surfaces; you can move and look around and see the location and shape of the highlight changing subtly. It is unfortunately very difficult to describe, and I wish I could get some videos online; the difference is truly amazing.

      It's going to look even better when I add a variable exponent based on the Doom 3 surface type. The following types are defined in the engine:

      // material types for particle, sound, footstep feedback
      {"metal", 0, SURFTYPE_METAL, 0 }, // metal
      {"stone", 0, SURFTYPE_STONE, 0 }, // stone
      {"flesh", 0, SURFTYPE_FLESH, 0 }, // flesh
      {"wood", 0, SURFTYPE_WOOD, 0 }, // wood
      {"cardboard", 0, SURFTYPE_CARDBOARD, 0 }, // cardboard
      {"liquid", 0, SURFTYPE_LIQUID, 0 }, // liquid
      {"glass", 0, SURFTYPE_GLASS, 0 }, // glass
      {"plastic", 0, SURFTYPE_PLASTIC, 0 }, // plastic
      {"ricochet", 0, SURFTYPE_RICOCHET, 0 }, // behaves like metal but causes a ricochet sound

      Plus the "default" surface, where a surface type has not been defined in the material shader. Unfortunately I've not yet been able to locate a table which would give me relative specularity data for differing surfaces. I'm still looking.

      Now, ideally the exponent is stored on a per-pixel level in the A (Alpha) component of an RGBA texture, where RGB is the specular intensity and color. This is a "true" specular map.

      Doom 3 specular maps do not have an alpha channel, so technically they are gloss maps. The original fragment shader applies the same fixed-value exponent to every world surface. This is the primary reason that people say "Doom 3 looks like everything is made of plastic."

      The best that I can do, with the existing media, is specular exponentiation at a "per-surface" level. Obviously, this is not as good as per-pixel exponentiation, but still an improvement over fixed-value for the entire world exponentiation.

      Instead of everything looking like plastic, metal will look shinier than flesh. You will see a difference once this is implemented.

      There are limitations on how good this can possibly look; if you've ever looked at corrugated cardboard you'll notice there are peaks and valleys to the corrugation. The peaks reflect more light (are more shiny) than the valleys. This is an example of something that cannot be fixed with the above solution, because it requires a real, true per-pixel specular map. The best I could do would be flat, non-corrugated cardboard; think "manila folder/envelope" rather than "cardboard box."

  4. Thank you everyone for your comments. I've pushed the Phong shading into the gl2progs repository as the default. If you don't like it, please feel free to comment here (with or without screenshots.)

    You can also revert back to Doom 3-style Blinn-Phong by simply uncommenting `//#define BLINN_PHONG' from `gl2progs/interaction.frag' If you do this, it's important you comment and tell me why you made this decision!

    I want to know whether I would annoy a bunch of people by losing Doom 3 compatibility.

    Once again, thank you for everyone who replied here or on IRC.

    1. commit 4e29721cccfd076a95b93d08a7936c5658fcbc0e
      Author: Oliver McFadden
      Date: Thu Aug 2 06:09:54 2012 +0300

      gl2progs: Phong exponent of 4.0f. Backwards compatibility warning!

      This value somewhat resembles the Blinn-Phong exponent of 16.0f,
      however, these are different lighting models and therefore will never
      match perfectly.

      Until I'm able to find a useful look-up table of material type to
      specularity, use a constant value for all surfaces in the world.

      Signed-off-by: Oliver McFadden

  5. Blinn-Phong behaves better at glancing angles. It gives more correct elongated reflections. I saw a good technical explanation once, but I don't recall where...

    1. Yes, this is true but I believe for most general cases Phong behaves fine and looks better. It's possible to have some in-surface aliasing, though.

  6. Blinn-Phong is better for me. Phong is too glossy.

  7. If the performance impact on real map is big, maybe you can keep both to switch when performance or "quality" is needed...otherwise i would stick with Phong. I expect metal look more glossy and reflective, with Blinn-Phong i am seeing a material that looks like...well i don't know what in real life can look like this :)
    Maybe another example? Some set of wood,glass,concrete?

    1. The performance impact shouldn't be very much, especially on the hardware we have nowadays. I don't like the idea of switching lighting models dynamically because just like with doing Level-of-Detail (LOD) you will see things pop in and out.

      In the comment above it's complained that "Phong is too glossy," however this is how the scene should look given the lighting configuration. Keep in mind that in this small test_box room, we have 4 overlapping lights with quite a large radius. They are arranged in an "X" pattern within the room (one light at each vertex of the "X")

      Phong is absolutely the right choice when you walk around the world and see the specular highlights behaving the way you'd expect them to in the real world. The rest is just tweaking the exponentiation for different surfaces.

      Unfortunately, as I commented on Twitter, Doom 3's media uses SURFTYPE_NONE much more than I would have expected or hoped. This means that I cannot know the surface material, and I have to fall back to the default exponent. I explain basically the same thing in an earlier comment about the difference between specular maps and gloss maps.

      I will try to get some better screenshots (or even video if possible) online as soon as possible.

  8. Hi,

    I don't agree with you about the Phong shading. The Phong shading is good looking but can't no way be seen on all surface in the world. Just see how it looks at grazing angles. The specular will get bigger and bigger due to the dot ( ReflectVector, LightVector ).

    This will never happen on metallic surfaces. A better choice would be the Blinn especially for Doom 3. It's a simple and good approach to a microfacet shading and it's cheaper than phong.

    Phong shading is good but not for metallic surfaces.

  9. Blinn-Phong is not an approximation to Phong, it is an improvement to the Phong method. Hence the naming. Everyone's opinions here about things looking too glossy or not glossy enough between the two are not relevant because the two approaches are both approximations to reality. Their exponents will give different results but one is no more accurate than another in that sense. Blinn-Phong not sharp enough for you? Then up the exponent - there's nothing holy about that number, it is just picked to look good.

    Where Blinn does have an advantage is at grazing angles, where highlights stretch more realistically. An example (Blinn on the left, Phong on the right):

  10. apk android trusted site and Muchos Gracias for your blog.Really looking forward to read more.

  11. The Blinn–Phong model isn't an approximation of the Phong model; it's simply an adaption of it which also happens to more accurately model the way real world objects reflect light. This is especially apparent when viewing the surface from a glancing angle.

    But I can't believe that the specular highlights produced by Blinn–Phong model in this case are so weak! They are barely even visible, but they should be as strong as the Phong speculars, unless you have modified the reflection coefficient or something like that. And yes, the exponent for Blinn–Phong needs to be only 1/4 of the exponent for Phong to get the same radius of the reflections. This is for surfaces viewed from the front though, and not from an angle.