Page tree

Versions Compared

Key

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

Table of Contents

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

The return type of RixShadingPlugin::CreateInstanceData() has been changed from int to void.

...

In 23, the renderer directly inspects the value of InstanceData::data to detect if the plugin instance allocated private instance data. The (newly introduced) SynchronizeInstanceData() will then be given a chance to update the contents of this private instance data, before the pointer is provided to the usual shading plugin methods.

Plugin Instance Synchronization

RixShadingPlugin::SynchronizeInstanceData() is a new API that allows user to update the private instance data associated with a plugin instance.

...

Code Block
languagecpp
    enum SynchronizeHints
    {
        k_None = 0x00000000,
        k_All =  0xFFFFFFFF
    };

Example

Let's consider a plugin instance with a non-trivial RixShadingPlugin::CreateInstanceData() method, using option queries and storing the returned values in its own private instance data class.

...

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():

...

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.

...

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;
        }
    }

RixIntegratorFactory

The integrator plugins are now using a Factory, similarly to RixProjection. 

...