Rendering Equation & Monte Carlo Path Tracing I CS295, Spring 2017 Shuang Zhao Computer Science Department University of California, Irvine CS295, Spring 2017 Shuang Zhao 1
Announcements Homework 1 due tonight! Programming Assignment 1 is out and will be due in 1.5 weeks on May 2 CS295, Spring 2017 Shuang Zhao 2
Previous Lectures The behavior of light Radiometry Monte Caro integration General framework Sampling from PDFs CS295, Spring 2017 Shuang Zhao 3
Today s Lecture Rendering equation Describe the distribution of light at equilibrium Monte Carlo Path Tracing I An unbiased numerical solution to the rendering equation CS295, Spring 2017 Shuang Zhao 4
The Rendering Equation CS295: Realistic Image Synthesis Rendering Equation & Monte Carlo Path Tracing I CS295, Spring 2017 Shuang Zhao 5
Recap: Radiometry Measurement of light energy Radiometric quantities Energy Power (radiant flux) Irradiance & radiosity Radiance CS295, Spring 2017 Shuang Zhao 6
Light Transport Goal Describe steady-state radiance distribution in virtual scenes Assumptions Geometric optics Achieves steady state instantaneously CS295, Spring 2017 Shuang Zhao 7
Radiance at Equilibrium Radiance values at all points in the scene and in all directions expresses the equilibrium 5D Light-field We only consider radiance on surfaces (4D) Assuming no volumetric scattering or absorption CS295, Spring 2017 Shuang Zhao 8
Rendering Equation (RE) RE describes the distribution of radiance at equilibrium RE involves: Scene geometry Light source info. Surface reflectance info. Radiance values at all surface points in all directions (Known) (Unknown) CS295, Spring 2017 Shuang Zhao 9
Rendering Equation (RE) = + = + CS295, Spring 2017 Shuang Zhao 10
Rendering Equation Incoming radiance CS295, Spring 2017 Shuang Zhao 11
Rendering Equation (Invariant of radiance along lines) CS295, Spring 2017 Shuang Zhao 12
Monte Carlo Path Tracing I CS295: Realistic Image Synthesis Rendering Equation & Monte Carlo Path Tracing I CS295, Spring 2017 Shuang Zhao 13
Path Tracing (Version 0) Estimating L r using MC integration: Draw ω i uniformly at random p(ω i ) = 1/(2π) CS295, Spring 2017 Shuang Zhao 14
Path Tracing (Version 0) radiance(x, ω): return emittedradiance(x, ω) + reflectedradiance(x, ω) reflectedradiance(x, ω): ω i = uniformrandom(n x ) y = RayTrace(x, ω i ) return 2.0 * π * radiance(y, -ω i ) * brdf(x, ω i, ω) * dot(n x, ω i ) CS295, Spring 2017 Shuang Zhao 15
uniformrandom uniformrandom(n): z = rand() r = sqrt(1.0 - z * z) φ = 2.0 * π * rand() x = r * cos(φ) y = r * sin(φ) [u, v, w] = createlocalcoord(n) return x * u + y * v + z * w [x, y, z] distributes uniformly on the hemisphere around [0, 0, 1] createlocalcoord(n) returns a local (orthogonal) coordinate system around n CS295, Spring 2017 Shuang Zhao 16
Path Tracing (Version 0.1) Estimating L r using MC integration: Randomly sample ω i using a probability density proportional to i.e., CS295, Spring 2017 Shuang Zhao 17
Path Tracing (Version 0.1) Estimating L r using MC integration: CS295, Spring 2017 Shuang Zhao 18
Path Tracing (Version 0.1) radiance(x, ω): return emittedradiance(x, ω) + reflectedradiance(x, ω) reflectedradiance(x, ω): ω i = uniformrandompsa(n x ) y = RayTrace(x, ω i ) return π * radiance(y, -ω i ) * brdf(x, ω i, ω) CS295, Spring 2017 Shuang Zhao 19
uniformrandompsa uniformrandompsa(n): z = sqrt(rand()) r = sqrt(1.0 - z * z) φ = 2.0 * π * rand() x = r * cos(φ) y = r * sin(φ) [u, v, w] = createlocalcoord(n) return x * u + y * v + z * w [x, y] distributes uniformly on a unit disc centered at [0, 0] createlocalcoord(n) returns a local (orthogonal) coordinate system around n CS295, Spring 2017 Shuang Zhao 20
Path Tracing (Version 0.1) radiance(x, ω): return emittedradiance(x, ω) + reflectedradiance(x, ω) reflectedradiance(x, ω): ω i = uniformrandompsa(n x ) y = RayTrace(x, ω i ) return π * radiance(y, -ω i ) * brdf(x, ω i, ω) CS295, Spring 2017 Shuang Zhao 21
Path Tracing (Version 0.1) radiance(x, ω): rad = emittedradiance(x, ω) ω i = uniformrandompsa(n x ) y = RayTrace(x, ω i ) rad += π * radiance(y, -ω i ) * brdf(x, ω i, ω) return rad CS295, Spring 2017 Shuang Zhao 22
Path Tracing (Version 0.1) Light source CS295, Spring 2017 Shuang Zhao 23
Path Tracing (Version 0.1) Light source CS295, Spring 2017 Shuang Zhao 24
Path Tracing (Version 0.5) Monte Carlo Path Tracing I CS295, Spring 2017 Shuang Zhao 25
Path Tracing (Version 0.1) radiance(x, ω): rad = emittedradiance(x, ω) ω i = uniformrandompsa(n x ) y = RayTrace(x, ω i ) rad += π * radiance(y, -ω i ) * brdf(x, ω i, ω) return rad Problem: infinite recursion! CS295, Spring 2017 Shuang Zhao 26
Avoid Infinite Recursion Idea 1: bounding the depth radiance(x, ω, depth): if depth > maxdepth: return 0.0 rad = emittedradiance(x, ω) ω i = uniformrandompsa(n x ) y = RayTrace(x, ω i ) rad += π * radiance(y, -ω i, depth + 1) * brdf(x, ω i, ω) return rad Problem: biased CS295, Spring 2017 Shuang Zhao 27
Avoid Infinite Recursion Idea 2: Russian roulette Pick survival probability, a constant within (0, 1) radiance(x, ω): rad = emittedradiance(x, ω) if rand() < survivalprobability: ω i = uniformrandompsa(n x ) y = RayTrace(x, ω i ) rad += π * radiance(y, -ω i ) * brdf(x, ω i, ω) / survivalprobability return rad Why does this work? CS295, Spring 2017 Shuang Zhao 28
Russian Roulette For any random variable X, let for some 0 < p < 1, then Pros: estimators of Y will always terminate Cons: increased variance (noise) CS295, Spring 2017 Shuang Zhao 29
Path Tracing (Version 0.5) radiance(x, ω, depth): rad = emittedradiance(x, ω) if depth <= rrdepth: p = 1.0 else: p = survivalprobability if rand() < p: ω i = uniformrandompsa(n x ) y = RayTrace(x, ω i ) rad += π * radiance(y, -ω i, depth + 1) * brdf(x, ω i, ω) / p return rad CS295, Spring 2017 Shuang Zhao 30
Path Tracing (Version 1.0) Monte Carlo Path Tracing I CS295, Spring 2017 Shuang Zhao 31
Challenge Small light source leads to high noise Because the probability for a light path to hit the light source is small 64 samples per pixel CS295, Spring 2017 Shuang Zhao 32
Idea: Separating Direct & Indirect Indirect Direct CS295, Spring 2017 Shuang Zhao 33
Idea: Separating Direct & Indirect radiance(x, ω, depth): return emittedradiance(x, ω) + reflectedradiance(x, ω, depth) reflectedradiance(x, ω, depth): return directradiance(x, ω) + indirectradiance(x, ω, depth) CS295, Spring 2017 Shuang Zhao 34
Direct Radiance Direct CS295, Spring 2017 Shuang Zhao 35
Indirect Radiance Indirect CS295, Spring 2017 Shuang Zhao 36
Summary: Direct + Indirect L = L e + L r This idea is usually called next-event estimation (more on this later) CS295, Spring 2017 Shuang Zhao 37
Estimating Indirect Radiance Almost identical to our reflected radiance estimator version 0.5 indirectradiance(x, ω, depth): if depth <= rrdepth: p = 1.0 else: p = survivalprobability if rand() < p: ω i = uniformrandompsa(n x ) y = RayTrace(x, ω i ) return π * reflectedradiance(y, -ω i, depth + 1) * brdf(x, ω i, ω) / p else: return 0.0 CS295, Spring 2017 Shuang Zhao 38
Estimating Direct Radiance Idea: sampling the light source Solid angle integral area integral Change of measure CS295, Spring 2017 Shuang Zhao 39
Area Integral A e : surfaces of all light sources V(x, y): visibility term describing if x and y are mutually visible (visible) (occluded) CS295, Spring 2017 Shuang Zhao 40
Area Estimator Sample y uniformly from A e p(y) = 1/S e S e denotes the surface area of A e E.g., for one spherical light source with radius r, S e = 4πr 2 CS295, Spring 2017 Shuang Zhao 41
Estimating Direct Radiance directradiance(x, ω): [y, pdf] = luminairesample() ω i = normalize(y - x) r 2 = dot(y - x, y - x) return emittedradiance(y, -ω i ) * brdf(x, ω i, ω) * visibility(x, y) * dot(n x, ω i ) * dot(n y, -ω i ) / (r 2 * pdf) CS295, Spring 2017 Shuang Zhao 42
Path Tracing (Version 1.0) reflectedradiance(x, ω, depth): return directradiance(x, ω) + indirectradiance(x, ω, depth) directradiance(x, ω): [y, pdf] = luminairesample() ω i = normalize(y - x) r 2 = dot(y - x, y - x) return emittedradiance(y, -ω i ) * brdf(x, ω i, ω) * visibility(x, y) * dot(n x, ω i ) * dot(n y, -ω i ) / (r 2 * pdf) indirectradiance(x, ω, depth): if depth <= rrdepth: p = 1.0 else: p = survivalprobability if rand() < p: ω i = uniformrandompsa(n x ) y = RayTrace(x, ω i ) return π * reflectedradiance(y, -ω i, depth + 1) * brdf(x, ω i, ω) / p else: return 0.0 CS295, Spring 2017 Shuang Zhao 43
Path Tracing (Version 1.0) reflectedradiance(x, ω, depth): [y 1, pdf] = luminairesample() ω 1 = normalize(y 1 - x) r 2 = dot(y 1 - x, y 1 - x) reflrad = emittedradiance(y 1, -ω 1 ) * brdf(x, ω 1, ω) * visibility(x, y 1 ) * dot(n x, ω 1 ) * dot(n y, -ω 1 ) / (r 2 * pdf) if depth <= rrdepth: p = 1.0 else: p = survivalprobability if rand() < p: ω 2 = uniformrandompsa(n x ) y 2 = RayTrace(x, ω 2 ) reflrad += π * reflectedradiance(y 2, -ω 2, depth + 1) * brdf(x, ω 2, ω) / p return reflrad CS295, Spring 2017 Shuang Zhao 44
Equal-Sample Comparison (Both at 64 sample paths per pixel) Path tracing version 0.5 Path tracing version 1.0 CS295, Spring 2017 Shuang Zhao 45
Next Lecture Monte Carlo Path Tracing II CS295, Spring 2017 Shuang Zhao 46