<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Arbitrary Output</title>
	<atom:link href="http://sitexgraphics.com/blog/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://sitexgraphics.com/blog</link>
	<description>rendering with SiTex Graphics Air</description>
	<lastBuildDate>Mon, 30 Apr 2012 17:33:09 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Air Point Cloud File Format</title>
		<link>http://sitexgraphics.com/blog/?p=99</link>
		<comments>http://sitexgraphics.com/blog/?p=99#comments</comments>
		<pubDate>Mon, 30 Apr 2012 17:33:09 +0000</pubDate>
		<dc:creator>sitexgraphics</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[point clouds]]></category>

		<guid isPermaLink="false">http://sitexgraphics.com/blog/?p=99</guid>
		<description><![CDATA[Air can save and re-use point-based data for effects such as indirect illumination, occlusion, subsurface scattering, and caustics.  The Air Point Tool (airpt) included with Air allows point data to be translated to and from several formats including a simple &#8230; <a href="http://sitexgraphics.com/blog/?p=99">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Air can save and re-use point-based data for effects such as indirect illumination, occlusion, subsurface scattering, and caustics.  The Air Point Tool (airpt) included with Air allows point data to be translated to and from several formats including a simple text format.  However, some users have requested information on the native Air Point Cloud (.apc) format used to store unstructured point data.  We&#8217;ve uploaded the source code for a simple APC reader <a title="printapc" href="http://www.sitexgraphics.com/printapc.zip">here</a>.</p>
<p>An Air point cloud is a simple binary file with a short header followed by a list of records, one record for each point.  Here&#8217;s the header:</p>
<pre>
typedef struct {
  char diName[48];
  int diType, diNarr, diIndex, diSize;
} DataInfo;

typedef struct {
  char id[4];
  unsigned int hsize;
  float gbound[6];
  float world2camera[16], world2ndc[16];
  int xres, yres;
  float par, fov;
  int flags;
  int maxdepth, maxleafsize;
  int nbrick, bricksize;
  int nbiv,npts;
  unsigned int ptoffset;
  float minwidth, maxwidth;
  int pad[256];
  int ndata,datasize;
  DataInfo di[64];
} AirPointHeader;
</pre>
<p>The ptoffset field gives the file position where the actual data begins.  The data for each point is stored as a binary array of floats with little-endian byte order.</p>
]]></content:encoded>
			<wfw:commentRss>http://sitexgraphics.com/blog/?feed=rss2&amp;p=99</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to render an object&#8217;s x,y,z position</title>
		<link>http://sitexgraphics.com/blog/?p=88</link>
		<comments>http://sitexgraphics.com/blog/?p=88#comments</comments>
		<pubDate>Tue, 28 Feb 2012 22:14:16 +0000</pubDate>
		<dc:creator>sitexgraphics</dc:creator>
				<category><![CDATA[Passes]]></category>
		<category><![CDATA[Shaders]]></category>
		<category><![CDATA[passes]]></category>
		<category><![CDATA[renderman]]></category>

		<guid isPermaLink="false">http://sitexgraphics.com/blog/?p=88</guid>
		<description><![CDATA[A user asked how to render an object&#8217;s world-space position into an image.  To address this question, we&#8217;ve included a new ShowPosition surface shader in Air 11.04 and later.  Here are the shader parameters: Surface "ShowPosition" "float UnitSize" [1] "float[3] &#8230; <a href="http://sitexgraphics.com/blog/?p=88">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>A user asked how to render an object&#8217;s world-space position into an image.  To address this question, we&#8217;ve included a new ShowPosition surface shader in Air 11.04 and later.  Here are the shader parameters:</p>
<pre>Surface "ShowPosition"
 "float UnitSize" [1]
 "float[3] Origin" [0 0 0]
 "float Clamp" [0]
 "float Cyclic" [0]
 "string ShadingSpace" ["world"]</pre>
<p>Here&#8217;s a rendering with the default parameter values.  The output color is the world-space x,y,z position of the current shading location:</p>
<p><a href="http://sitexgraphics.com/blog/wp-content/uploads/2012/02/showposition1.png"><img class="alignnone size-full wp-image-89" title="showposition1" src="http://sitexgraphics.com/blog/wp-content/uploads/2012/02/showposition1.png" alt="ShowPosition" width="300" height="225" /></a></p>
<p>It doesn&#8217;t normally make sense to filter position values, so this image was rendered with only 1 pixel sample (PixelSamples 1 1 in the RIB file) and no filtering.</p>
<p>The position values may well be greater than 1 or less than 0, so a full-precision position image should be saved in a file format such as HDR, EXR, or TIFF that supports floating-point data.</p>
<p>The ShowPosition shader also allows the position values to be scaled to lie in the unit interval, which allows the data to be recorded in an 8-bit or 16-bit image.  The scaling is performed by mapping the position into a cube with one corner defined by the Origin parameter and each side of length UnitSize.  In this image the UnitSize is set to 10:</p>
<p><a href="http://sitexgraphics.com/blog/wp-content/uploads/2012/02/showposition2.png"><img class="alignnone size-full wp-image-90" title="showposition2" src="http://sitexgraphics.com/blog/wp-content/uploads/2012/02/showposition2.png" alt="show scaled position" width="300" height="225" /></a></p>
<p>Position values that lie outside of the box defined by the Origin and UnitSize value will be clamped to the unit interval if the Clamp parameter is set to 1.  If the Cyclic parameter is set to 1, out of range values will be wrapped to form a periodic pattern.  Here&#8217;s the same model with UnitSize set to 1 and Cyclic set to 1:</p>
<p><a href="http://sitexgraphics.com/blog/wp-content/uploads/2012/02/showposition3.png"><img class="alignnone size-full wp-image-91" title="showposition3" src="http://sitexgraphics.com/blog/wp-content/uploads/2012/02/showposition3.png" alt="show cyclic position" width="300" height="225" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://sitexgraphics.com/blog/?feed=rss2&amp;p=88</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Shader Networks and Layered Shaders</title>
		<link>http://sitexgraphics.com/blog/?p=81</link>
		<comments>http://sitexgraphics.com/blog/?p=81#comments</comments>
		<pubDate>Sun, 31 Jul 2011 17:39:37 +0000</pubDate>
		<dc:creator>sitexgraphics</dc:creator>
				<category><![CDATA[Shaders]]></category>
		<category><![CDATA[passes]]></category>
		<category><![CDATA[renderman]]></category>

		<guid isPermaLink="false">http://sitexgraphics.com/blog/?p=81</guid>
		<description><![CDATA[SiTex Graphics Air version 11 (press release) introduces the ability to use multiple shaders to compute the shading for surfaces, displacements, imagers, and environments. This new capability provides a simple solution to several common shading tasks that would otherwise require &#8230; <a href="http://sitexgraphics.com/blog/?p=81">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>SiTex Graphics Air version 11 (<a title="Air 11 press release" href="http://www.sitexgraphics.com/html/air_11_press_release.html">press release</a>) introduces the ability to use multiple shaders to compute the shading for surfaces, displacements, imagers, and environments.</p>
<p>This new capability provides a simple solution to several common shading tasks that would otherwise require complex custom shaders:</p>
<ul>
<li><strong>Decals</strong>:  apply an arbitrary number of texture maps to an object&#8217;s color and feed the result into any surface shader.</li>
</ul>
<ul>
<li><strong>Extra output variables</strong>:  add an arbitrary number of additional shaders to an object to produce extra output values without affecting the normal shading of the object.</li>
</ul>
<ul>
<li><strong>Assign different shaders to specific regions</strong>:  simple shader compositing allows existing surface shaders to be selectively applied to sections of a surface.</li>
</ul>
<ul>
<li><strong>Replicate application shader networks</strong>:  create arbitrary shader networks by connecting pre-compiled components.</li>
</ul>
<p>Further, the implementation of networked and layered shaders does not require existing shaders to be re-written to take advantage of these new features.</p>
<p>This article describes how to use multiple shaders to address each of these tasks.  Sample shaders and rib files are included in the AIR distribution in:</p>
<pre style="padding-left: 30px;">$AIRHOME/examples/layers
</pre>
<h3>Simple Color Layers</h3>
<p>Here&#8217;s a simple RIB fragment that assigns multiple surface shaders to an object:</p>
<pre>Surface "ColorMap" "string ColorMapName" "grid.tx"
Surface "+VMarble"</pre>
<p>Prepending the shader name with &#8220;+&#8221; tells Air to append the shader to the list of shaders assigned to the object. The shaders are executed in the order in which they are assigned. Subsequent shaders inherit the current shading state (including the values of global variables) from shaders previously executed. Here&#8217;s a ColorMap shader that uses a texture map to set the object&#8217;s color value:</p>
<pre>generic ColorMap(
  string ColorMapName = "";
  float SetColor = 1;
  output varying color __Color = 0;
)
{
  if (ColorMapName!="") {
    __Color = color texture(ColorMapName,s,t);
    if (SetColor!=0) Cs = __Color;
  }
}</pre>
<p>In the RIB fragment given above, the VMarble shader will use the color map result as one of the input colors for the marble pattern. No modification of the VMarble shader is required.</p>
<p>The new generic shader type is compatible with any other shader type.  Generic shaders can be used to construct re-usable components for layered and networked shaders.</p>
<p>Sample scene: colormap.rib</p>
<h3>Decals</h3>
<p>The layers example directory includes a LayerDecal shader that applies a masked color to a surface. Simple sequential shader assignment allows an arbitrary number of decals to be applied to a surface without constructing a complex custom surface shader:</p>
<pre>Surface "LayerDecal"
  "ColorMapName" "sitex.tx"
  "OriginXY" [.3 .67]
  "SizeXY" [-.3 -.3]
  "DecalColor" [1 1 1]
Surface "+LayerDecal"
  "ColorMapName" "sitex.tx"
  "OriginXY" [.25 .6]
  "SizeXY" [-.25 -0.25]
  "DecalColor" [1 0 0]
Surface "+plastic"</pre>
<p>Sample scene: decals.rib</p>
<h3>Extra Passes</h3>
<p>Another task made easy with multiple shaders is adding extra output values to a rendering pass.   Air 11 includes a new generic shader that adds an occlusion output value to any surface (stored in a __occlusion output variable).   Sample usage:</p>
<pre> Display "extrapass.tif" "framebuffer" "rgba,color __occlusion"
...
Surface "VMarble"
Surface "+genOcclusion" "setshaderoutput" 0</pre>
<p>Sample scene: extrapass.rib</p>
<h3>Shader Compositing</h3>
<p>Air&#8217;s multi-shader support includes an option to composite one shader on top of another. Here&#8217;s an example that adds a plastic decal to a metallic surface:</p>
<pre>Surface "VMetal"
Surface "*VPlastic" "OpacityMapName" "sitex.tx" "ColorMapName" "square.tx"</pre>
<p>The * before the shader name tells Air to blend the output color from the VPlastic shader with the output color of the VMetal shader using the output opacity from the VPlastic shader. Any output variables shared by the two shaders will also be composited using the output opacity.</p>
<p>Sample scene: compshaders1.rib</p>
<p>The above example shows how to composite a shader with controls for its output opacity. For surface shaders without opacity controls, an auxiliary shader can be used to control the opacity. Here is a simple generic shader that sets the global input opacity value:</p>
<pre>generic OpacityMap(
  string OpacityMapName = "";
  output varying color __Opacity = 1;
)
{
  if (OpacityMapName!="") {
    __Opacity = color texture(OpacityMapName,s,t,"fill",-1);
    if (comp(__Opacity,1)==-1) __Opacity=comp(__Opacity,0);
    Os = __Opacity;
  }
}
</pre>
<p>This shader allows any surface shader that modulates its output color by the input opacity to be composited over another shader.  Most surface shaders modulate their output color in this way.</p>
<p>Here is how the OpacityMap shader might be used to add a marble decal to a 2D grid:</p>
<pre>Surface "VGrid2D"
Surface "+OpacityMap" "OpacityMapName" "sitex.tx"
Surface "*VMarble"</pre>
<p>To optimize the evaluation of composited shaders, Air will skip any shader layer whose input opacity value is 0.</p>
<p>Sample scene: compshaders2.rib</p>
<h3>Shader Networks</h3>
<p>Multiple shaders can be used to re-construct a general shader network by defining connections among the shaders assigned to an object. Connections are defined by including additional parameters in the shader declaration. First, each shader declaration is assigned a name using:</p>
<p style="padding-left: 30px;">&#8220;string layername&#8221; &#8220;<em>componentname</em>&#8220;</p>
<p>Naturally layername does not need to be an actual parameter of the shader.</p>
<p>Each connection is defined with an additional string parameter:</p>
<p style="padding-left: 30px;">&#8220;string connect:<em>toparametername</em>&#8221; &#8220;<em>fromlayer</em>:<em>fromparametername</em>&#8220;</p>
<p>The connection transfers the value of <em>fromparametername </em>in layer <em>fromlayer </em>to the target parameter in the current shader.  The source parameter must be an output variable of the source shader or a global shader variable.  The target parameter is normally one of the shader&#8217;s input parameters, but it can also be the global input color (Cs) or input opacity (Os).  The source and target parameters must have the same type.</p>
<p>Sample usage:</p>
<pre>Surface "ColorMap"
  "string ColorMapName" "grid.tx"
  "float SetColor" [0]
  "layername" "gridlayer"
Surface "+VMarble"
  "connect:VeinColor" "gridlayer:__Color"</pre>
<p>In this example, the marble vein color is taken from the ColorMap shader&#8217;s __Color output variable.</p>
<h3>Applications</h3>
<p>The <a title="Air Stream for Maya" href="http://www.sitexgraphics.com/html/air_stream.html">Air Stream</a> plug-in for Maya uses the new shader network capability in Air 11 to translate Maya&#8217;s shader networks for rendering with Air.  This approach also easily allows:</p>
<ul>
<li>Air shader parameters to be driven by a Maya shading network</li>
<li>Air shaders and Maya shaders to be mixed in a single network</li>
<li>Air custom shading language functions to be incorporated in a Maya shading network using generic shaders</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://sitexgraphics.com/blog/?feed=rss2&amp;p=81</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A dictionary function for the shading language</title>
		<link>http://sitexgraphics.com/blog/?p=73</link>
		<comments>http://sitexgraphics.com/blog/?p=73#comments</comments>
		<pubDate>Thu, 31 Mar 2011 23:09:00 +0000</pubDate>
		<dc:creator>sitexgraphics</dc:creator>
				<category><![CDATA[Shaders]]></category>
		<category><![CDATA[dso]]></category>
		<category><![CDATA[renderman]]></category>

		<guid isPermaLink="false">http://sitexgraphics.com/blog/?p=73</guid>
		<description><![CDATA[For the Air 11 release we&#8217;ve added new shaders that compute a physical sky environment and sun position based on geographical location and date/time.  We thought it would be nice to be able to enter a location using a simple &#8230; <a href="http://sitexgraphics.com/blog/?p=73">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>For the Air 11 release we&#8217;ve added new shaders that compute a physical sky environment and sun position based on geographical location and date/time.  We thought it would be nice to be able to enter a location using a simple city name instead of having to look up and remember a set of figures for latitude, longitude, and time zone every time.</p>
<p>We need a function that allows us to look up a set of values based on a name, like looking up a word&#8217;s definition in a dictionary.   We can add such a function to Air&#8217;s shading language by implementing a dynamic shadeop, or DSO for short, which will be loaded by Air automatically and used to evaluate our new function.</p>
<p>The dictionary DSO adds the following new functions to the shading language:</p>
<pre>float dictionary(string dictname, string keyname, float fvalue);
float dictionary(string dictname, string keyname, color cvalue);
float dictionary(string dictname, string keyname, string svalue);
</pre>
<p>The dictionary function looks for a text file named dictname and tries to load a list of token value pairs, one per line.  The token values should look like</p>
<pre>Seattle 47.45 -122.3 -8
</pre>
<p>The functions return 0 if they succeed.  If an error occurs, the functions return one of the following error codes:</p>
<pre>-1:  unable to find or read dictionary file
-2:  key name not found
-3:  unable to convert value to the requested type
</pre>
<p>Since Air 11 has not yet been released, here are a couple other uses for the dictionary function that you can try with the current Air release.</p>
<p>The first example uses the dictionary function to allow the base surface color to be specified using a name instead of r,g,b values.  The Air distribution includes a list of named colors in $AIRHOME/vizools/colors.txt (used by the Air Space tool).  Here&#8217;s the source code for a simple NamedColor shader:</p>
<pre>surface NamedColor(
 float Ambient = 1;
 float Diffuse = 1;
 string ColorName = "";
 string ColorList = "$AIRHOME/viztools/colors.txt"
)
{
  color Ct = Cs;
  if (ColorName!="") dictionary(ColorList,ColorName,Ct);
  normal Nf = faceforward (normalize(N),I);
  Oi = Os;
  Ci = Oi * Ct * (Ambient * ambient() + Diffuse * diffuse(Nf));
}</pre>
<p>The dictionary function will expand the reference to the $AIRHOME environment variable in the ColorList value.</p>
<p>In a RIB file, we can then specify a named color as:</p>
<pre>Surface "NamedColor"
 "string ColorName" "neon pink"</pre>
<p>Another application for the dictionary function is to allow simple text files to be used to define &#8220;preset&#8221; values for a shader&#8217;s parameters.  Here&#8217;s an extended version of the standard paintedplastic surface shader with an option to use a file with preset values:</p>
<pre>surface paintedplasticpreset(
 float Ka = 1;
 float Kd = .5;
 float Ks = .5;
 float roughness = .1;
 color specularcolor = 1;
 string texturename = "";
 string preset = "";
)
{
 float preKa=Ka;
 float preKd=Kd;
 float preKs=Ks;
 float preroughness = roughness;
 color prespecularcolor=specularcolor;
 string pretexturename=texturename;

 if (preset!="") {
  dictionary(preset,"Ka",preKa);
  dictionary(preset,"Kd",preKd);
  dictionary(preset,"Ks",preKs);
  dictionary(preset,"roughness",preroughness);
  dictionary(preset,"specularcolor",prespecularcolor);
  dictionary(preset,"texturename",pretexturename);
 }
 Ci = Cs;
 if (pretexturename != "")     Ci *= color texture(pretexturename);
 normal Nf = faceforward (normalize(N),I);
 Oi = Os;
 Ci = Oi * Ci * (preKa*ambient() + preKd*diffuse(Nf)) + prespecularcolor * preKs*specular(Nf,-normalize(I),preroughness);
}</pre>
<p>A sample preset file might look like:</p>
<pre>Kd 0.4
Ks 0.6
roughness 0.2
specularcolor = 1 1 0
texturename = grid.tx</pre>
<p>The new dictionary shadeop can found in this <a href="http://www.sitexgraphics.com/dictionary1.zip">archive</a>.  Unzip the archive to the AIRHOME directory, and the new shadop will automatically be added to the shaders directory of your Air installation (where Air can find it).  Examples and source code for the shadeop can be found in $AIRHOME/examples/dictionary.</p>
]]></content:encoded>
			<wfw:commentRss>http://sitexgraphics.com/blog/?feed=rss2&amp;p=73</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to render a normal map</title>
		<link>http://sitexgraphics.com/blog/?p=59</link>
		<comments>http://sitexgraphics.com/blog/?p=59#comments</comments>
		<pubDate>Sun, 27 Feb 2011 22:32:20 +0000</pubDate>
		<dc:creator>sitexgraphics</dc:creator>
				<category><![CDATA[Shaders]]></category>
		<category><![CDATA[normal map]]></category>
		<category><![CDATA[renderman]]></category>
		<category><![CDATA[rhino]]></category>

		<guid isPermaLink="false">http://sitexgraphics.com/blog/?p=59</guid>
		<description><![CDATA[A poster to the Rhino newsgroup recently asked for an easy way to render a normal map based on a model in Rhino.  This simple surface shader can be used to render such a tangent-space normal map with Air: surface &#8230; <a href="http://sitexgraphics.com/blog/?p=59">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>A poster to the Rhino newsgroup recently asked for an easy way to render a normal map based on a model in Rhino.  This simple surface shader can be used to render such a tangent-space normal map with Air:</p>
<pre>surface RenderTangentNormalMap(
 float ReverseZ = 1;
)
{
 normal NN=normalize(faceforward(N,I));
 if (ReverseZ!=0) setzcomp(NN,-zcomp(NN));
 NN=0.5+0.5*NN;
 Ci = NN;
 Oi = 1;
}
</pre>
<p>Here&#8217;s an <a title="archive" href="http://www.sitexgraphics.com/RenderTangentNormalMap.zip" target="_blank">archive</a> with the source code and a pre-compiled binary for Air.  Air users can install the shader by unzipping the archive to the shaders directory of their Air installation.</p>
<p>To generate a normal map, first be sure the output image gamma is set to 1 (RhinoAir users can find this control on the Air Display page in the Rhino Options dialog).  Assign the above shader to your objects, then render an orthographic viewport.  You should see an image with colors similar to those in this sample:</p>
<p><a href="http://sitexgraphics.com/blog/wp-content/uploads/2011/02/rhinonormalmapsmall.png"><img class="alignnone size-full wp-image-60" title="rhinonormalmapsmall" src="http://sitexgraphics.com/blog/wp-content/uploads/2011/02/rhinonormalmapsmall.png" alt="" width="256" height="256" /></a></p>
<p>To apply the normal map to an object for rendering, assign the VTangentNormalMap shader as the displacement shader for the object, and set the shader&#8217;s TextureName parameter to the file name of the previously generated normal map.  Here&#8217;s a simple rendering using the above map:</p>
<p><a href="http://sitexgraphics.com/blog/wp-content/uploads/2011/02/applynormalmapsmall.jpg"><img class="alignnone size-full wp-image-61" title="applynormalmapsmall" src="http://sitexgraphics.com/blog/wp-content/uploads/2011/02/applynormalmapsmall.jpg" alt="" width="300" height="200" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://sitexgraphics.com/blog/?feed=rss2&amp;p=59</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Viewing the rendering mesh</title>
		<link>http://sitexgraphics.com/blog/?p=47</link>
		<comments>http://sitexgraphics.com/blog/?p=47#comments</comments>
		<pubDate>Sat, 29 Jan 2011 22:49:04 +0000</pubDate>
		<dc:creator>sitexgraphics</dc:creator>
				<category><![CDATA[Outlines]]></category>
		<category><![CDATA[meshes]]></category>
		<category><![CDATA[toon]]></category>

		<guid isPermaLink="false">http://sitexgraphics.com/blog/?p=47</guid>
		<description><![CDATA[Air renders most geometric primitives as meshes of polygons.  Viewing the rendering mesh can sometimes help diagnose errors or optimize rendering, whether the mesh is a polygon mesh provided as input or the result of tessellating a smooth surface primitive. &#8230; <a href="http://sitexgraphics.com/blog/?p=47">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Air renders most geometric primitives as meshes of polygons.  Viewing the rendering mesh can sometimes help diagnose errors or optimize rendering, whether the mesh is a polygon mesh provided as input or the result of tessellating a smooth surface primitive.</p>
<p>You can use Air&#8217;s outline capability to view the individual polygons in a mesh:</p>
<p>One way Air detects edges for outlines is based on a <em>toon id</em> value that is assigned to each element.  By default each geometric primitive is assigned a unique id.  Where two primitives abut in the rendered image, the toon id value changes, and Air will draw an outline.</p>
<p>The toon id for an object can be explicitly specified with:</p>
<pre>Attribute "toon" "float id" [<em>n</em>]</pre>
<p>If the toon id is set to the special value -2, Air automatically assigns a unique id to each face in the rendering mesh.</p>
<p>So to view the rendering mesh, we just need to enable outlines and to set the toon id to -2 for the objects whose mesh we wish to view.  We can do that by placing a few commands in a small text file:</p>
<pre>Option "toon" "maxinkwidth" [0.5]
Attribute "toon" "inkwidth" [0.5]
Attribute "toon" "float id" [-2]</pre>
<p>Save the above commands to a file named viewmesh.rib.  Then render with:</p>
<pre>air -d viewmesh.rib myscene.rib</pre>
<p>We can achieve the same result using a couple of Air&#8217;s command line options:</p>
<pre>air -d -inkw 0.5 -at toon id -2 myscene.rib</pre>
<p>Here are a few images showing the effect of adjusting the flatness tessellation criterion for a blobby object (from 8 to 4 to 2).</p>
<p><a href="http://sitexgraphics.com/blog/wp-content/uploads/2011/01/mesh_outline.png"><img class="alignleft size-full wp-image-53" title="mesh_outline" src="http://sitexgraphics.com/blog/wp-content/uploads/2011/01/mesh_outline.png" alt="" width="600" height="200" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://sitexgraphics.com/blog/?feed=rss2&amp;p=47</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Adding an occlusion pass</title>
		<link>http://sitexgraphics.com/blog/?p=34</link>
		<comments>http://sitexgraphics.com/blog/?p=34#comments</comments>
		<pubDate>Tue, 21 Dec 2010 22:50:28 +0000</pubDate>
		<dc:creator>sitexgraphics</dc:creator>
				<category><![CDATA[Passes]]></category>
		<category><![CDATA[massive]]></category>
		<category><![CDATA[occlusion]]></category>
		<category><![CDATA[passes]]></category>
		<category><![CDATA[renderman]]></category>

		<guid isPermaLink="false">http://sitexgraphics.com/blog/?p=34</guid>
		<description><![CDATA[Air&#8217;s surface shaders provide a consistent set of output variables for common rendering passes such as diffuse, specular, reflection, and per-light channels.  Any or all of these values can be saved during a single invocation of the renderer, either to &#8230; <a href="http://sitexgraphics.com/blog/?p=34">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Air&#8217;s surface shaders provide a consistent set of output variables for common rendering passes such as diffuse, specular, reflection, and per-light channels.  Any or all of these values can be saved during a single invocation of the renderer, either to separate image files or as individual layers in a multi-layer OpenEXR file.  What if we need to save an additional pass, such as occlusion, as part of the rendered image set?</p>
<p>If we were rendering each pass with a separate invocation of the renderer, we could use one of Air&#8217;s command filtering options to override the surface shader assignments with a shader that computes the desired value, occlusion in this case:</p>
<p style="padding-left: 30px;">air -surf occlusionpass myscene.rib</p>
<p>However, if we&#8217;re trying to record all output values in a single rendering, we need to preserve the existing shader assignments.  There are at least two ways to add additional passes to the output mix without clobbering the existing shaders:</p>
<p><strong>Method 1:</strong></p>
<p>Add an additional output variable with the desired value to the surface shaders.  For shaders built with the Vshade user interface, the VPlastic surface shader can serve as a model.  It includes extra blocks that compute an occlusion value exported as a __occlusion output variable.  In the Vshade source  network, the occlusion code and output variables are just two blocks which  can easily be copied to other Vshade surface shaders.</p>
<p style="padding-left: 30px;"><a href="http://sitexgraphics.com/blog/wp-content/uploads/2010/12/vshadeocclusionblocks.png"><img class="alignnone size-full wp-image-40" title="Vshade occlusion blocks" src="http://sitexgraphics.com/blog/wp-content/uploads/2010/12/vshadeocclusionblocks.png" alt="Vshade occlusion blocks" width="319" height="105" /></a></p>
<p>For text-based shaders, we can copy-and-paste the necessary code fragments.  First, add two new arbitrary output variables (AOVs):</p>
<pre>surface mysurf(...;
   output varying color __occlusion = 0;
   output varying vector __bent_normal = 0;
)</pre>
<p>then include code to compute the occlusion values:</p>
<pre>if (raylevel()==0) {
  if ((isshadowray()+isindirectray())==0) {
    float doOcclusion = 0;
    option("display:__occlusion", doOcclusion);

    if (doOcclusion!=0) {
       normal Nf = faceforward(normalize(Normal),I);
       __occlusion = occlusion(Position,Nf,PI*0.5,__bent_normal);
       __bent_normal = vtransform("current","world",__bent_normal);
     }
   }
}</pre>
<p>This code only computes the __occlusion value when it is being saved in an output image.</p>
<p>With this method of computing occlusion, the occlusion quality parameters must be set using the  corresponding indirect attributes, which are documented in the Air user  manual in the Indirect Lighting section of the Lighting chapter.</p>
<p><strong>Method 2:</strong></p>
<p>Use a volume shader that emits the desired value, and assign the volume shader as the Atmosphere shader for the desired objects.  Atmosphere shaders are normally used for volumetric effects.  For scenes that do not require atmospheric effects, we can use a &#8220;fake&#8221; atmosphere shader (that does not modify the main output color or opacity) as a container for additional output variables.</p>
<p>As an example, I&#8217;ve converted to the massive_occlusionpass surface shader included with Air to a volume shader &#8211; massive_occlusion_layer:</p>
<p><a title="http://www.sitexgraphics.com/massive_occlusion_layer.zip" href="http://www.sitexgraphics.com/massive_occlusion_layer.zip" target="_blank">http://www.sitexgraphics.com/massive_occlusion_layer.zip</a></p>
<p>The converted shader provides a __occlusion output variable with the occlusion result; the shader does not alter the output color or opacity from the surface shader.</p>
<p>To assign a volume shader as an atmosphere shader, use the Atmosphere RIB statement:</p>
<pre>Atmosphere "massive_occlusion_layer"</pre>
<p>If you are rendering with Massive, you can assign the above shader to all objects by placing the above text in a small file  and either specifying that file as the rib options file in Massive, or including it on the command line when rendering from a command shell:</p>
<p style="padding-left: 30px;">air addocc.rib myscene.rib</p>
<p>Although the above discussion focused on occlusion, the same techniques can be used to compute and export any desired value for inclusion in a multi-layer EXR file or other storage format.</p>
]]></content:encoded>
			<wfw:commentRss>http://sitexgraphics.com/blog/?feed=rss2&amp;p=34</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Visualizing procedural bounding boxes</title>
		<link>http://sitexgraphics.com/blog/?p=13</link>
		<comments>http://sitexgraphics.com/blog/?p=13#comments</comments>
		<pubDate>Mon, 01 Nov 2010 23:13:07 +0000</pubDate>
		<dc:creator>sitexgraphics</dc:creator>
				<category><![CDATA[RIB Filters]]></category>
		<category><![CDATA[massive]]></category>
		<category><![CDATA[procedural primitive]]></category>
		<category><![CDATA[renderman]]></category>
		<category><![CDATA[rib filter]]></category>

		<guid isPermaLink="false">http://sitexgraphics.com/blog/?p=13</guid>
		<description><![CDATA[Procedural primitives are a powerful mechanism for efficiently rendering complex scenes.  In a scene file a procedural primitive is defined with the Procedural RIB command: Procedural &#8220;type&#8221; [arguments] [minx maxx miny maxy minz maxz] The array of 6 floats at &#8230; <a href="http://sitexgraphics.com/blog/?p=13">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Procedural primitives are a powerful mechanism for efficiently rendering complex scenes.  In a scene file a procedural primitive is defined with the Procedural RIB command:</p>
<p style="padding-left: 30px;">Procedural &#8220;<em>type</em>&#8221; [<em>arguments</em>] [<em>minx maxx miny maxy minz maxz</em>]</p>
<p>The array of 6 floats at the end defines a bounding box for all objects that might be created by the procedural.  The procedural prim acts a placeholder in the scene.  The procedural e is evaluated only when and if the renderer needs to access the interior of the bounding box.  If the bound is never encountered by the renderer &#8211; because say the bounding box is off-screen or occluded by other objects &#8211; the procedural primitive is never evaluated.</p>
<p>Because of the on-demand manner in which a procedural primitive is created, it is important that the bounding box be accurate.  If the bound is too large, the renderer may unnecessarily evaluate a procedural prim whose contents are hidden.  If the bound is too small, objects of created by the procedural primitive may be rendered incorrectly (usually appearing to be clipped along bucket boundaries or the boundaries of the bounding box).</p>
<p>Here is a small RIB filter plugin to aid in visualizing the bounding box for a procedural primitive:</p>
<p style="padding-left: 30px;"><a class="wp-oembed" href="http://www.sitexgraphics.com/showprocbd.zip" target="_blank">http://www.sitexgraphics.com/showprocbd.zip</a></p>
<p>Unzip the archive to the procedurals directory of your Air installation, and Air will be able to find the showprocbd plugin without a path reference.</p>
<p>You can use the -rif command line switch to apply the showprocbd RIB filter to a scene:</p>
<p style="padding-left: 30px;">air -rif showprocbd myscene.rib</p>
<p>Here&#8217;s an example showing a small group of agents from the Massive crowd simulation program.  Massive uses a procedural primitive to generate agents geometry at render time.</p>
<p><a href="http://sitexgraphics.com/blog/wp-content/uploads/2010/11/showprocbd0.jpg"><img class="alignnone size-full wp-image-15" title="showprocbd0" src="http://sitexgraphics.com/blog/wp-content/uploads/2010/11/showprocbd0.jpg" alt="" width="320" height="240" /></a></p>
<p><img class="alignnone size-full wp-image-16" title="showprocbd1" src="http://sitexgraphics.com/blog/wp-content/uploads/2010/11/showprocbd1.jpg" alt="" width="320" height="240" /></p>
<p>By default the showprocbd filter replaces each procedural primitive with a box representing the procedural bound. This can be help accelerate preview rendering in cases where the full expanded geometry is not needed.</p>
<p>Showprocbd has a number of options for customizing its behavior.  For example, you can set the alpha and color for the box:</p>
<p style="padding-left: 30px;">air -rif &#8220;showprocbd boxalpha 0.5 boxcolor 1 .8 .6&#8243; myscene.rib</p>
<p><img class="alignnone size-full wp-image-17" title="showprocbd2" src="http://sitexgraphics.com/blog/wp-content/uploads/2010/11/showprocbd2.jpg" alt="" width="320" height="240" /></p>
<p>Including a &#8220;replace 0&#8243; in the argument list retains the contents of the procedural primitive:</p>
<p style="padding-left: 30px;">air -rif &#8220;showprocbd boxalpha 0.5 replace 0&#8243; myscene.rib</p>
<p><img class="alignnone size-full wp-image-18" title="showprocbd3" src="http://sitexgraphics.com/blog/wp-content/uploads/2010/11/showprocbd3.jpg" alt="" width="320" height="240" /></p>
<p>In this scene we can see that for some agents the elbows protrude slightly outside the bounding box.</p>
<p>The box can be represented by lines instead of or in addition to polygons:</p>
<p style="padding-left: 30px;">air -rif &#8220;showprocbd boxalpha 0 linewidth 3 linecolor .7 .8 .5&#8243; myscene.rib</p>
<p><img class="alignnone size-full wp-image-20" title="showprocbd4" src="http://sitexgraphics.com/blog/wp-content/uploads/2010/11/showprocbd4.jpg" alt="" width="320" height="240" /></p>
<p>Box corners can also be rendered:</p>
<p style="padding-left: 30px;">air -rif &#8220;showprocbd boxalpha 0 cornerwidth 20 cornercolor 1 0 0 linewidth 5&#8243; myscene.rib</p>
<p><img class="alignnone size-full wp-image-21" title="showprocbd5" src="http://sitexgraphics.com/blog/wp-content/uploads/2010/11/showprocbd5.jpg" alt="" width="320" height="240" /></p>
<p>Finally, instead of applying the filter as a command line option, you can define the current filter for an object as a RIB attribute:</p>
<p style="padding-left: 30px;">Attribute &#8220;render&#8221; &#8220;rifilter&#8221; &#8220;showprocbd replace 0 boxalpha 0.5&#8243;</p>
<p style="padding-left: 30px;">
]]></content:encoded>
			<wfw:commentRss>http://sitexgraphics.com/blog/?feed=rss2&amp;p=13</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

