July 13, 2026 · 5 min read

Math test: the rendering equation, briefly

A KaTeX-heavy mockup post used to test inline and block math rendering. Safe to delete.

Note to self: mockup post to test KaTeX (inline + block, fractions, integrals, Greek, matrices). Delete before launch.

Almost everything a technical artist touches in lighting traces back to one equation. It looks intimidating written out, but each piece has a plain-language job. Here it is.

The equation

The outgoing radiance LoL_o from a point xx in direction ωo\omega_o is the emitted light plus everything reflected from the hemisphere Ω\Omega above the surface:

Lo(x,ωo)=Le(x,ωo)+Ωfr(x,ωi,ωo)Li(x,ωi)(ωin)dωiL_o(x, \omega_o) = L_e(x, \omega_o) + \int_{\Omega} f_r(x, \omega_i, \omega_o)\, L_i(x, \omega_i)\,(\omega_i \cdot n)\, d\omega_i

Reading it left to right: take the emitted light LeL_e, then add up — that's the integral Ω\int_\Omega — the contribution of every incoming direction ωi\omega_i, weighted by how the surface reflects it and how grazing the angle is.

The pieces

  • Li(x,ωi)L_i(x, \omega_i) — the light arriving from direction ωi\omega_i.
  • fr(x,ωi,ωo)f_r(x, \omega_i, \omega_o) — the BRDF, the surface's rule for turning incoming light into outgoing light.
  • ωin\omega_i \cdot n — the cosine term, cosθi\cos\theta_i. Light hitting head-on counts fully; light at a grazing angle barely counts at all.

That cosine is why a floor looks bright underfoot and dim toward the horizon.

A concrete BRDF

For a simple diffuse surface with albedo ρ\rho, the BRDF is just a constant:

fr=ρπf_r = \frac{\rho}{\pi}

The π\pi in the denominator is the part everyone forgets — it's what keeps energy conserved so a surface never reflects more light than it receives.

Specular is where it gets interesting. The Fresnel term, using Schlick's approximation, is:

F(θ)=F0+(1F0)(1cosθ)5F(\theta) = F_0 + (1 - F_0)\,(1 - \cos\theta)^5

where F0F_0 is the reflectance at normal incidence. For most dielectrics F00.04F_0 \approx 0.04, which is why even matte plastic gets a bright rim at grazing angles.

Why the integral is hard

We can't evaluate Ω\int_\Omega exactly in real time, so we approximate it. Monte Carlo integration samples NN random directions and averages:

Ωf(ω)dω1Nk=1Nf(ωk)p(ωk)\int_{\Omega} f(\omega)\, d\omega \approx \frac{1}{N} \sum_{k=1}^{N} \frac{f(\omega_k)}{p(\omega_k)}

The p(ωk)p(\omega_k) is the probability of picking each sample — importance sampling just means choosing pp to match where ff is large, so you spend samples where they matter.

A tiny bit of linear algebra

Transforming a normal isn't the same as transforming a position. If MM is your model matrix, normals must use the inverse-transpose:

n=(M1)Tnn' = (M^{-1})^{\mathsf{T}}\, n

For a rotation like

R=[cosθsinθsinθcosθ]R = \begin{bmatrix} \cos\theta & -\sin\theta \\ \sin\theta & \cos\theta \end{bmatrix}

the inverse-transpose equals RR itself, which is why pure rotations never distort your normals — but non-uniform scale does, and that is the usual culprit behind broken lighting.

Wrapping up

You rarely type these equations into a shader directly, but knowing what each term does turns "the lighting looks wrong" into a diagnosis. The cosine, the π\pi, the Fresnel rim — each one is a knob with a physical meaning.

If the math above rendered as crisp symbols rather than raw dollar signs, KaTeX is working.