$$S(x_{i}, \vec{\omega_{i}}, x_{o}, \vec{\omega_{o}}) = S_{d}(x_{i}, \vec{\omega_{i}}, x_{o}, \vec{\omega_{o}}) + S^{(1)}(x_{i}, \vec{\omega_{i}}, x_{o}, \vec{\omega_{o}})$$
The previous few posts all surrounds on the topic about: "how to get \(S_{d}(x_{i}, \vec{\omega_{i}}, x_{o}, \vec{\omega_{o}})\) sample?", "How to get the sample distributed well for importance sampling?" Now we can put these parts all together :) Last look (for now) on the integration equation:
$$L( x_{o},\vec{\omega _{o}} )=\int_{A }\int_{\Omega }L_{i}( x_{i},\vec{\omega _{i}} )S_{d} ( x_{i},\vec{\omega _{i}}, x_{o},\vec{\omega _{o}} )cos\left ( \theta \right )d\omega dA $$
The basic flowchart of this part will be:
1. when intersect a BSSRDF material, start figure out the probe radius \(R_{max}\) (this can be precomputed actually but considering \(\sigma_{a}\) and \(\sigma_{tr}\) may varying in texture space, I made the computation on the fly for now)
2. casting out probe rays for scene intersection test (we can actually just do the intersection test with this particular surface with BSSRDF material instead of intersection test the whole scene. This is a BIG TODO in my mind now for efficiency concern)
3. for each probe ray intersection sample point, calculate the irradiance (the current method is picking light based on power distribution, and only casting one lighting sample for each probe ray intersection, we can definitely do splitting here!(multiple lighting sample with one BSSRDF sample) another BIG TODO item)
4. evaluate \(S_{d}(x_{i}, \vec{\omega_{i}}, x_{o}, \vec{\omega_{o}})=\frac{1}{\pi}F_{r}(\eta, \vec{\omega_{i}})R_{d}(\parallel x_{i}, x_{o} \parallel)F_{r}(\eta, \vec{\omega_{o}})\), the two Fresnel terms can be calculated with ray direction, intersection normal and the refraction index
5. add up the 3. 4. calculation with appropriate MIS weight we mentioned in the previous post, and divide it with corresponding pdf (pick the light, pick the geometry point on light surface, pick the axis, pick the disc sample, the ray/intersection normal dot product, all need to be taken into account)
and here's the naive implementation with the above flowchart:
Lots of stuff can be further optimized at this moment, but let's give it a quick taste on the new dishes :P, with just a little bit seasoning pepper: 25 samples
For comparison I put another simplest Lambert shade version. Same camera/lighting settings, same samples number:
we can see the dark edges(the head and tail part) in BRDF shading got soften a lot in BSSRDF since the lighting contribution from nearby area, also the bumpy body become not that hard lined in BSSRDF version.
Now moving to the single scattering part, as the term suggests, this part simulate the case that light specular refract into medium, encounter a scatter event to change its direction, refract out the medium and enter the camera. (or think in the other way: camera shoot eye rays with importance, refract into the medium, during the travel in the medium, it absorbs photon that emit from light and refract into the medium) The following images illustrate the single scattering idea:
Image taken from Hery 03, the whole radiance received by this eye ray would be the integration alone the refract ray \(\vec{pT_{o}}\) in the medium
Put in Fresnel, scatter event, phase function into accout, Jensen 01 derive the equation for each sample point alone the refracted eye ray:
$$L^{(1)}(x_{o}, \vec{\omega_{o}}) = (\sigma_s(x_{o})Fp(\vec{{\omega_{i}}'},\vec{{\omega_{o}}'})/\sigma_{tc})e^{-{s_{i}}'\sigma_{t}(x_{i})}e^{-{s_{o}}'\sigma_{t}(x_{o})}L_{i}(x_{i}, \vec{\omega_{i}})$$
another round of scary symbol sort:
\(F = F_{r}(x_{o}, \eta)F_{r}(x_{i}, \eta)\) : the Fresnel factor
\(\sigma_{a}\): the absorb coefficient
\(\sigma_{s}\): the scatter coefficient
\(p\): Henry-Greenstein phase function, similar to BRDF for surface, this describe the scatter property for volume
\(\vec{{\omega_{i}}'}\): photon \(L_{i}\) refraction direction
\(\vec{{\omega_{o}}'}\): eye ray refraction direction
\(G = \parallel\vec{n_{x_{i}}}\cdot\vec{{\omega_{o}}'}\parallel/\parallel\vec{n_{x_{i}}}\cdot\vec{{\omega_{i}}'}\parallel\) : geometry factor
\(\sigma_{t}=\sigma_{a} + \sigma_{s}\) : the extinction coefficient
\(\sigma_{tc}=\sigma_{t}(x_{o}) + G\sigma_{t}(x_{i})\) : combined extinction coefficient
\({s_{i}}'\): the refracted photon traveling distance
\({s_{o}}'\): the refracted eye ray traveling distance
For the refract photon distance \({s_{i}}'\), it is actually pretty difficult to sample correctly since there is a specular refraction direction change from the inside medium sample to light sample point. Jensen proposed an approximation for the true refracted distance with Snell's law:
$${s_{i}}'=s_{i}\frac{\parallel\vec{n_{x_{i}}}\cdot\vec{\omega_{i}}\parallel}{\sqrt{1-(\frac{1}{\eta})^2(1-\parallel\vec{n_{x_{i}}}\cdot\vec{\omega_{i}}\parallel^2)}}$$
where \(s_{i}\) is the distance between sample point in medium to light sample point minus the part this ray is not in the medium.
Jensen also suggested that we importance sampling alone the eye ray with \(pdf(d) = \sigma_{t}e^{-\sigma_{t}d}\) since the exponential attenuation alone the medium. This 1D sample was covered in previous post , so we are pretty much ready to go!
The flowchar for single scattering will be:
1. when intersect a BSSRDF material, change the ray direction with specular refraction
2. alone the refraction ray sample point with 1D exponential falloff
3. for each sample point from 2. , sample light source and casting shadow ray to see if there is other geometry blocking the light besides the current medium (need to be a little bit careful on this part when playing around with the shadow ray length)
4. approximate \({s_{i}}'\) with Snell's law, evaluate Fresnel term and phase function
put them into codes:
and we got the single scattering part :) (Though we still face the similar further optimization in TODO list like splitting and direct surface intersection test)
One more! in Jensen 01's final demo image marble bust he added a Fresnel reflection pass. Though it's not necessary, I feel that shiny sparkling highlight is pretty charming. Plus, we already have that in our BRDF, so I just directly plug it into the new Subsurface material:
All the jigsaw pieces are put in place now. Finally! Put them altogether, we have this shiny marble cutie :)
So how's the multiple importance sampling benefit we have? That's actually the most exciting part! For comparison, I render another image with sample alone normal axis only without multiple importance sampling, same 25 samples.
And the side by side comparison (left side no MIS, right side with MIS):
In the highly curvy surface, The MIS version did a pretty good job removing those most noticeable variance noise, while in the relatively flat surface(the dragon right side body part), project all samples alone normal has a better result. Kulla 13 did mentioned about this part that there will be performance lost in overall flat surface since we would have extra wasted sample projected alone dpdu/dpdv and intersect nothing. The algorithm generally remove the spiky high variance but introduce some relatively more uniform variance, which is easier to converge when the sample amount got cranked up.
Image taken from Kulla 13, explains the issue that MIS doesn't work particular well for overall flat surface
No comments:
Post a Comment