Physically Plausible Shading
|
Introduction
Over and above the complications of writing RSL2 shaders - compared to
writing classic shaders - coding a physically plausible shader presents a
significant challenge because of the need to understand the order in
which shader methods are called and how data is
accumulated as a result of a material, light sources and Pixar's "integrators"
working cooperatively to form a shading pipeline.
public void diffuselighting(output color Ci, Oi) { printf("material: diffuselighting() start\n"); printf("material: diffuselighting() calling directlighting()\n"); Ci += directlighting(this, getlights()); if(diffuseSamples > 0) { printf("material: diffuselighting() calling indirectspecular()\n"); Ci += m_diffuse->m_diffColor * indirectdiffuse(P, m_shadingCtx->m_Nn, diffuseSamples); } printf("material: diffuselighting() finish\n"); }
The helloAS.sl (uses the Ashikhmin/Shirley shading model) and
plausibleArealight.sl source files were copied to Cutter's rsl source
directory and re-compiled.
The rib file shown below was used to generate the output of the printf() statements. To reduce the quantity of text the material shader was assigned to a single point - it is shaded only once when the hider is set to "hidden". Listing 1 (dataflow.rib)
Because the edited versions of helloAS.sl and plausibleArealight.sl also printed the values of the data contained in the array of __radiancesample structs the "min" and "max" sampling of light were reduced to 4 and 8. Likewise, the rib values of "specularSamples" and "diffuseSamples" were reduced. |
private void printRadianceSamples(string label; __radiancesample samples[]) { uniform float i; if(m_print == 0) return; printf("-----------%s------------\n", label); for(i = 0; i < arraylength(samples); i += 1) { printf("direction %1.3p\n", samples[i]->direction); printf("radiance %c\n", samples[i]->radiance); printf("materialResponse %c\n", samples[i]->materialResponse); printf("accumulatedMaterialResponse %c\n", samples[i]->accumulatedMaterialResponse); } printf("----------------------------\n"); } |
The Calling of Pipeline Methods |
The pipeline methods implemented by plausibleArealight.sl are: public void light(output vector L; output color Cl) public void construct() public void begin() public void prelighting(output color Ci, Oi) public void generateSamples(string integrationdomain; output __radiancesample rsamples []) public void evaluateSamples(string integrationdomain; output __radiancesample rsamples[]) The pipeline methods implemented by helloAS.sl are: public void construct() public void begin() public void prelighting(output color Ci, Oi); public void lighting(output color Ci, Oi) public void diffuselighting(output color Ci, Oi) public void specularlighting(output color Ci, Oi) public void evaluateSamples(string distribution; output __radiancesample samples[]) public void generateSamples(string type; output __radiancesample samples[]) |
The output of the printf() statements is shown below. The pipeline methods of helloAS.sl and plausibleArealight.sl are shown in blue while the integrator, and other RSL functions, that are called by the pipeline methods are shown in red. RENDER BEGIN________ light::construct() material::construct() material::begin() material::prelighting() material::lighting() start material::lighting() -calling directlighting() [directlighting() requests a list of samples from the material. Each sample represents a direction (vector). Later in the pipeline the light shader will calculate how much of its overall illumination contributes to the color of the light hitting a surface for each sample direction] material::generateSamples() start material::generateSamples() -calling genSpecularSamps() material::generateSamples() -genSpecularSamps() generated 4 samples material::generateSamples() finish [directlighting() next requests a list of samples from the light. Each sample represents a direction and a (radiance) color] light::begin() light::generateSamples() start light::generateSamples() -generated 8 samples light::generateSamples() finish [directlighting() next requests a list of samples from the material. Each sample represents the diffuse (materialResponse) color] material::evaluateSamples() start material::evaluateSamples() -calling evalDiffuseSamps() material::evaluateSamples() -8 samples were evaluated material::evaluateSamples() finish [directlighting() finally requests another list of samples from the material. Each sample represents the combination of the diffuse and specular contributions (accumulatedMaterialResponse) color] material::evaluateSamples() start material::evaluateSamples() -calling evalSpecularSamps() material::evaluateSamples() -8 samples were evaluated material::evaluateSamples() finish light::shadowSamples() start light::shadowSamples() finish light::evaluateSamples() start light::evaluateSamples() finish light::shadowSamples() start light::shadowSamples() finish material::lighting() directlighting() generated 4 samples material::lighting() -calling indirectspecular()() material::lighting() -indirectspecular() generated 4 samples material::lighting() -calling indirectdiffuse() material::lighting() finish RENDER END__________
|
Mixing Pipeline Methods and Hider Options
The dataflow.rib file was rendered alternatively using, lighting() diffuselighting() specularlighting() "hidden" 1 0 0 "raytrace" 0 1 86 diffuselighting() specularlighting() "hidden" 1 1 "raytrace" 1 86 lighting() diffuselighting() "hidden" 1 0 "raytrace" 87 1 lighting() specularlighting() "hidden" 1 0 "raytrace" 87 0 |
Pipeline Methods and the Accumulation of Data
The helloAS shader uses instances of several structs (aka databases) in which it
stores and manipulates data. This section looks at the use of the __radiancesample
struct defined in,
-----------MATERIAL generateSamples------------ direction 0, 0, 0 radiance 0, 0, 0 materialResponse 0, 0, 0 accumulatedMaterialResponse 0, 0, 0 4 samples in total -----------LIGHT generateSamples------------ direction -0.497, 0.321, -0.806 radiance 2, 2, 2 materialResponse 0, 0, 0 accumulatedMaterialResponse 0, 0, 0 8 samples in total -----------MATERIAL evaluateSamples------------ direction -0.497, 0.321, -0.806121 radiance 2, 2, 2 materialResponse 0.0392593, 0.0392593, 0.0392593 accumulatedMaterialResponse 0, 0, 0 8 diffuse samples in total -----------MATERIAL evaluateSamples------------ direction -0.497085, 0.321053, -0.806121 radiance 2, 2, 2 materialResponse 0, 0, 0 accumulatedMaterialResponse 0.0822628, 0.0822628, 0.0822628 8 specular samples in total |
© 2002- Malcolm Kesson. All rights reserved.