💡

Lighting

Computing Light Interaction

🦴💎💡✨🌀⚡
Roadmap topics covered here
Full roadmap →

Lighting lessons

Intuition: What Does a Dot Product Actually Mean?

The dot product A.B measures how much B points in the direction of A. The yellow projection line shows this geometrically — it is literally the shadow of B cast onto A. This is why N.L gives diffuse lighting intensity:

The yellow projection shows what A·B measures: how much B points in A's direction

Intuition: Cross Product Geometry

The cross product produces a vector perpendicular to both inputs. Its magnitude equals the parallelogram area. This is how TBN builds an orthogonal frame, how IK Jacobian columns are computed, and how curl noise works:

Cross product is perpendicular to both vectors. Magnitude = parallelogram area. Make them parallel to see it go to zero.

Normal Map Decoder

Normal maps store surface normals as RGB colors in tangent space. Hover over the map to see how each pixel decodes from RGB [0,255] to XYZ [-1,+1] and affects lighting:

Hover to decode RGB to XYZ normal vector and see lighting result.

Fresnel Ring Demonstrator

See where Fresnel kicks in on a sphere — the bright ring at the edges shows grazing-angle reflection. Center (head-on) uses F0, edges approach 1.0:

Bright ring=Fresnel. Edges glow at grazing angle. Increase F0 for metals.
Fresnel on Surface
At center: NdotV = 1.0, F = F0 At edge: NdotV -> 0, F -> 1.0 Every surface becomes a mirror at 90 degrees

Lambert Diffuse

Lambert
E = E0*cos(t) = E0*max(N.L, 0) 1 dot product -- cheapest lighting operation

Interactive: Diffuse + Specular + Fresnel

Drag the light to see all three shading quantities update in real-time:

Drag to rotate light — diffuse, specular, and Fresnel update live

Normal Mapping and TBN

TBN
TBN = [ T | B | N ] T=tangent B=bitangent n_world = normalize(TBN . n_map) B = N x T * w (w=+-1 for mirrored UVs)

Shadow Mapping

Shadow
shadow = d_frag > d_stored + bias ? 0 : 1 bias = max(b_max*(1-N.L), b_min) PCF: shadow = (1/N)*Sum(compare(samples))

Live: Shadow Map Depth Visualizer

See the scene from both camera and light. Set bias to 0 to see shadow acne — the floor falsely shadows itself because d_fragment barely exceeds d_stored due to floating-point precision:

Set bias to 0 to see shadow acne — floor shadows itself from floating-point precision errors.

Global Illumination

Radiosity
Bi = Ei + pi*Sum(Fij*Bj) (form factors)

Interactive: Spherical Harmonics Basis

SH probes encode diffuse lighting. L0 = ambient, L1 = directional, L2 = quadratic. 9 coefficients x RGB = 27 floats per probe:

Click to view SH bands — L0=ambient, L1=directional, L2=quadratic

Ray-Triangle Intersection

Moller-Trumbore
r(t) = o + t*d e1=v1-v0 e2=v2-v0 T=o-v0 p=d x e2 q=T x e1 [t u v]^T = (1/p.e1)*[q.e2 p.T q.d]^T Hit: t>0, u,v,(1-u-v) in [0,1]
← 💎 ShadersVFX ✨ →
Interactive lessonCanvas visualizersMathematical notation