Anisotropic Phase Function (5pts)

Implementation

Added files:

  • phase.h
  • heyneygreenstein.cpp

For the implementation of the phase function, I closely followed the approach described in PBRv3. For this, I first had to add an interface phase.h that all phase functions have to be a subclass of. This interface specifies all methods a phase function implementation has to offer, the most important ones being p() and Sample_p(). The first one returns the evaluation of the henyey greenstein function (HG function) given two directions wi and wo. Conceptually, this is the analogon for phase functions to the eval() method of the bsdfs. Because the HG function integrates to one, the function p() can be used to get the probability to sample the direction wo given wi as well. The second method takes wi as a parameter and first perfectly importance samples the HG function. Then it returns an outgoing direction wo constructed from this sample. Here it is important to transform wo back to world coordinates before returning it, as after sampling it its coordinates are in the local frame spanned by wi.

The phase function can be added in the xml as a child of a medium. It takes one parameter: the value g. The syntax is as follows:

<medium type="homogeneous"> ... <!-- can be omitted, in which case an isotropic phase function (g = 0) will be instantiatet --> <phase type="henyeygreenstein"> <float name="g" value="0.8" /> </phase> ... </medium>

Validation

I validated my implementation by comparing with Mitsuba and varying the g parameter. Since mitsuba uses a MIS integrator, I use a lot higher samples per pixels for my images and the noise generally looks worse.

g = -0.8

Nori Mitsuba

Isotropic (g = 0)

Nori Mitsuba

g = 0.8

Nori Mitsuba