Page tree

Versions Compared

Key

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

Table of Contents
minLevel3

Introduction

This

 

<h3>  <ac:structured-macro ac:macro-id="800ed41e-1dc2-48bf-8f89-99488606d54f" ac:name="toc" ac:schema-version="1">    <ac:parameter ac:name="minLevel">3</ac:parameter>  </ac:structured-macro></h3><h3>Introduction</h3><p>This documentation is intended to instruct developers in the authoring of custom <em> <a href="https://en.wikipedia.org/wiki/Bidirectional_scattering_distribution_function">bxdfs</a> </em> bxdfs (previously referred to as <em>surface shaders</em> surface shaders). Developers should also consult the <code>RixBxdf.h</code> header the RixBxdf.h header file for complete details.</p><p>The <code>RixBxdfFactory</code> interface

The RixBxdfFactory interface defines a shading plugin responsible for creating a <code>RixBxdf</code> object RixBxdf object from a shading context (<code>RixShadingContext)</code> and RixShadingContext) and the set of connected patterns (<code>RixPattern</code>).</p><p>The <code>RixBxdf</code> interface characterizes the <em>light-scattering behavior</RixPattern).

The RixBxdf interface characterizes the light-scattering behavior em> (sometimes referred to as <em>material response</em>) for material response) for a given point on the surface of an object.

RixBxdfFactory

Integrators (RixIntegrator) uses RixBxdfFactory objects by invoking RixBxdfFactory</p><h4>  <code>RixBxdfFactory</code></h4><p>Integrators (<code>RixIntegrator</code>) uses <code>RixBxdfFactory</code> objects by invoking <code style="line-height: 1.42857;">RixBxdfFactory::BeginScatter()</code>  to obtain a  <code style="line-height: 1.42857;">RixBxdf,</code>  parameterized  to obtain a  RixBxdf,  parameterized by the bxdf's potentially varying input parameters.  <code style="line-height: 1.42857;">RixBxdfFactory::RixBxdfFactory::BeginScatter()</code>  is  is expected to invoke  <code style="line-height: 1.42857;">RixShadingContextRixShadingContext::EvalParam()</code> for  for the relevant bxdf parameters. The bxdf acts bxdf acts as a closurea closure, associated with a given shading context.</p><h4>  <code>RixBxdf</code></

RixBxdf

Once a RixBxdf h4><p>Once a <code>RixBxdf</code> object is obtained, the integrator may invoke the following methods:</p><ul style="list-style-type: square;">  <li>    <code>RixBxdf::

  • RixBxdf::GenerateSample()

...

  • to generate samples of the bxdf function.

...

  • RixBxdf::EvaluateSample()

...

  •  and RixBxdf::EvaluateSamplesAtIndex()

...

  • to evaluate the bxdf function.

...

  • RixBxdf::EmitLocal()

...

  • to retrieve the bxdf's local emission.

The RixBxdf </li></ul><p>The <code>RixBxdf</code> methods above are expected to return quantities for each point of the shading context originally given to <code>RixBxdfFactorcontext originally given to RixBxdfFactor::BeginScatter()</code>, excepting <code style="line-height: 1.42857;">RixBxdf, excepting RixBxdf::EvaluateSamplesAtIndex()</code> , that operates on a single point of the shading context, evaluating the bxdf function for one or many directions.

RixOpacity

In </p><h4>  <code>RixOpacity</code></h4><p>In certain cases, integrators may also call <code>RixBxdfFactorycall RixBxdfFactory::BeginOpacity()</code> to retrieve a <code>RixOpacity</code> RixOpacity object, and invoke the following methods:</p><ul style="list-style-type: square;">  <li>    <code>RixBxdf

  • RixBxdf::GetPresence()

...

  •  to evaluate the

...

  • geometry presence.
  • RixBxdf::GetOpacity()

...

  •  to evaluate the opacity color.

Execution Model

There <em>opacity color</em>.</li></ul><h3>Execution Model</h3><p>There is one instance of a <code>RixBxdfFactory</code> RixBxdfFactory per bound <code>RiBxdf</code> RiBxdf (RIB) request. This instance may be active in multiple threads simultaneously.</p><p>The

The context for a per-thread execution is signaled by the various methods <code>Beginmethods Begin___()</code> and <code>End and End___()</code>. Has a consequence, <code>RixBxdf</code> objects  RixBxdf objects can be assumed as being used used in a mono-threaded context.</p><p>The <code>RixBxdfFactory</code>

The RixBxdfFactory should stash state in the <code>RixBxdf</code> the RixBxdf object and consider that the <code>RixBxdf</code> lifetime RixBxdf lifetime is under control of the integrator. Generally  Generally integrators will attempt to minimize the number of live  <code>RixBxdf</code>  objects RixBxdf  objects but may nonetheless require a large number. For  For this reason, the  <code>RixBxdf</code>  instances RixBxdf  instances should attempt to minimize  memory consumption and construction / deconstruction costs.</p><p>The primary  <code>RixBxdf</code>  entry

The primary  RixBxdf  entry points operate on a collection of shading points (<code>RixShadingContext</code>RixShadingContext) in  in order to reasonably maximize shading coherency and support SIMD computation. Integrators rely on the  <code>RixBxdf</code> RixBxdf 's ability to generate and evaluate samples across the entire collection of points.  Sample evaluation may be performed in an <em>allall-points-one-sample</em> variant using  <code style="line-height: 1.42857;">EvaluateSample()</code> sample variant using  EvaluateSample() , and a <em>11-point-n-samples</em> variant via  <code style="line-height: 1.42857;">EvaluateSamplesAtIndex()</code> samples variant via  EvaluateSamplesAtIndex() . Generation, however, is constrained to <em>allall-points-one-sample</em>sample. Evaluation typically has different requirements (e.g. for making connections in a bidirectional integrator), whereas generation typically benefits from being performed all points at once.</p><ul>  <li>    <code>RixBxdf

  • RixBxdf::GenerateSample()

...

  •  generates one sample for each point of the shading context
  • RixBxdf::EvaluateSample()

...

  •  evaluates one direction for each point of the shading context
  • RixBxdf::EvaluateSamplesAtIndex()

...

  •  evaluates one-or-many

...

  • directions for a

...

  • given point of the shading context

Bxdf correctness

A context</li></ul><h3>Bxdf correctness</h3><p>A bxdf should always provide the three methods <code>RixBxdfmethods RixBxdf::GenerateSample()</code>, <code>RixBxdf RixBxdf::EvaluateSample()</code> and <code>RixBxdf and RixBxdf::EvaluateSamplesAtIndex()</code>.</p><p>In .

In order to maintain physical correctness, bxdfs are expected to conserve energy and obey the <a href="https://en.wikipedia.org/wiki/Helmholtz_reciprocity">Helmholtz reciprocity</a>the Helmholtz reciprocity. Care should be taken so that <code>RixBxdfthat RixBxdf::GenerateSample()</code>, <code>RixBxdf RixBxdf::EvaluateSample()</code> and <code>RixBxdf and RixBxdf::EvaluateSamplesAtIndex()</code> return  return consistent results. This allows bxdf plugins to be compatible with different rendering techniques such as:</p><ul>  <li>    <a href="https://en.wikipedia.org/wiki/Path_tracing">unidirectional path tracing</a>  </li>  <li>    <a href="https://en.wikipedia.org/wiki/Path_tracing#Bidirectional_path_tracing">bidirectional path tracing</a>  </li>  <li>    <a href="https://en.wikipedia.org/wiki/Photon_mapping">photon mapping</a>  </li>  <li>    <a href="http://iliyan.com/publications/VertexMerging">vertex connection merging (VCM)</a>  </li>  <li>    <a href="http://cgg.mff.cuni.cz/~jaroslav/papers/2014-upbp/index.htm">unified

Note that the RixBxdf interfaces </a>  </li></ul><p>Note that the <code>RixBxdf</code> interfaces requires two separate scalar pdf values to be returned. The <em>forward pdf</em> should The forward pdf should account for light moving from the L to V direction where as the <em>reverse pdf</em> account the reverse pdf account for the opposite (from V to L). Bxdfs should always provide both values for the integrators to use.

Bxdfs </p><p>Bxdfs that do not scatter light (e.g. PxrConstant) should disable all lobes and set the <em>forward pdf</em> and <em>reversed pdf</the forward pdf and reversed pdf to zero.

Additional Considerations

Bxdf Evaluation Domain

Bxdf Lobes

Non-Opaque Surfaces

Alpha For Compositing

Query Ray Properties

Bxdf Sample Validity

Installation

RenderMan em> to zero.</p><h3>Additional Considerations</h3><p>  <ac:link>    <ri:page ri:content-title="Bxdf Evaluation Domain"/>  </ac:link></p><p>  <ac:link>    <ri:page ri:content-title="Bxdf Lobes"/>  </ac:link></p><p>  <ac:link>    <ri:page ri:content-title="Non-Opaque Surfaces"/>  </ac:link></p><p>  <ac:link>    <ri:page ri:content-title="Alpha For Compositing"/>  </ac:link></p><p>  <ac:link>    <ri:page ri:content-title="Query Ray Properties"/>  </ac:link></p><p>  <ac:link>    <ri:page ri:content-title="Bxdf Sample Validity"/>  </ac:link></p><h3>Installation</h3><p>RenderMan will search for bxdf plugins on demand, under the <em>rixplugin</em> rixplugin searchpath. The following rib stream will search for a plugin file named <code>MyDiffuse.so</code></p><ac:structured-macro ac:macro-id="5966a98e-1073-4d4f-922a-e0e0916dd514" ac:name="code" ac:schema-version="1">  <ac:plain-text-body><![CDATA[Bxdf "MyDiffuse" "diffuse1" "color tint" named MyDiffuse.so

Code Block
Bxdf "MyDiffuse" "diffuse1" "color tint" [0.5 0.5 0.5]

Args files

By convention, arg ]]></ac:plain-text-body></ac:structured-macro><h3>Args files</h3><p>By convention, <em>arg</em> files (.args) are used to define shader metadata needed by host applications. This includes parameter names, default values, localization and GUI hints.</

Arg p><p>Arg files are written in a simple xml format and should be easy to parse.

Bridge </p><p>Bridge specific metadata should also be written to arg files. For example, Maya requires <code>nodeid</code> and <code>classification</code> information:</p><p> </p><ac:structured-macro ac:macro-id="5836fb1a-7e85-4530-b332-37e69de0548d" ac:name="code" ac:schema-version="1">  <ac:plain-text-body><![CDATA[<rfmdata nodeid and classification information:

 

Code Block
<rfmdata nodeid="1053406" classification="shader/surface:rendernode/RenderMan/bxdf:swatch/rmanSwatch"/>

Note ]]></ac:plain-text-body></ac:structured-macro><p>Note that RenderMan itself queries parameter information using the <code>RixBxdfFactorythe RixBxdfFactory::GetParamTable()</code> method, not by reading arg files.</p>