Page tree

Versions Compared

Key

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

Pure-virtual and default implementation in the RixShadingPlugin API

Note

Because the RixShadingPlugin API and the associated subclasses (RixBxdf, etc...) also contain non-pure virtual methods, it is strongly recommended to use the C++ keyword override when overriding methods of the API.

Interactive editing and Options / Render State queries.

RenderMan 23 introduces the possibility of editing displays and LPEs during an interactive rendering session, without needing to restart the entire rendering session (e.g. translate the entire scene again).

...

Note

The restriction to RixLPEInfo implies that functions like RixBXLookupLobeByName shouldn't be called in Init() or CreateInstanceData() either. This function should usually be called in Synchronize().

RixPlugin::CreateInstanceData() and RixPlugin::SynchronizeInstanceData()

Plugin Instance Initialization

...

Code Block
languagecpp
void MyBxdfFactory::CreateInstanceData(RixContext& ctx, RtUString const handle,
                                       RixParameterList const* plist, InstanceData* result)
{
    // We do not allocate any memory for the private instance data here. This is done for each
    // render in SynchronizeInstanceData().

    // We want SynchronizeInstanceData() to be called in all cases.
    result->synchronizeHints = RixShadingPlugin::SynchronizeHints::k_All;
}

void MyBxdfFactory::SynchronizeInstanceData(RixContext& ctx, RtUString const handle,
                                            RixParameterList const* plist, uint32_t editHints,
                                            InstanceData* result)
{
    // Because this method is called before each render, we need to make sure we properly delete
    // the private instance data that was created for the previous render.
    if (result->data && result->freefunc)
    {
        (result->freefunc)(result->data);
    }

    MyInstanceData* data = new MyInstanceData;

    // This method uses the RixRenderState object to query options values, that are then stored in
    // the `data` structure.
    RixRenderState* rst = (RixRenderState*)ctx.GetRixInterface(k_RixRenderState);
    doSomething(rst, data);

    result->data = data;
    result->freefunc = &ReleaseMyInstanceData;
}

RixProjectionFactory::CreateProjection() and RixProjection::RenderBegin()

For similar reasons, the RixProjection API has changed. Previously, the RixIntegratorEnvironment structure was provided to RixProjectionFactory::CreateProjection():

Code Block
    virtual RixProjection* CreateProjection(
        RixContext& ctx,
        RixProjectionEnvironment& env,
        RtUString const handle,
        RixParameterList const* pList) = 0;

In order for a RixProjection object to respond to edits affecting the RixIntegratorEnvironment structure, a new API has been introduced: RixProjection::RenderBegin(). Note that we do not pass RixIntegratorEnvironment to CreateProjection() anymore:

Code Block
class RixProjectionFactory : public RixShadingPlugin
{
// ...
    virtual RixProjection* CreateProjection(
        RixContext& ctx,
        RtUString const handle,
        RixParameterList const* pList) = 0;
// ...
};


class RixProjection
{
// ...
    virtual void RenderBegin(RixContext& ctx, RixProjectionEnvironment const& env,
                             RixParameterList const* instanceParams) = 0;
// ...
};

Any code previously in the RixProjection constructor that was using RixIntegratorEnvironment should now live in RixProjection::RenderBegin().

RixIntegratorEnvironment::deepMetric

Previously, the projection plugins were allowed to modify the value of RixIntegratorEnvironment::deepMetric during the creation of the RixProjection object. This is not the case anymore, and in RixProjection::RenderBegin(), this structure is now read-only.

Projection plugins should now use the a RixProjection::GetProperty() mechanism to communicate a particular metric to the renderer (similarly to what was already happening for RixProjection::DicingHint):

Code Block
class RixProjection
{
public:
// ...
    /// Expresses depth metric to use for samples in deep output.  Set to k_cameraZ for standard
    /// perspective or orthographic projections. Use k_rayLength for spherical, cylindrical,
    /// etc... with -Z rays.
    /// Default value (if no value is returned) will be: k_cameraZ
    enum DeepMetric
    {
        k_cameraZ   = 0,
        k_rayLength = 1
    };

    enum ProjectionProperty
    {
        // enum DicingHint - see above
        k_DicingHint,

        // enum DeepMetric - see above
        k_DeepMetric,
// ...
};

A typical implementation of the RixProjection::GetProperty() method would look like this:

Code Block
RixSCDetail GetProperty(
        ProjectionProperty property,
        void const** result) const override
    {
        switch (property)
        {
            case k_DicingHint:
                *result = &dicingHint;
                return k_RixSCUniform;
                break;
            case k_DeepMetric:
                *result = &deepMetric;
                return k_RixSCUniform;
                break;
            case k_FieldOfView:
                *result = &fovHint;
                return k_RixSCUniform;
                break;
            default:
                return k_RixSCInvalidDetail;
        }
    }