5 min read
On this page

Shading and Lighting

Overview

Shading computes the color of each surface point based on material properties, light sources, and viewing direction. Modern rendering has evolved from simple empirical models to physically based approaches that conserve energy and produce photorealistic results.

Light Types

Directional Light

Infinitely distant source with parallel rays (sun). Defined by a direction vector L and color/intensity. No attenuation.

Point Light

Emits light uniformly in all directions from a position. Intensity falls off with the inverse square of distance:

attenuation = 1 / (d^2)

In practice, a windowed falloff is used to bound the light's influence:

attenuation = saturate(1 - (d/r_max)^4)^2 / (d^2 + epsilon)

Spot Light

Point light restricted to a cone. Defined by position, direction, inner angle (theta_i), and outer angle (theta_o):

spot_factor = smoothstep(cos(theta_o), cos(theta_i), dot(-L, D))

Area Light

Emits from a surface (rectangle, disc, sphere). Produces soft shadows and realistic highlights. Requires integration over the light's area; approximated with Linearly Transformed Cosines (LTC) or representative point methods.

Emissive Surfaces

Self-illuminating geometry. In PBR workflows, emissive contribution is added directly to the output without shading.

Reflection Models

Lambertian (Diffuse)

Ideal diffuse surface scatters light equally in all directions. Intensity depends only on the angle between the surface normal N and light direction L:

L_diffuse = k_d * c_light * max(N . L, 0)

Where k_d is the diffuse reflectance (albedo). Energy-preserving normalization: divide by pi.

Phong Reflection Model

Adds specular highlights via the reflection vector:

R = 2(N . L)N - L
L_specular = k_s * c_light * max(R . V, 0)^n

Where V is the view direction and n is the shininess exponent. Higher n produces tighter highlights.

Total Phong: L = ambient + diffuse + specular

Blinn-Phong Model

Replaces the reflection vector with the half-vector H = normalize(L + V):

L_specular = k_s * c_light * max(N . H, 0)^n

Advantages over Phong:

  • Cheaper to compute (no reflection vector)
  • More physically plausible at grazing angles
  • Half-vector is constant for directional lights with fixed view

Shading Frequencies

  • Flat shading: One normal per triangle, constant color across the face
  • Gouraud shading: Evaluate lighting at vertices, interpolate colors
  • Phong shading: Interpolate normals across the triangle, evaluate lighting per-fragment

Physically Based Rendering (PBR)

The Rendering Equation

All physically based shading derives from the rendering equation (Kajiya 1986):

L_o(p, w_o) = L_e(p, w_o) + integral_Omega f_r(p, w_i, w_o) * L_i(p, w_i) * (N . w_i) dw_i

Where:

  • L_o = outgoing radiance
  • L_e = emitted radiance
  • f_r = BRDF (bidirectional reflectance distribution function)
  • L_i = incoming radiance
  • (N . w_i) = cosine foreshortening term
  • Omega = hemisphere above the surface

BRDF Properties

A physically valid BRDF must satisfy:

  1. Reciprocity (Helmholtz): f_r(w_i, w_o) = f_r(w_o, w_i)
  2. Energy conservation: integral f_r * cos(theta) dw_i <= 1
  3. Positivity: f_r >= 0

Cook-Torrance Microfacet BRDF

The standard PBR specular model:

f_r(w_i, w_o) = D(h) * F(w_i, h) * G(w_i, w_o, h) / (4 * (N.w_i) * (N.w_o))

Where h = normalize(w_i + w_o) is the half-vector.

Normal Distribution Function (NDF) - D

Describes the statistical distribution of microfacet normals. GGX (Trowbridge-Reitz) is the most widely used:

D_GGX(h) = alpha^2 / (pi * ((N.h)^2 * (alpha^2 - 1) + 1)^2)

Where alpha = roughness^2. Produces a long specular tail that matches real materials well.

Fresnel Term - F

Describes how reflectance varies with angle. At grazing angles, all surfaces approach total reflection.

Schlick's approximation:

F(w_i, h) = F0 + (1 - F0) * (1 - w_i.h)^5

Where F0 is the reflectance at normal incidence:

  • Dielectrics: F0 ~ 0.04 (glass, plastic)
  • Metals: F0 = albedo color (gold ~ (1.0, 0.71, 0.29))

Geometry/Visibility Function - G

Accounts for microfacet self-shadowing and masking. Smith's separable form:

G(w_i, w_o) = G1(w_i) * G1(w_o)

Using GGX-correlated Smith:

G1(v) = 2(N.v) / ((N.v) + sqrt(alpha^2 + (1 - alpha^2)(N.v)^2))

Diffuse BRDF in PBR

The Lambertian term with energy conservation:

f_diffuse = (1 - F) * (1 - metallic) * albedo / pi

Metals have no diffuse component (metallic = 1). The (1 - F) factor ensures energy conservation between specular and diffuse.

Standard PBR Material Parameters

| Parameter | Range | Description | |------------|--------|------------------------------------------| | Albedo | [0,1] | Base color (linear, not sRGB) | | Metallic | 0 or 1 | Dielectric vs metal (binary in practice) | | Roughness | [0,1] | Microsurface irregularity | | AO | [0,1] | Ambient occlusion | | Emissive | [0,+inf)| Self-illumination |

Image-Based Lighting (IBL)

Uses an environment map (HDR cubemap or equirectangular) as a light source, capturing real-world or authored illumination.

Diffuse IBL

Precompute the irradiance map by convolving the environment map with a cosine lobe:

E(N) = integral_Omega L_i(w_i) * max(N . w_i, 0) dw_i

Stored as a low-resolution cubemap (32x32 per face is sufficient since diffuse is low-frequency).

Specular IBL and the Split-Sum Approximation

Direct integration of the specular BRDF over the environment map is too expensive for real-time. Epic Games' split-sum approach factors it into two parts:

L_specular ~ prefiltered_env(R, roughness) * (F0 * scale + bias)

Part 1 - Prefiltered environment map: Convolve the environment map at multiple roughness levels, stored in mip levels of a cubemap. Sample direction is the reflection vector R.

Part 2 - BRDF integration LUT: A 2D texture indexed by (N.V, roughness) storing precomputed scale and bias for the Fresnel term. Computed once offline:

LUT(NdotV, roughness) = integral D*G*F / (4*NdotL*NdotV) dw_i
                        split into F0*scale + bias terms

Spherical Harmonics (SH)

Represent low-frequency lighting as coefficients of spherical basis functions. L2 (9 coefficients) captures diffuse irradiance well. Efficient for dynamic lighting and light probes.

Shadowing

  • Shadow maps: Render depth from the light's perspective, compare during shading
  • Shadow volumes: Geometric extrusion of silhouette edges (exact, but expensive)
  • Ambient occlusion: Approximate self-shadowing of indirect light (SSAO, GTAO)
  • Contact shadows: Screen-space ray march for small-scale shadows near surfaces

Advanced Topics

Subsurface Scattering (SSS)

Light enters a surface, scatters internally, and exits at a different point. Important for skin, wax, marble, leaves. Approximated with:

  • BSSRDF: Generalization of BRDF accounting for spatial offset
  • Screen-space blur: Separable Gaussian blur in screen space (Jimenez)
  • Pre-integrated skin: LUT indexed by curvature and NdotL

Anisotropic Reflections

Materials like brushed metal have direction-dependent roughness. Modify the NDF to use separate roughness in tangent and bitangent directions:

D_aniso = 1 / (pi * alpha_t * alpha_b * ((h.T/alpha_t)^2 + (h.B/alpha_b)^2 + (h.N)^2)^2)

Multiple Scattering

Standard microfacet BRDFs only model single-bounce interactions between microfacets. Energy is lost at high roughness. Kulla-Conty compensation adds an energy-preserving correction term to recover the lost energy.