Page tree

Versions Compared

Key

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

...

The seasoned RenderMan user will notice this is all very similar to how displacement was done in the classic RenderMan Shading Language (RSL) – see for example the "Advanced RenderMan" book by Apodaca and Gritz, section 8.2.  One notable difference is that the displacement calculations used to be in camera space, but in RenderMan 22 they are in object space.

The RixDisplacement class class

For most users, it will be sufficient to write OSL patterns to calculate displacement amounts, and simply pass their output to the standard PxrDisplace displacement shader.  However, PxrDisplace is just one example of a RixDisplacement class  class displacement shader.  The RixDisplacement interface  interface characterizes the displacement of points on the surface of an object.

If a developer wishes to write their own displacement plug-in, two classes are of interest: RixDisplacementFactory and  and RixDisplacement.

The RixDisplacementFactory interface  interface is a subclass of RixShadingPlugin, and defines a shading plugin responsible for creating a RixDisplacement object  object from a shading context (RixShadingContext) and  and the set of connected patterns (RixPattern).  Since RixDisplacementFactory is  is a subclass of RixShadingPlugin, it shares the same initialization, synchronization, and and parameter table logic  logic as other shading plugins. Therefore to start developing your own displacement plug-in, you can #include "RixDisplacement.h" and  and make sure your displacement factory class implements the required methods inherited from the RixShadingPlugin interface interface: Init(), Finalize(), Synchronize(), GetParamTable(), and CreateInstanceData(), as well as the methods BeginDisplacement(), and  and EndDisplacement(). Generally, there is one shading plugin instance of a RixDisplacementFactory per  per bound RiDisplacement (RIB) request. This instance may be active in multiple threads simultaneously.

Integrators (RixIntegrator) use RixDisplacementFactory objects by invoking RixBxdfFactory::BeginDisplacement()  to obtain a  RixDisplacement. Because a RixDisplacement is expected to be a lightweight object that may be created many times over the course of the render, RixDisplacementFactory is expected to take advantage of the lightweight instancing services provided by RixShadingPlugin. In particular, BeginDisplacement() is provided a pointer to an instance data that is created by RixDisplacementFactory::CreateInstanceData(), which is called once per shading plugin instance, as defined by the unique set of parameters supplied to the material description. It is expected that the instance data will point to a private cached representation of any expensive setup which depends on the parameters, and BeginDisplacement() will reuse this cached representation many times over the course of the render to create RixDisplacement objects. 

Once a RixDisplacement object  object is obtained, the renderer may invoke its GetDisplacement() method method.  The GetDisplacement() method  method loops over the surface points in a RixShadingContext and  and moves them according to e.g. surface normal and various input parameters.  Operating  Operating on a collection of shading points allows maximizing shading coherency and supporting SIMD computation. It would be typical for either BeginDisplacement() or the implementation of GetDisplacement() to invoke  RixShadingContext::EvalParam() in order to evaluate the relevant displacement input parameters. Since displacements also generally require geometric data, or built-in variables, such as the shading normal (Nn),  RixShadingContext::GetBuiltinVar() function should be used for each such built-in variable.

For more details, please see the built-in PxrDisplace displacement shader implementation – it is a good example of how a displacement plug-in is structured.

...