3D graphics gurus and hardcore gamers continually lust-after the latest in 3D rendering hardware so that they may get closer to the holy grail of ray-tracing, real-time volumetric lighting, and other rendering effects. But these science-based effects, while accurate, are geared mainly toward the reproduction of reality. For the game I’m making now, I’m much more interested in creating an experience in a world that is visually driven by aesthetics, not reality. A world that is rich with character – more like a painting than a photograph or a blockbuster movie.
To present this contrast, let me reintroduce the most basic lighting model, the Phong reflection model. The formula for the Phong model computes the amount of light hitting a point based on the surface normal at that point, the direction of a light source, and the direction of the viewer. The equation can be broken down into 3 components: an ambient lighting term (bouncing light from all directions), a diffuse term (direct light from a source), and a specular term (reflected light).
Let us now imagine a simple 3D object. We’ll choose a nice green for the diffuse color of its surface material. (“Nice greens” usually have red in them, by the way). The gradient below represents, from left-to-right, the diffuse term in the Phong model; from the brightest point (surface color facing the light) to the opposite side of the object (the parts in shadow):
While the green color I’ve chosen is quite splendid, the gradient itself is rather boring. This is a well-known condition – a topic for Art 101. Artists are trained to avoid boring lighting gradients and embellish these with interesting color. Often these colors use a completely different hue. In the example of a skin tone on the right, an artist will highlight the basic yellow with warm, red hues. No outdoor watercolor would be complete without shadows of blue and purple, instead of just darker versions of a subject’s actual color.
Computer scientists thought they could solve this problem by adding the ambient lighting term. In theory, you could add in a dark blue color to give the effect of a vivid shadow. The problem is, this also affects the color of the lit part of the object:
What this means is that a lighting artist typically has to mess with the lighting to get it to look the way they want it to. This means adding in fill lights to a game world until the scene looks the way they want it to. These extra lights often must be “baked” into the game world and are static (can’t move or change) because there are too many to efficiently calculate in a pixel shader.
Graphics programmers usually think of color in terms of its RGB (red, green, and blue) components. But artists are trained to think in terms of HSB, or hue, saturation, and brightness. To get a visual sense of the HSB color space, look at any color wheel. The code to convert between these systems does consume a few CPU cycles, but it can be very useful for a programmer to start using the HSB (also known as HSV) color space for certain applications. In this space, you can take any color and simply tweak a single value up or down to alter the saturation, hue, or brightness of that color. When you apply some artistic principals to this idea, you can take any color and “twist” it to get another color. One that compliments it in a really attractive way, creating a color harmony. This is called color scheming and I won’t go into these ideas here, but you can read more about them elsewhere.
I began to experiment with these ideas in the context of lighting. Colors that are next to each other on the color wheel look good together (analogous colors). I used this principle to generate a shadow color for any particular surface color. I ended up with the following technique:
- convert the surface color to HSB (looks best when color has saturation less than 50%)
- darken it to a value between 20-35%.
- bump the saturation up to 100%.
- “twist” the hue by 30-50 degrees in either direction.
Using this twisted hue technique, our green lighting gradient can now looks like this:
…which preserves the green color and produces a much more compelling lighting model than the Phong model gradients that I showed earlier. Here are some other twisted hue examples using other surface colors (the last two use the same surface color):
Finally, here are some simple examples to show the difference. These terrain renderings are captured from my game engine running on the iPhone. The top renderings are using a standard N*L lighting model to modulate the texture color (a desaturated yellow color, similar to the above gradients). The bottom renderings use N*L to interpolate along the twisted hue lighting gradient.
For more information on HSV and HSL color spaces, see Wikipedia.