...
To tie this all together, here's some pseudo code to convey the RixIntegrator requirements for the tracing of volume-aware indirect rays:
Code Block | ||
---|---|---|
| ||
// ictx is a RixIntegratorContext associated with primary camera rays
// sctx is a RixShadingContext associated with a group of hit points
// requiring shading. We are tracing the indirect rays traced by the
// the sctx. The bxdf GenerateSamples method has already been executed
// on the sctx to determine the directions of these rays as well as
// whether or not the rays transmit into the surface.
if (!sctx->HasVolume(k_AnyVolume))
ictx->GetNearestHits(...);
else
// Group the rays into 2 bundles: transmit and reflect.
// This can be accomplished by checking the lobeSampled.GetTransmit()
// flag on the ray
RixVolumeIntegrator *volint;
if( transRays)
{
volint = sctx->BeginOppositeVol(transRays.size(), transRays);
if(volint)
volint->GetNearestHits(...);
sctx->EndVolume(volint);
else
ictx->GetNearestHits(...);
}
if (reflRays)
{
volint = sctx->BeginIncidentVol(reflRays.size(), reflRays);
if(volint)
volint->GetNearestHits(...);
sctx->EndVolume(volint);
else
ictx->GetNearestHits(...);
} |
...
Volume Closures
Similar to RixBxdf
, RixVolumeIntegrators
are closures that are created by a subclass of RixBxdfFactory
- in this case, by a call to RixBxdfFactory::BeginInterior()
. At the time that BeginInterior()
is called, a shading context is bound to the RixVolumeIntegrator
. Pattern graph evaluation via EvalParam()
may occur during BeginInterior()
to evaluate any needed inputs to the volume integrator that may be used by GetNearestHits()
or GetTransmission()
. Hence, any outputs from these pattern graph evaluations should be saved explicitly by the plugin until these routines (GetNearestHits()/GetTransmission
) are called (hence our use of the term closure).
...