Sampling, Antialiasing, and Monte Carlo
One sample through the pixel center produces a recognizable image and a bad final image. Edges stair-step. Thin highlights alias. High-frequency texture detail sparkles under motion.
The first remedy is not a blur filter. The first remedy is correct sampling and averaging in linear space.
Several stratified samples inside a pixel beat one center sample near edges.
Pixel antialiasing
color = 0
for k = 1..N:
(s, t) = stratified or random in [0, 1)²
ray = camera.generate(i, j, s, t)
color += trace(ray)
color /= N
Stratified sampling partitions the pixel into cells and places one sample in each cell. It reduces clumping relative to pure white noise. Blue-noise tables are better for stills when available. Stratification is enough while you learn.
Monte Carlo estimation
To approximate an integral, sample the domain and average carefully:
∫ f(x) dx ≈ (1/N) Σ f(x_i) / p(x_i)
Here p is the probability density that generated x_i. Forget the PDF and image brightness becomes a function of your sampling strategy. That bug is easy to ship and hard to notice if you only stare at relative contrast.
Light sampling and BSDF sampling
Direct lighting can sample lights. Indirect lighting often samples the BSDF. Ideal mirrors must be sampled by their reflection direction. Random hemisphere directions will almost never hit a Dirac lobe.
A practical teaching order:
- stratified pixel samples
- one analytic light with shadow rays
- cosine-weighted hemisphere samples for diffuse indirect light
- multiple importance sampling only after the above are correct
Cosine-weighted hemisphere
Uniform hemisphere sampling wastes effort near the horizon, where cosθ kills the contribution. For Lambertian surfaces, cosine-weighted sampling matches the integrand better:
r1, r2 ~ U(0,1)
φ = 2π r1
r = sqrt(r2)
x = r cosφ
y = r sinφ
z = sqrt(max(0, 1 - r2))
pdf = z / π
Transform (x,y,z) into world space with a basis around n. For Lambert, f cosθ / pdf simplifies cleanly. If the simplified result disagrees with brute-force evaluation, the sampler is wrong.
Noise versus bias
Too few samples produce noise. A missing PDF term or an energy clamp produces bias. Denoisers hide noise. They cannot invent the correct mean of a wrong estimator. Prefer a noisy correct image while debugging.
Temporal behavior
Still frames conceal crawling edges. Camera motion reveals them. Per-frame white noise shimmers. Stable sequences are a later topic. Honesty of the still estimator comes first.
Common errors
- Randomizing only one pixel axis
- Averaging sRGB values instead of linear values
- Hemisphere samples without the matching PDF
- Using
1/Nwhile forgetting1/pdf - Enabling a denoiser before high-sample raw accumulation is trustworthy
If increasing sample count lowers noise without shifting average brightness, the estimator is probably sane.
Expected value intuition
If each sample is an unbiased estimate of pixel radiance, the average of N samples is also unbiased and its variance falls roughly like 1/N for independent samples. That is why four times the samples halves the RMS noise only in the independent case, and why structured samplers can look better sooner. You are estimating an integral. You are not “drawing harder.”
Domain checklist
State the domain before coding a sampler:
- pixel area
- lens disk
- light area
- hemisphere around
n - time interval
Each domain has a measure and a PDF. If you cannot write the PDF, you are not finished designing the sampler.