Page tree

Versions Compared

Key

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

...

As mentioned above, integrators invoke RixBxdfFactory::BeginScatter() to obtain a RixBxdf. The renderer's operating model is that the Bxdf that is obtained this way is a closure, with the closure functions being GenerateSampleEvaluateSample, and EmitLocaland EmitLocal. Any  Any computations that the Bxdf needs need in order to efficient evaluate its closure functions should be computed once inside RixBxdfFactory::BeginScatter(), and then saved in the overridden RixBxdf class. Critically, these computations include upstream evaluation of any pattern networks. Therefore, it is typical for BeginScatter() to invoke  RixShadingContext::EvalParam() in order to evaluate the relevant bxdf input parameters, and then pass the pointers returned from EvalParam to the Bxdf constructor. Since Bxdfs also generally require geometric data, or built-in variables, such as the shading normal, geometric normal, and viewing direction, either BeginScatter() or the Bxdf constructor itself will need to call RixShadingContext::GetBuiltinVar() function for each such built-in variable.

...

Code Block
languagecpp
RixBxdf *
PxrConstant::BeginScatter(RixShadingContext const *sCtx,
                          RixBXLobeTraits const &lobesWanted,
                          RixSCShadingMode sm,
                          RtPointer instanceData)
{
    // Get all input data
    RtColorRGB const* emitColor; 
    sCtx->EvalParam(k_emitColor, -1, &emitColor, &m_emitColor, true);
    RixShadingContext::Allocator pool(sCtx);
    void *mem = pool.AllocForBxdf<ConstantBxdf>(1);
    ConstantBxdf *eval = new (mem) ConstantBxdf(sCtx, this, lobesWanted, emitColor);
    return eval;
}


In the following code from PxrDiffuse, we demonstrate how its constructor sets up required geometric information that is later on used for sample generation and evaluation.


Code Block
languagecpp
    PxrDiffuse(RixShadingContext const *sc, RixBxdfFactory *bx, 
               RixBXLobeTraits const &lobesWanted,
               RtColorRGB const *emit, 
               RtColorRGB const *diff, 
               RtColorRGB const *trans,
               RtNormal3 const *bumpNormal) : 
        RixBxdf(sc, bx), 
        m_lobesWanted(lobesWanted),
        m_emit(emit),
        m_diffuse(diff),
        m_transmission(trans),
        m_bumpNormal(bumpNormal)
    {
        RixBXLobeTraits lobes = s_reflDiffuseLobeTraits | s_albedoLobeTraits;
        if (m_transmission)
            lobes |= s_tranDiffuseLobeTraits;

        m_lobesWanted &= lobes;

        sc->GetBuiltinVar(RixShadingContext::k_P, &m_P);
        if(m_bumpNormal)
            m_Nn = bumpNormal;
        else
            sc->GetBuiltinVar(RixShadingContext::k_Nn, &m_Nn);
        sc->GetBuiltinVar(RixShadingContext::k_Ngn, &m_Ngn);
        sc->GetBuiltinVar(RixShadingContext::k_Tn, &m_Tn);
        sc->GetBuiltinVar(RixShadingContext::k_Vn, &m_Vn);
    }


BeginScatter() is passed an instance data pointer created via CreateInstanceData that can be used to cache and reuse certain calculations common amongst all factory instances of the same Bxdf; for more information, please consult the lightweight instancing discussion in RixShadingPlugin.

BeginScatter() is also passed two parameters that can be used as hints to optimize the calculation. RixBXLobeTraits const &lobesWanted is a description of the Bxdf lobes that the renderer expects to generate or evaluate; this parameter can be used to avoid any computations not necessary for the requested lobes. RixSCShadingMode will take either the value k_RixSCScatterQuery, indicating that the factory should construct a Bxdf for scattering on the surface, or k_RixSCVolumeScatterQuery, indicating that a Bxdf should be constructed for scattering on the inside of a volume. 

RixBxdf

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

...