Sunday, June 2, 2013

HDR Lighting - Intro to HDR, and HDR render target

HDR lighting is a very very big subject, but in a graphics or gaming context it basically means using some kind of average luminance measurements or other heuristic to tone-map our image differently to the "classic" effect. The reason to do that is that the "classic", LDR format actually proves too restrictive to provide us with a very realistic or artistically beautiful image on a scene that is designed to be real-time created.

Background
The human visual system (eye and brain) is very very adaptable to lighting conditions using a number of mechanisms, both mechanical and chemical. There are a number of mechanisms allowing our eye to adjust from very bright to very dark conditions and still discern colors and details from the scene. The most important way to adapt is the eye's pupil which, according to the brightness of the scene, contracts or dilates in order to change the amount of light that passes in the eye in order to adapt to the overall brightness of the image, exactly like the diaphragm on a photographic camera (actually, the photographic camera works exactly like the eye's pupil...).

There are other mechanisms in place, such as visual photoreceptor cells in the eye themselves chemically adjusting their sensitivity, but let's just stay with the fact that vision adapts to lighting conditions.

Up to now, we were using a more or less physically-correct lighting model, where our optics model (lights, the diffuse and specular reflection of each point on an object et.c.) determined the brightness of each point on the scene, a number that pretty much reflects (no pun intended) the amount of light that would be reflected from a point in the scene to the viewer's eye, without taking into consideration the viewer's eye itself.

Saturation
There was a caveat though... Imagine that we have a light with a color of 1,1,1. It lights the pixel of a white object that it is pretty close to (let's say, diffuse material 1,1,1), for a pixel color of 0.9,0.9,0.9.
Then, imagine a second light, and similar conditions. The pixel color would have gone to 1.8, 1.8, 1.8.

Well, it's not going to! A normal, LDR framebuffer only goes to a value of one, and we can no longer encode brighter pixels.

HDR render targets
So, what we want to do first is un-clamp the range of lighting (or rather, since completely unclamping is impractical on a computer context, move the clamping upwards to a point where it does not bother us anymore...).
This way we can simulate the viewer's pupil, changing the way we map colors in order to give a more realistic, convincing, and ultimately nicer scene. In the above scene, the very bright parts of the object might stimulate the user's pupils to contract, in order to re-map the scene to a 0..1 range or similar.

We want an HDR render target.

One of the first things we want to do, is give a bigger range in our initial conditions in order to be able to handle very bright and very dark pixels. The way to do that is to use a HDR render target, with a format that is more than 8 bits per color channel (either 16 or 32 bits), so a R16G16B16A16 or R32G32B23A32. For now I do not have a convincing argument for more than 16 bits so that is what I will use, but I defer final judgment for later.

There is not even the point of a snippet here, it is as simple as it sounds. When defining our render target format, we just supply (for DirectX semantics) DXGI_FORMAT_R16G16B16A16_FLOAT instead of  DXGI_FORMAT_R8G8B8A8_UNORM or  DXGI_FORMAT_R8G8B8A8_UNORM_SRGB.

This way, we can encode color values of more than 1.0, and get pixels that have a final color greater than 1.0. It is also much less risky to use lights that have a greater color value than 1.

At this point, we have not gained much. If we try to render this to the screen, we will get the exact same image as if it was clamped to 1.0.

The gain here is that we can now use these values in order to post-process the image using this enhanced information, to achieve a nicer image, and any number of pretty effects.

No comments:

Post a Comment