Many modern sci-fi games have some sort of glowing lights. The bright intensity of several small lights contrasts well against dark starfields or the dimly lit interior of an alien spacecraft. Naturally, we wanted to replicate this effect in Unity for Longshot.
Generally speaking, this is done in two stages. The first step is to use a “self-illuminated” or “emissive” shader. These shaders set part of the rasterized model to full brightness, regardless of the surrounding lighting. This makes the area look like it has been lit, but doesn’t really give the intense light effect we’re looking for.
The second stage involves a full screen image effect, which means it requires Unity Pro. In general terms, this effect takes bright pixels and blurs them into the neighboring area so it looks like there is a halo around this light, similar to the “halo” checkbox in a dynamic light. However, using a dynamic light for every little light on a ship would be hugely expensive, and unnecessary; it’s not like these are huge spotlights, we’re just trying to capture the effect of a bright light against a dark background.
The first image effect we tried sounded like the obvious choice: Glow. However, this is a simple (and perhaps old fashioned) effect that didn’t really do what we wanted. It uses the alpha channel to blur a given tint color around “bright” pixels. As you can see in the next image, since we are using more than one color of light, this doesn’t look quite right. Also, it always uses the alpha channel, which means we would need to tweak every material we had so it didn’t accidentally write out alpha and cause undesired pixels to glow.
On our second attempt, we used the Bloom effect. This shader is often used to enhance the look of things like glare off a car, or bright light from the sun, and so on. However, it did two things that we were looking for: it uses the intensity of the pixels rather than the alpha values (though it can be configured to use alpha as well), and it preserves the color of the pixels.
However, there was one problem. Since color values are normally clamped to the range [0,1], this means that it could bloom out any pixel, even pixels that should just be brightly colored, but don’t necessarily correspond to lighting. This can cause the whole screen to become somewhat blurry, and still our individual lights wouldn’t look that bright. We tried setting the intensity threshold really high (close to 1.0), and set the emissive intensity of our materials pretty high, but this ended up washing out our colors and our lights looked mostly white.
This is where high-dynamic range (HDR) comes into play. With a HDR enabled camera, output pixel intensity values are unbound in a practical sense. This means we could make our pixels as intense as we wanted, and use tone mapping to map these super-intense pixels back down into the [0,1] range, so that they don’t look washed out. Now we could set the bloom intensity threshold high enough so that only our lights (and perhaps really brightly lit areas) would bloom out at all.
Now it looks like we wanted, a ship with small, bright lights against a dark starfield background!