Page tree

Versions Compared

Key

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

...

  • lobeSampled is similar to the input lobesWanted, and specifies which lobe was actually sampled. Bxdfs must respect the transportTrait and lobesWanted request and indicate which class of lobe is associated with each sample by setting lobesSampled for each generated sample. If and only if the bxdf is unable to generate a requested sample, then lobesSampled should be set to k_RixBXNullTraitmarked as invalid by calling SetValid(false); for example, if the lobesWanted argument requests a specific lobe (e.g., diffuse reflection) that the Bxdf does not support because the Bxdf only supports glossy reflections, then lobesSampled should be set to k_RixBXNullTrait[i].SetValid(false) should be called. However, if it is possible to generate the requested samples, then lobesSampled should not be set to k_RixBXNullTrait and marked invalid and should instead be set to the sampled lobe for each point in the shading context. 

    When generating a Bxdf sample, you can also run into corner cases (often legitimate cases) where a valid sample cannot be generated. For instance, if the camera ray hits the backside of a single-sided object, a valid sample cannot be generated. Therefore, the lobeSampled for this camera ray should also be marked as invalid in this case by calling SetValid(false).

    If an invalid sample is returned to the integrator, the integrator will terminate the ray and avoid any further computation. Bxdfs that do not scatter light (e.g. PxrConstant) should also mark all samples as invalid.

    Note

    There is a subtle difference between an invalid sample and a black sample. If a camera ray hits a diffuse black surface, the sample will have zero contribution to the final image despite being valid. It would make sense for the integrator to terminate the ray because further bounces will not contribute to the final image either, but it is important to splat the black contribution to both the beauty and alpha channel. Failing to do so might result in missing geometry in the rendered image. An invalid sample on the other hand, should not only be terminated but also ignored for splatting purposes.


  • directions is the generated ray direction vectors; these directions must be unit length. 
  • weights is a color per sample indicating that sample's weight. 
  • forwardPdfs should account for light moving from the L to V direction, whereas reversePdfs account for the opposite (from V to L). Bxdfs should always provide both pdf values for integrators to use. Bxdfs that do not scatter light (e.g. PxrConstant) should set both pdfs to zero.
  • compTrans is an optional result which can be used to indicate transmission color; this will be used as alpha in compositing. A bxdf should check that compTrans is not NULL before assigning to it.  

As an example, a purely Lambertian diffuse bxdf should 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, Ln) 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.

Sample Evaluation

The parameters to the EvaluateSample() function are very similar to GenerateSample()transportTraitlobesWanted, random number generator rnglobesEvaluateddirectionsweightsforwardPdfs and reversePdfs.  The main difference is that directions is an array of inputs that the function should compute weights and pdfs for.

...