② Derive importance functions and implement the
CameraWe(), Pdf_We(), Sample_Wi(), and
Pdf_Wi() methods for one or more of EnvironmentCamera,
OrthographicCamera, or RealisticCamera. Render images using
bidirectional path tracing or MMLT and show that given sufficient samples,
they converge to the same images as when the scene is rendered with
standard path tracing.
② Discuss situations where the current methods for sampling
outgoing rays from ProjectionLights and GonioPhotometricLights may be
extremely inefficient, choosing many rays in directions where the light
source casts no illumination. Use the Distribution2D structure to
implement improved sampling techniques for each of them based on sampling
from a distribution based on the luminance in their
2D image maps, properly accounting for the
transformation from the 2D image map sampling distribution to the
distribution of directions on the sphere. Verify that the system still
computes the same images (modulo variance) with your new sampling
techniques when using an Integrator that calls these methods.
Determine how much efficiency is improved by using these sampling methods
instead of the default ones.
③ Implement Walter et al.’s lightcuts algorithm in
pbrt (Walter et al. 2005, 2006). How do the BSDF interfaces in
pbrt need to be generalized to compute the error terms for lightcuts? Do
other core system interfaces need to be changed? Compare the efficiency of
rendering images with global illumination using your implementation to some
of the other bidirectional integrators.
① Experiment with the parameters to the SPPMIntegrator
until you get a good feel for how they affect rendering time and the
appearance of the final image. At a minimum, experiment with varying the
search radius, the number of photons traced, and the number of iterations.
② Another approach to improving the efficiency of photon
shooting is to start out by shooting photons from lights in all directions
with equal probability but then to dynamically update the probability of
sampling directions based on which directions lead to light paths that have
high throughput weight and end up being used by visible points.
Photons then must be reweighted based on the probability for shooting a
photon in a particular direction. (As long as there is always nonzero
probability of sending a photon in any direction, this approach doesn’t
introduce additional bias into the shooting algorithm.) Derive and
implement such an approach. Show that in the limit, your modified
SPPMIntegrator computes the same results as the original. How much
do these changes improve the rate of convergence?
② The SPPMIntegrator ends up storing all of the BSDFs
along camera paths to the first visible point, even though only the last
BSDF is needed. First, measure how much memory is used to store
unnecessary BSDFs in the current implementation for a variety of scenes.
Next, modify the VisiblePoint representation to store the
reflectance, BSDF::rho(), at visible points and then compute
reflection assuming a Lambertian BSDF. Does this approximation introduce
visible error in test scenes? How much memory is saved?
② To find the VisiblePoints around a photon–surface
intersection, the SPPMIntegrator uses a uniform grid to store the
bounding boxes of visible points expanded by their radii. Investigate other
spatial data structures for storing visible points that support efficient
photon/nearby visible point queries, and implement an alternate
approach. (You may want to specifically consider octrees and kd-trees.)
How do performance and memory use compare to the current implementation?
② Implement “final gathering” in the
SPPMIntegrator, where camera rays are followed for one more bounce
after hitting a diffuse surface. Investigate how many iterations and how
many photons per iteration are needed to get good results with this
approach for a variety of scenes compared to the current implementation.
② There is actually one case where collisions from the
hash() function used by the SPPMIntegrator can cause a problem:
if, for example, nearby voxels have a collision, then a VisiblePoint
that overlaps both of them will be placed in a linked list twice, and then
a photon that is close to them will incorrectly contribute to the pixel’s
value twice. Can you prove that this will never happen for the current
hash function? If it does happen, can you construct a scene where the error
makes a meaningful difference in the final image? How might this problem be
addressed?
③ Extend the SPPM integrator to support volumetric
scattering. First, read the papers by Knaus and Zwicker (2011) and
Jarosz et al. (2011b) and choose one of these approaches. Compare the
efficiency and accuracy of images rendered with your implementation to
rendering using the bidirectional path tracer or the MMLT integrator.
② One shortcoming of the current SPPMIntegrator
implementation is that it’s inefficient for scenes where the camera is only
viewing a small part of the overall scene: many photons may need to be
traced to find ones that are visible to the camera. Read the paper by
Hachisuka and Jensen (2011) on using adaptive Markov chain sampling to
generate photon paths and implement their approach. Construct a scene
where the current implementation is inefficient and your new one does much
better, and render comparison images using equal amounts of computation for
each. Are there any scenes where your implementation computes worse
results?
③ Extend the BDPT integrator to support subsurface scattering with
BSSRDFs. In addition to connecting pairs of vertices by evaluating the
geometric term and BSDFs, your modified integrator should also evaluate the
BSSRDF when two points are located on an object with
the same Material with a non-nullptr-valued BSSRDF.
Since two connection techniques lead to paths with a fundamentally different
configuration—straight-line transport versus an additional subsurface
scattering interaction on the way from on —their area product
density should never be compared to each other when computing multiple
importance sampling weights.
② Implement Russian roulette to randomly skip tracing
visibility rays for low-contribution connections between subpaths in
the ConnectBDPT() function. Measure the change in Monte Carlo
efficiency compared to the current BDPTIntegrator implementation.
② Modify the BDPT integrator to use the path space
regularization technique described by Kaplanyan and Dachsbacher (2013b). (Their method makes it possible for light transport algorithms
based on incremental path construction to still handle difficult sampling
cases based on chains of specular interactions.) Construct a scene where
this approach is useful, and render images to compare results between this
approach, SPPM, and an unmodified bidirectional path tracer.
② By adding mutation strategies that don’t necessarily
modify all of the sample values , it can be possible to reuse
some or all of the paths generated by the previous samples in the
MLTIntegrator. For example, if only the PrimarySample values
for the light subpath are mutated, then the camera subpath can be
reused. (An analogous case holds for the light subpath.) Even if a
mutation is proposed for a subpath, if the samples for its first few
vertices are left unchanged, then that portion of the path doesn’t need to
be retraced.
Modify the MLTIntegrator to add one or more of the above
sampling strategies, and update the implementation so that it reuses any
partial results from the previous sample that remain valid when your new
mutation is used. You may want to add both “small step” and “large
step” variants of your new mutation. Compare the mean squared error of
images rendered by your modified implementation to the MSE of images rendered
by the original implementation, comparing to a reference image rendered
with a large number of samples. For the same number of samples, your
implementation should be faster but will likely have slightly higher error
due to additional correlation among samples. Is the Monte Carlo
efficiency of your modified version better than the original
implementation?
③ In his Ph.D. dissertation, Hoberock proposes a number of
alternative scalar contribution functions for Metropolis light transport,
including ones that focus on particular types of light transport and ones
that adapt the sample density during rendering in order to reduce
perceptual error (Hoberock 2008). Read Chapter 6 of his
thesis, and implement either the multistage MLT or the noise-aware MLT
algorithm that he describes.