Date: Fri, 29 Mar 2024 00:58:56 +0000 (UTC) Message-ID: <1988432443.175.1711673936571@ip-10-0-0-233.us-west-2.compute.internal> Subject: Exported From Confluence MIME-Version: 1.0 Content-Type: multipart/related; boundary="----=_Part_174_2055215265.1711673936568" ------=_Part_174_2055215265.1711673936568 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Content-Location: file:///C:/exported.html
RixShadingPlugin
is the base class for RixBxdfFactory
, RixDisplacementFactory
, RixIntegrator=
, RixLig=
htFilter
, RixLi=
ghtFactory
, R=
ixPattern
, RixProjection
, and RixSampleFilter
. These are plugins that implemen=
t services for the renderer.
Here, it is important to distinguish between two types of plugins: ones =
that need to create short-lived lightweight instances during the course of =
a render, and ones that do not. RixBxdf
, RixDisplacement
, and RixLight
represent=
lightweight instances that may be created many times during the course of =
a single render, and therefore are not directly subclasses of RixShadingPlugin
. Instead, instancees of=
those classes are returned by the appropriate Factory (e.g. RixBxdfFactory
), with the Fact=
ory itself being the subclass of Rix=
ShadingPlugin
.
RixIntegrator<=
/code>,
RixDispla=
yFilter
, RixLightFilter
, RixPattern,
RixProjection
, and RixSampleFilter
do not create many ligh=
tweight instances. As such, these classes are directly subclasses of =
RixShadingPlugin
.
All RixShadingPlugins
share common methods related to =
initialization, synchronization with the renderer, and management of lightw=
eight instances.
In order to initialize the plugin, the renderer will call Init()=
code> once. Even if the plugin is evoked multiple times during the render w=
ith different arguments,
Init()
will still be called only=
once during the lifetime of the render. The RixContext
p=
arameter can be used by the plugin to request any RixInterfaces<=
/code> services provided by the renderer. Any expensive memory allocat=
ions or operations that can be reused during the lifetime of the plugin can=
be performed in this routine. Upon successful initialization, this routine=
should return a zero status.
Finalize()
is the companion to Init()
, called =
at the end of rendering with the expectation that any data allocated within=
the Init()
implementation will be released.
All shading plugins are expected to return a description of their input =
and output parameters via the GetParamTable()
method. Thi=
s returns a pointer to an array of RixSCParamInfo
, contai=
ning one entry for each input and output parameter, as well as an extra emp=
ty entry to mark the end of the table. This parameter table is used by the =
renderer to ensure proper type checking and validate the connections of ups=
tream and downstream nodes. As such, each entry in the table should set a n=
ame, a type (RixSCType
enumeration), detail (varying vs u=
niform, RixSCDetail
enumeration), and access (input vs ou=
tput, RixSCAccess
enumeration). These declarations a=
lso need to be kept in sync with the associated .args file.
For an example of usage, consider a pattern plugin which returns a color= . The resultC output parameter is a color, so it is defi= ned in the parameter table as:
RixSCParamInfo(= "resultC", k_RixSCColor, k_RixSCOutput)
A float input parameter named density can be defined = as:
RixSCParamInfo(= "density", k_RixSCFloat)
While a float[16] input parameter named placementMatrix&nb= sp;can be defined as:
RixSCParamInfo(= "placementMatrix", k_RixSCFloat, k_RixSCInput, 16)
The full implementation of GetParamTable()
for this pl=
ugin would look something like this:
RixSCPar= amInfo const * MyPattern::GetParamTable() { static RixSCParamInfo s_ptable[] =3D { // outputs RixSCParamInfo("resultC", k_RixSCColor, k_RixSCOutput), // inputs RixSCParamInfo("density", k_RixSCFloat), RixSCParamInfo("placementMatrix", k_RixSCFloat, k_RixSCInput, 16), RixSCParamInfo(), // end of table }; return &s_ptable[0]; }
The ordinal position of a parameter in the parameter table is the intege=
r paramId
used to evaluate parameter inputs using the&nbs=
p;RixShadingContext::EvalParam
method. Because these n=
eed to be kept in sync, it is recom=
mended that you create a parameter enumeration (a private enum
=
type) to keep track of the order that your parameters were created in=
the table. The enumeration can be used later on when calling RixS=
hadingContext::EvalParam
in the body of the shader. Follow=
ing the three parameter table entries above:
enum par= amId { k_resultC=3D0, // output k_density, k_placementMatrix, k_numParams };
In order to facilitate the reuse of the same parameter enumeration for <= a href=3D"/display/REN22/Writing+Patterns#WritingPatterns-ComputeOutputPara= ms">pattern output computation, it is highly recommended that all outpu= ts be placed at the beginning of the parameter table.
The Synchronize()
routine allows the plugin to respond=
to synchronization signals delivered by the renderer. The renderer may pro=
vide additional information to the plugin via the input parameter Rix=
ParameterList
. These signals include:
k_RixSCRenderBegin
: The renderer is being initialized.k_RixSCRenderEnd
: The renderer is about to end.k_RixSCInstanceEdit
: Currently unused.k_RixSCCancel
: Currently unused.k_RixSCCheckpointRecover
: A signal that the renderer is ab=
out to restart rendering from a checkpoint. The parameter list will contain=
a single constant integer "increment" which contains the increment value f=
rom which the renderer will restart.k_RixSCCheckpointWrite
: A signal that the renderer is abou=
t to write a checkpoint. The parameter list will contain two values: a cons=
tant integer "increment" indicating the increment value the renderer will w=
rite, and a constant string "reason" which contains one of three values: "c=
heckpoint", "exiting", or "finished", indicating why the renderer is writin=
g the checkpoint.k_RixSCIncrementBarrier
: A signal that the rendering of an=
new increment is about to begin. This signal will only be received if the =
integrator has set wantsIncrementBarrier
to true in the =
RixIntegratorEnvironment
. The parameter list will contain a sin=
gle constant integer "increment" which contains the increment value the ren=
derer is about to render.For shading plugin types which support the creation of multiple lightwei=
ght instance classes not derived from RixShadingPlugin
(i.e. RixBxdf
, RixDisplacement
, and RixLight
), the =
renderer can potentially create many, many instances over the course of the=
render. Here, the term instance is unfortunately overloaded, and it is imp=
ortant to differentiate between: an instance of a shading plugin a=
s defined by the unique set of parameters given to the material defini=
tion, and a C++ instance which involves an actual memory allo=
cation, construction, and destruction of an object. Over the lifetime of a =
render there can be a one to many relationship between the former and the l=
atter, and for performance reasons, it is important to keep the cost of the=
creation of the latter C++ objects low. In order to reduce the cost of the=
se instantiations, the renderer offers the ability to track custom instance data with every shading plu=
gin instance that can be shared and reused amongst all the C++ objects that=
share the same shading plugin instance.
The shading plugin can create pri=
vate instance data using the =
CreateInstanceData()
method. =
Instance data would typically be computed from the unique evocation paramet=
ers, supplied to CreateInstan=
ceData
via the
If the shading plugin does create instance data, it should be stored in =
the data field of the InstanceData=
code> struct. If the data requires non-trivial deletion, the
field of the InstanceData
struct s=
hould be set to a function that the renderer will invoke when the plugin in=
stance will no longer be needed. A trivial implementation of Cre=
ateInstanceData()
produces no instance data and returns a non-zero v=
alue.
Any instance data that is created will be automatically returned to the =
shading plugin methods by the renderer when the lightweight instance is cre=
ated - for example, when RixBxdfFactory::BeginScatter()
i=
s invoked to create a RixBxdf
. The implementation of RixBxdf
.
The RixParameterList
class allows for the evaluation o=
f the plugin instance parameters via the EvalParam()
method. T=
o aid in this, it allows for the querying via RixParameterList::=
GetParamInfo()
of whether the parameters have been unset (and a=
re therefore at their default value), set as a uniform value, or are part o=
f a network connection, i.e. the parameter is compu=
ted by an upstream node in the shading graph. A network connection is =
understood to be a varying quantity, and its value cannot be evaluated at t=
he time that CreateInstanceData
is evoked; this is w=
hy EvalParam()
will return k_RixSCInvalidDetai=
l
if the parameter is a network connection. Otherwise, Ev=
alParam()
can be used to get an understanding of the uniform, non-va=
rying parameters that are passed to the shading instance, and these can be =
used to perform any precomputations as needed.
As an example of usage of instance data, consider the PxrDiff=
use
bxdf. Although it is a fairly trivial bxdf, it does handle =
presence and opacity, and the renderer passes instance data to the Ri=
xBxdf
interface in order to get an understanding of the require=
ments for presence and opacity. In the following code, PxrDiffus=
e
checks its own presence parameter to see if it is a connectio=
n, knowing that its Args
file only allows presence to be =
set to a default value (and therefore is trivially fully opaque) or is conn=
ected (and therefore requires the renderer to perform presence calculations=
). If it is connected, then it sets the instance data to be the same <=
code>InstanceHints bitfield that is requested by the renderer from&n=
bsp;RixBxdf::GetInstanceHints
.
plis= t->GetParamInfo(k_presence, &typ, &cnx1); if(cnx1 =3D=3D k_RixSCNetworkValue) { if (cachePresence =3D=3D 0) { req |=3D k_ComputesPresence; } else { req |=3D k_ComputesPresence | k_PresenceCanBeCached; } }
For a more complicated example of instance data usage, consider the =
;PxrDirt
pattern. Its instance data routine caches the values =
of many uniform parameters and reuses them in ComputeOutputParams()=
code>, knowing that its Args file prohibits those parameters from being set=
to network connections.
Data= *data =3D static_cast<Data*>(instanceData->data); data->numSamples =3D 4; data->distribution =3D k_distributionCosine; data->cosineSpread =3D 1.0f; data->falloff =3D 0.0f; data->maxDistance =3D 0.0f; data->direction =3D k_directionOutside; data->raySpread =3D 1.0f; params->EvalParam(k_numSamples, 0, &data->numSamples); data->numSamples =3D RixMax(1, data->numSamples); params->EvalParam(k_distribution, 0, &data->distribution); params->EvalParam(k_cosineSpread, 0, &data->cosineSpread); params->EvalParam(k_falloff, 0, &data->falloff); params->EvalParam(k_maxDistance, 0, &data->maxDistance); params->EvalParam(k_direction, 0, &data->direction);
RixPattern
=
plugins do not fully follow the lightweight instancing pattern because they=
do not have an associated factory object, and do not create lightweight C+=
+ objects because patterns are generally not expected to retain state. Howe=
ver, they do support instance data, and the renderer will return this insta=
nce data every time output is requested from the pattern plugin, with the u=
nderstanding that any expensive computation that can be performed based on =
an understanding of the uniform parameters can be reused on each invocation=
of ComputeOutputParams()
.
A plugin can create its parameter table dynamically based on the paramet=
ers provided to each instance of the plugin. This dynamically created table=
is created using the CreateInstanceData()
method, and sh=
ould be saved in the paramtable
member of the Insta=
nceData
, along with a corresponding freefunc()
rou=
tine. Generally, static interfaces should be preferred over dynamic interfa=
ces due to their extra memory expense. If the paramtable
=
member remains null, all instances will share the parameter table returned =
by GetParamTable()
. In order to prevent the renderer from filt=
ering out dynamic parameters as bad inputs, a plugin that is using a dynami=
cally created table should have a k_RixSCAnyType
entry in=
its plugin parameter table.
CreateInstanceData()
may be called in multiple threads=
, and so its implementation should be re-entrant and thread-safe.
RenderMan will search for shading plugins on demand, under the /rixpluginpath settings in Rendermn.ini=
a>; or the directory can be appended to the
rixplugin
&nbs=
p;search path which is emitted by the bridge.
If you would like RenderMan for Maya or RenderMan for Katana to recogniz= e your plugin and provide a user interface for changing input parameters an= d connecting output parameters to other nodes, then you will need to create= an args file for your shading plugin. The args file defines the input and = output parameters in XML so that tools like RMS or Katana can easily read t= hem, discover their type, default values, and other information used while = creating the user interface for the pattern node. Please consult the <= a href=3D"/display/REN22/Args+File+Reference">Args File Reference = for more information.