A Bi-directional Reflectance Distribution Function (BRDF) is a mathematical function that describes how light is reflected when it hits a surface. This largely corresponds to a lighting model in Unity-speak (although note that BDRFs are concerned only with reflected light, whereas lighting models can also account for emitted light and other lighting effects).
The “bi-directional” bit refers to the fact that the function depends on two directions:
- the direction at which light hits the surface of the object (the direction of incidence, ωi)
- the direction at which the reflected light is seen by the viewer (the direction of reflection, ωr).
These are typically both defined relative to the normal vector of the surface, n, as shown in the following diagram (rather than simple angles, each direction is actually modelled in the BRDF using spherical coordinates (θ, φ) making the BRDF a four-dimensional function):
Given that our perception of a material is determined to a large extent by its reflectance properties, it’s understandable that several different BRDFs have been developed, with different effectiveness and efficiency at modelling different types of surfaces:
- Lambert: Models perfectly diffuse smooth surfaces, in which apparent surface brightness is affected only by angle of incident light. The observer’s angle of view has no effect.
- Phong and Blinn-Phong: Models specular reflections on smooth shiny surfaces by considering both the direction of incoming light and that of the viewer.
- Oren-Nayar: Models diffuse reflection from rough opaque surfaces (considers surface to be made from many Lambertian micro-facets)
- Torrance-Sparrow: Models specular reflection from rough opaque surfaces (considers surface to be made from many mirrored micro-facets).
In addition to the preceding links, there’s a good article explaining some of the maths behind these models at http://www.cs.princeton.edu/courses/archive/fall06/cos526/tmp/wynn.pdf
In the case of game development, it’s often not necessary to strive for physically-accurate BRDF models of how a surface reacts to light. Instead, it’s sufficient to aim for something that “looks” right. And that’s where BRDF maps come in (sometimes also called “Fake BRDF”).
A BRDF map is a two-dimensional texture. It’s used in a similar way to a one-dimensional “ramp” texture, which are commonly used to lookup replacement values for individual lighting coefficients. However, the BRDF map represents different parameters on each of its two axes – the incoming light direction and the viewing direction as shown below:
A shader can use a tex2D lookup based on these two parameters to retrieve the pixel colour value for any point on a surface as a very cheap way of modelling light reflection. Here’s an example Cg BRDF surface shader:
And here’s the image it produces – notice how the shading varies from red to yellow based on view direction, and from light to dark based on direction to the light source.
As a slightly less trivial example, here’s another BRDF texture map that again uses light direction relative to surface on the x axis, but this time, instead of using view direction, uses curvature of the surface on the y axis (the gradient in the y axis is quite subtle but you should be able to note reddish hue towards the top centre of the image, and blueish tint at the top right):
This map can be used to generate convincing diffuse reflection of skin that varies across the surface of the model (such that, say, the falloff at the nose appears different from the forehead), as shown here: