Page tree

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Integrators (RixIntegrator) uses RixBxdfFactory objects by invoking RixBxdfFactory::BeginScatter()  to obtain a  RixBxdf,  parameterized by the bxdf's potentially varying input parameters.  RixBxdfFactory::BeginScatter()  is expected to invoke  RixShadingContext::EvalParam() for the relevant bxdf parameters. The bxdf acts as a closure, associated with a given shading context.  BeginScatter() will typically call a Bxdf constructor which will get the necessary built-in variables such as shading normal (Nn), geometric normal (Ngn), viewing direction (Vn), etc., by calling the GetBuiltinVar() function for each variable.

RixBxdf

Once a RixBxdf object is obtained, the integrator may invoke the following methods:

...

The GenerateSample() function has the following input parameters: transportTrait, lobesWanted, and random number generator. The transportTrait tells the Bxdf the subset of light transport to consider: direct illumination, indirect illumination, or both. lobesWanted specifies what lobes are requested, for example specular reflection, diffuse transmission, etc. The random number generator should be called to generate well-stratified samples; such samples typically reduce noise and improve convergence compared to using uniform random samples.

The GenerateSample() function has the following output parameters (results): lobeSampled, Lndirection, weight, forward pdf, reverse pdf, and compTrans.  lobeSampled  lobeSampled is similar to the input lobesWanted, and specifies which lobe was actually sampled. direction (Ln) is the generated ray direction vectors; these directions must have unit length. Weight weight is a color per sample indicating that sample's weight. The forward pdf should account for light moving from the L to V direction where as the reverse pdf account for the opposite (from V to L). Bxdfs should always provide both pdf values for the integrators to use. compTrans is an optional result which can be used to indicate transmission color; this will be used as alpha in compositing. AllA bxdf should check that compTrans is not NULL before assigning to it.  All results are arrays with one value per sample point.

As an example, a purely Lambertian diffuse bxdf should ... Ln is cosine distribution over hemisphere ... weight is albedo ... forward pdf ... reverse pdf ..loop over the sample points and for each sample point set the result values as follows: set lobeSampled to diffuse reflection, set the reflection direction to a randomly generated direction chosen with a cosine distribution on the hemisphere defined by the surface normal (using a well-stratified 2D "random" sample value generated by calling the provided random number generator), set the weight to the diffuse surface albedo color times dot(Nn, L) divided by pi, set the forward pdf to dot(Nn, Ln) divided by pi, and set the reverse pdf to dot(Nn, Vn). More details can be found in the source code for the PxrDiffuse bxdf.

The parameters to the EvaluateSample() function are very similar: transportTrait, lobesWanted, random number generator, lobesEvaluated, direction, weight, forward pdf and reverse pdf.  The main difference is that direction (Ln) is an array of inputs that the function should compute weights and pdfs for.

The EvaluateSamplesAtIndex() function is very similar to EvaluateSample(), but is used to evaluate multiple samples at the same surface position and normal, but with different illumination directions (Ln). The inputs are the same as for EvaluateSample(), except that it has two additional inputs: index and number of samples. index is used to index into built-in variables such as the normal Nn and viewing direction Vn, and number of samples is the number of directions (Ln) to evaluate the bxdf for. The functionality of EvaluateSamplesAtIndex()–  the former only exists to make sample evaluation more efficient in certain light transport settings.

Bxdfs that do not scatter light (e.g. PxrConstant) should disable all lobes and set the forward pdf and reverse pdf to zero.

In order to maintain physical correctness, bxdfs are expected to conserve energy and obey the Helmholtz reciprocity. Care should be taken so that RixBxdf::GenerateSample()RixBxdf::EvaluateSample() and RixBxdf::EvaluateSamplesAtIndex() return consistent results. This allows bxdf plugins to be compatible with different rendering techniques such as:

...