Page tree

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

Version 1 Next »

Contents

 

<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> (previously referred to as <em>surface shaders</em>). Developers should also consult the <code>RixBxdf.h</code> header file for complete details.</p><p>The <code>RixBxdfFactory</code> interface defines a shading plugin responsible for creating a <code>RixBxdf</code> object from a shading context (<code>RixShadingContext)</code> and the set of connected patterns (<code>RixPattern</code>).</p><p>The <code>RixBxdf</code> interface characterizes the <em>light-scattering behavior</em> (sometimes referred to as <em>material response</em>) for a given point on the surface of an object.</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 by the bxdf's potentially varying input parameters.  <code style="line-height: 1.42857;">RixBxdfFactory::BeginScatter()</code>  is expected to invoke  <code style="line-height: 1.42857;">RixShadingContext::EvalParam()</code> for the relevant bxdf parameters. The bxdf acts as a closure, associated with a given shading context.</p><h4>  <code>RixBxdf</code></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::GenerateSample()</code> to generate samples of the bxdf function.</li>  <li>    <code>RixBxdf::EvaluateSample()</code> and <code>RixBxdf::EvaluateSamplesAtIndex()</code>to evaluate the bxdf function.</li>  <li>    <code>RixBxdf::EmitLocal()</code> to retrieve the bxdf's local emission.</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>RixBxdfFactor::BeginScatter()</code>, excepting <code style="line-height: 1.42857;">RixBxdf::EvaluateSamplesAtIndex()</code> , that operates on a single point of the shading context, evaluating the bxdf function for one or many directions.</p><h4>  <code>RixOpacity</code></h4><p>In certain cases, integrators may also call <code>RixBxdfFactory::BeginOpacity()</code> to retrieve a <code>RixOpacity</code> object, and invoke the following methods:</p><ul style="list-style-type: square;">  <li>    <code>RixBxdf::GetPresence()</code> to evaluate the <em>geometry presence</em>.</li>  <li>    <code>RixBxdf::GetOpacity()</code> to evaluate the <em>opacity color</em>.</li></ul><h3>Execution Model</h3><p>There is one instance of a <code>RixBxdfFactory</code> per bound <code>RiBxdf</code> (RIB) request. This instance may be active in multiple threads simultaneously.</p><p>The context for a per-thread execution is signaled by the various methods <code>Begin___()</code> and <code>End___()</code>. Has a consequence, <code>RixBxdf</code> objects can be assumed as being used used in a mono-threaded context.</p><p>The <code>RixBxdfFactory</code> should stash state in the <code>RixBxdf</code> object and consider that the <code>RixBxdf</code> lifetime is under control of the integrator. Generally integrators will attempt to minimize the number of live  <code>RixBxdf</code>  objects but may nonetheless require a large number. For this reason, the  <code>RixBxdf</code>  instances should attempt to minimize  memory consumption and construction / deconstruction costs.</p><p>The primary  <code>RixBxdf</code>  entry points operate on a collection of shading points (<code>RixShadingContext</code>) in order to reasonably maximize shading coherency and support SIMD computation. Integrators rely on the  <code>RixBxdf</code> 's ability to generate and evaluate samples across the entire collection of points.  Sample evaluation may be performed in an <em>all-points-one-sample</em> variant using  <code style="line-height: 1.42857;">EvaluateSample()</code> , and a <em>1-point-n-samples</em> variant via  <code style="line-height: 1.42857;">EvaluateSamplesAtIndex()</code> . Generation, however, is constrained to <em>all-points-one-sample</em>. 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::GenerateSample()</code> generates <em>one sample</em> for <em>each point</em> of the shading context</li>  <li>    <code>RixBxdf::EvaluateSample()</code> evaluates <em>one direction</em> for <em>each point</em> of the shading context</li>  <li>    <code>RixBxdf::EvaluateSamplesAtIndex()</code>  evaluates <em>one-or-many directions</em> for a <em>given point</em> of the shading context</li></ul><h3>Bxdf correctness</h3><p>A bxdf should always provide the three methods <code>RixBxdf::GenerateSample()</code>, <code>RixBxdf::EvaluateSample()</code> and <code>RixBxdf::EvaluateSamplesAtIndex()</code>.</p><p>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>. Care should be taken so that <code>RixBxdf::GenerateSample()</code>, <code>RixBxdf::EvaluateSample()</code> and <code>RixBxdf::EvaluateSamplesAtIndex()</code> 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 points, beam and paths (UPBP)</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 account for light moving from the L to V direction where as the <em>reverse pdf</em> account for the opposite (from V to L). Bxdfs should always provide both values for the integrators to use.</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</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> 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" [0.5 0.5 0.5]]]></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.</p><p>Arg files are written in a simple xml format and should be easy to parse.</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="1053406" classification="shader/surface:rendernode/RenderMan/bxdf:swatch/rmanSwatch"/>]]></ac:plain-text-body></ac:structured-macro><p>Note that RenderMan itself queries parameter information using the <code>RixBxdfFactory::GetParamTable()</code> method, not by reading arg files.</p>