L(x′→x″)=Le(x′→x′)+∫ALi(x→x′)fs(x→x′→x″)G(x↔x′)dx
into the measurement equation:
I=∫Alens∫AfilmWe(xfilm→xlens)L(xfilm→xlens)G(xfilm↔xlens)dxfilmdxlens
recursive expand it, we get:
I=∑∞k=1∫Ak+1Le(x0→x1)G(x0↔x1)∏k−1i=1fs(xi−1→xi→xi+1)G(xi↔xi+1)
We(xk−1→xk)dA(x0)...dA(xk)
=∫A2Le(x0→x1)G(x0↔x1)We(x0→x1)dA(x0)dA(x1)
+∫A3Le(x0→x1)G(x0↔x1)fs(x0→x1→x2)G(x1↔x2)
We(x1→x2)dA(x0)dA(x1)dA(x2)
+∫A4Le(x0→x1)G(x0↔x1)fs(x0→x1→x2)G(x1↔x2)fs(x1→x2→x3)
G(x2↔x3)We(x2→x3)dA(x0)dA(x1)dA(x2)dA(x3)
+............
In English:
measurement result (radiance)
= integrate all measured value with path length 1 to path length infinity
= integrated path length 1 measured value ( direct visible light)
+ integrated path length 2 measured value ( direct lighting )
+ integrated path length 3 measured value ( first bounce lighting )
+ ....
All these paths can be built by tracing ray from camera or from light, or from both and connect together, there are many (be more specific, n + 1 methods if the path contains n vertices) ways to form a path. We can pick out a length 3 (first bounce, 4 vertices) path x0x1x2x3as case study (for all different lengths it's still the same thing, just feel length 3 is on a sweet spot to cover the idea). Follow Veach's naming convention, s stands for the path vertices start tracing from light, t stands for the path vertices start tracing from camera (or eye). For path length 3, s + t = 4, we have 5 kinds of ways to form the path:
s=0,t=4 trace ray from camera until it hits the light (naive path tracing)
s=1,t=3 trace ray from camera and connect to a sample on light (commonly used path tracing)
s=2,t=2 trace ray from both light and camera, connect them together
s=3,t=1 trace ray from light and connect to a sample on camera lens ( t = 1 style light tracing )
s=3,t=1 trace ray from light and connect to a sample on camera lens ( t = 1 style light tracing )
s=4,t=0 trace ray from light until it hits the camera lens (t = 0 style light tracing )
The function to be integrated for path x0x1x2x3 is the same for any s, t combinations:
f(ˉx)=Le(x0→x1)G(x0↔x1)fs(x0→x1→x2)G(x1↔x2)fs(x1→x2→x3)
G(x2↔x3)We(x2→x3)
The pdf to form the path is different from one combination to another combination though. In Veach97 the pdf usually measured in "projection solid angle" space. It is defined as:
pdfω⊥(x,ω)=pdfω(x,ω)/cosθ
and since we can transform pdf from solid angle space to area space as:
pdfA(x,x′)=pdfω(x,ω)cosθx′/d(x↔x′)2
The introduction of projection solid angle brings the geometry term G into battle:
pdfA(x,x′)=pdfω⊥(x,ω)G(x↔x′)
With this projection solid angle pdfω⊥, the pdfA for different s, t combination can be written as:
pdfA(ˉxs=0,t=4)=pdfA(x3)pdfω⊥(x3→x2)G(x2↔x3)pdfω⊥(x2→x1)G(x1↔x2)
pdfω⊥(x1→x0)G(x0↔x1)
pdfA(ˉxs=1,t=3)=pdfA(x3)pdfω⊥(x3→x2)G(x2↔x3)pdfω⊥(x2→x1)G(x1↔x2)
pdfA(x0)
pdfA(ˉxs=2,t=2)=pdfA(x3)pdfω⊥(x3→x2)G(x2↔x3)pdfω⊥(x1←x0)G(x0↔x1)
pdfA(x0)
pdfA(ˉxs=3,t=1)=pdfA(x3)pdfω⊥(x2←x1)G(x1↔x2)pdfω⊥(x1←x0)G(x0↔x1)
pdfA(x0)
pdfA(ˉxs=4,t=0)=pdfω⊥(x3←x2)G(x2↔x3)pdfω⊥(x2←x1)G(x1↔x2)
pdfω⊥(x1←x0)G(x0↔x1)pdfA(x0)
Divide f(ˉx) by pdfA, we got five different Monte Carlo estimators C∗s,tfor path x0x1x2x3:
C∗0,4=Le(x0→x1)fs(x0→x1→x2)fs(x1→x2→x3)We(x2→x3)pdfA(x3)pdfω⊥(x3→x2)pdfω⊥(x2→x1)pdfω⊥(x1→x0)
C∗1,3=Le(x0→x1)G(x0↔x1)fs(x0→x1→x2)fs(x1→x2→x3)We(x2→x3)pdfA(x3)pdfω⊥(x3→x2)pdfω⊥(x2→x1)pdfA(x0)
C∗2,2=Le(x0→x1)fs(x0→x1→x2)G(x1↔x2)fs(x1→x2→x3)We(x2→x3)pdfA(x3)pdfω⊥(x3→x2)pdfω⊥(x1←x0)pdfA(x0)
C∗3,1=Le(x0→x1)fs(x0→x1→x2)fs(x1→x2→x3)G(x2↔x3)We(x2→x3)pdfA(x3)pdfω⊥(x2←x1)pdfω⊥(x1←x0)pdfA(x0)
C∗4,0=Le(x0→x1)fs(x0→x1→x2)fs(x1→x2→x3)We(x2→x3)pdfω⊥(x3←x2)pdfω⊥(x2←x1)pdfω⊥(x1←x0)pdfA(x0)
all geometry terms got cancelled out except the one that connect end points between light path and eye path. The 5 estimators show beautiful symmetry between each opposite side (s1t3 vs s3t1, s0t4 vs s4t0 ). In fact, Veach made all path length cases into a generalized equation and it is one of the largest building block for bidirectional path tracing:
For a path ˉxs,t=y0...ys−1zt−1...z0, the unweighted contribution can be computed as C∗s,t=αLscs,tαEt, where light path factor:
αL0=1
αL1=L(0)e(y0)/PA(y0)
αLi=fs(yi−3→yi−2→yi−1)Pω⊥(yi−2→yi−1)αLi−1 for i≥2
and eye path factor:
αE0=1
αE1=W(0)e(z0)/PA(z0)
αEi=fs(zi−3→zi−2→zi−1)Pω⊥(zi−2→zi−1)αEi−1 for i≥2
and connection factor:
c0,t=Le(zt−1→zt−2)
cs,0=We(ys−2→ys−1)
cs,t=fs(ys−2→ys−1→zt−1)G(ys−1↔zt−1)fs(ys−1→zt−1→→zt−2) for s,t>0
One notation looks a bit weird is that L(0)e and W(0)e. Veach97 call this "spatial component" and define the radiance/importance as:
Le(y0→y1)=L(0)e(y0)L(1)e(y0→y1)
We(z1→z0)=W(0)e(z0)W(1)e(z1→z0)
fs(y−1→y0→y1)=L(1)e(y0→y1)
fs(z1→z0→z−1)=W(1)e(z1→z0)
The purpose of this notation, according to Veach, is to reduce the number of special cases that need to be considered, by interpreting the directional component of emission as a BSDF. Though personally, I don't feel this particular tempting to me. Writing a branch VS writing another bsdf interface for light and camera, I prefer a branch.
My fingers are aching by typing latex equation now and it's kinda dry to go through the math, but at this point we have all the stuff I need to implement light tracing : importance, filter, path contribution C∗s,t. The next post will focus on the light tracing implementation, and some (not that academic) ways to verify the result.
No comments:
Post a Comment