💡

Lighting

Created
Tagsgraphics

Overview

Lighting is the technique that models how light interacts with surfaces.

Realistic lighting can be approximated using three terms to model different species of light that occur in a scene: ambient, diffuse, and specular color.

Th colors terms are blended between the light sources and the surface material and multiplied by an intensity. The intensity of each component is determined by the light equation.

color = ambient + diffuse + specular

Light types

Directional

A directional light intensity is defined by the angle between the reverse light direction and the surface normal.

A direction light is far enough away so that its rays can be considered to be hitting the surface of an object all in parallel, like the sun.

Point

A point light intensity is defined by the angle between the direction from the vertex to the the light and the surface normal.

The calculation is typically done in world space, so the input vertex position is multiplied with the world transform in the vertex shader, and passed to the fragment shader.

Spot

Parallel Point

Light terms

Ambient

An ambient light describes a light source that illuminates everything in a scene, regardless of the orientation, position, and surface characteristics of the objects in the scene.

An ambient light is not characterized by a position or a direction.

It is an approximation of indirect light (light that has bounced off other surfaces in the scene).

Ambient lighting prevents the parts of geometry that are not directly lit from being completely black.

Calculated from the product of a material ambient color and a light ambient color.

Ambient = MaterialColor * LightColor

Diffuse

A diffuse color is the color of an object given by direct illumination.

It represents the tendency of surfaces to reflect light equally in all directions.

Diffuse light follows Lambert’s cosine law.

The direction of the light is negated to obtain the proper direction vector.

The intensity of the reflected light is directly proportional to the cosine of the angle between the normal of the surface and the direction of the light.

The normal direction and light direction vector are unit vectors, so the cosine is equal to the dot product between these vectors.

Diffuse = MaterialColor * LightColor * (NormalDirection . LightDirection)

A dot product can produce values in the [-1, 1] range. A negative value indicates that the face is oriented away from the light source and should not receive any contribution from it. Therefore, the result is restricted to the [0, 1] range.

For point lights, the light attenuation is calculated.

For spot lights, the light attenuation and light falloff is calculated.

Specular

The specular color is the bright highlight of a shiny object.

It represents the tendency of surfaces to reflect light in a particular direction rather than scatter it in all directions.

The specular color is calculated using the direction to the viewer's eye.

The shininess is used to convert the specular highlight from a linear falloff to an exponential falloff. The shininess is quantified by a specular power value. Lower values are more matte and higher values are shinier.

Shininess is the opposite of roughness, which is a different representation of surfaces.

There are different lighting models to compute the specular term.

Blinn-Phong

The Blinn-Phong specular term uses the vector that points halfway between the direction to the light source and the direction from which the surface is viewed.

HalfwayDirection = (LightDirection + ViewDirection) / 2

A more stable calculation is to compute the halfway vector by normalizing the sum of light direction and view direction.

HalfwayDirection = normalize(LightDirection + ViewDirection)

The intensity of the reflected light is directly proportional to the cosine of the angle between the normal direction and the halfway direction. As these are unity vectors, the value is computed using their dot product.

A dot product can produce values in the [-1, 1] range. Therefore, the result is restricted to the [0, 1] range.

An optimization is to replace the view direction by a unit direction on the z-axis to simulate points at a viewpoint infinitely distant on the z-axis.

Finally, the result is raised to the specular power value.

For point lights, the light attenuation is calculated.

For spot lights, the light attenuation and light falloff is calculated.

Specular = MaterialColor * LightColor * (NormalDirection . HalfwayDirection) ^ SpecularPower

Light Attenuation over Distance

The light attenuation is determined from the distance between a light source and the vertex being lit.

💡
Point lights and spot lights have an attenuation factor, but not directional lights.

If the distance is within the light's range applies the following formula is used to calculate light attenuation over distance:

A = 1 / (Attenuation0 + D * Attenuation1 + D*D * Attenuation2)

A is the calculated total attenuation and D is the distance from the light source to the vertex. Attenuation0, Attenuation1, and Attenuation2 are attenuation constants that act as coefficients in the formula to obtain a variety of attenuation curves.

Spot Light Falloff

Spot lights emit a cone of light that has two parts: a bright inner cone and an outer cone.

Light is brightest in the inner cone and isn't present outside the outer cone, with light intensity attenuating between the two areas.

This type of attenuation is commonly referred to as falloff.


The falloff is calculated by the dot product of the spot light's direction vector and the vector from the vertex to the light.

This value is equal to the cosine of the angle between the two vectors, and serves as an indicator of the vertex's position that can be compared to the light's cone angles to determine where the vertex might lie in the inner or outer cones.

Cosine = (VertexToLightDirection . SpotLightDirection)

This value is compared to the cosine of the spotlight's inner and outer cone angles.

Lighting Model

We use an approximation consisting of three terms to model different species of light that occur in a scene: ambient, diffuse, and specular.

Th color component is blended between the light and the material and multiplied by a different intensity. The intensity of each component is determined by the light equation.

Phong

The light calculations are done per pixel, in camera space.

In the vertex function, we convert the positions and directions into camera space.

Vertex

float4 position_model = float4(input_position, 1);
position_model = modelViewProjection_transform * position_model;
float3 normal_model = float4(input_normal, 0);
normal_camera = (normalize(modelViewProjection_transform * normal_model.xyz);
float3 position_camera = (modelView_transform * position_model).xyz;
eyeDirection_camera = float3(0,0,0) - position_camera;
float3 lightPosition_camera = (view_transform * float4(lightPosition, 1)).xyz;
lightDirection_camera = lightPosition_camera + eyeDirection_camera

Fragment

float4 ambientColor = materialAmbientColor;
float3 n = normalize(normal_camera);
float3 l = normalize(lightDirection_camera);
float n_dot_l = saturate(dot(n, l));
float4 diffuseColor = lightColor * n_dot_l * materialDiffuseColor;
float3 e = normalize(eyeDirection_camera);
float3 r = -l + 2 * n_dot_l * n;
float e_dot_r = saturate(dot(e, r));
float intensity = pow(e_dot_r, materialShininess);
float4 specularColor = materialSpecularColor * lightColor * intensity;
color = (ambientColor + diffuseColor + specularColor);

Deferred Lighting with Shadow Maps

Requires two passes, four color buffers (including two g-buffers), a depth buffer and a stencil buffer.

Reflection

Reflection occurs when light bounces off of a reflective surface.

In a mirror reflection, all light bounces off at an angle equal to its incident angle.

To simulate reflection, a cubic texture is sampled using the reflected vector as the texture coordinates.

Refraction

Refraction occurs when light passes from one medium to another.

The amount the light bends is proportional to the ratio between the indices of refraction of the two media it is passing between.

The index of refraction of a substance is a quantity that characterizes how much it slows down the propagation of light, relative to a vacuum.

Refraction follows the Snell’s law which states that the ratio of the sines of the incident and transmitted angles is equal to the inverse ratio of the indices of refraction of the media.

Snell's law

Reflection & Reflection

Normal Mapping

Increase the apparent complexity of surfaces without using additional geometry.

Requires a normal and orthonormal axes (tangent and bitangent) for each vertex.

These three axes are the tangent frame.

Image Based Lighting (IBL)

Vertex

Transform the position, normal and tangent vectors.

out.position = modelViewProjectionTransform * in.position;
out.normal = normalTransform * in.normal;
out.tangent = normalTransform * in.tangent;
out.bitangent = normalTransform * cross(in.normal, in.tangent);

Shadows

Shadow Buffer

A shadow buffer is similar to a depth buffer.

It stores depth information from the viewpoint of a light source instead of from the viewpoint of the camera.

💡
Using a larger shadow buffer create finer resolution shadows.
  1. For each light, render to the shadow buffer:
    • Disable all color writes.
    • Set a viewport to the dimensions of the shadow buffer.
    • Clear that viewport of depth information.
    • Set up the views and projections from the light's viewpoint.
    • Render any objects in the scene that should be shadowed.
  1. Render the scene with shadows
    1. Enable all color writes.
    1. Reset the viewport dimensions
    1. Clear the viewport of color and depth informaiton.
    1. Set up the transformations.
    1. Set the shadow buffer in a texture stage.
    1. Render objects in the view frustum.

The shadow buffer works by comparing the z texture coordinate values with those values recorded in the shadow buffer.

A point is shadowed if the shadow buffer value is greater than the z texture coordinate.