<?xml version='1.0' encoding='UTF-8'?>

<?xml-stylesheet href="./_c74_tut.xsl" type="text/xsl"?>
<chapter name="Tutorial 50: Procedural Texturing &amp; Modeling">
<setdocpatch name="50jProcedural" patch="50jProcedural.maxpat"/>

<previous name="jitterchapter49">Colorspaces</previous>
<next name="jitterchapter51">Jitter Java</next>
<parent name="jitindex">Jitter Tutorials</parent>



<h1>Tutorial 50: Procedural Texturing &amp; Modeling</h1>
<p>In this Tutorial we will be examining different operations that can be used to construct a procedural model of a texture or some form of geometric data.</p>

<p>Procedural techniques are a powerful way of defining some aspect of a computer-generated model through algorithms and/or mathematical functions. In contrast to using pre-existing data such as a static images or photographs, procedural models can generate visual complexity of arbitrary resolution and infinite variation. In conjunction with parametric controls, such models can be used to build a flexible interface for controlling complex behaviors and capturing a special effect.</p>

<p>Jitter provides a comprehensive set of basis functions and generators that are exposed through the <o>jit.bfg</o> object. Each function performs a point-wise operation in <i>n</i>-dimensional space whose evaluation is independent of neighboring results. This means that these operations can be performed on any number of dimensions, across any coordinate, without any need of referencing existing calculations. In addition, since they all share a common interface, these objects can be combined together and evaluated in a function graph by cross-referencing several <o>jit.bfg</o> objects.</p>

<p>There are several categories of functions, each of which are characterized by a different intended use. These categories include <i>fractal</i>, <i>noise</i>, <i>filter</i>, <i>transfer</i>, and <i>distance</i> operations. Functions contained in these folders can be passed by name to <o>jit.bfg</o> either fully qualified (category.classname) or relaxed (classname).</p>

<p>Before looking at these categories in detail, we'll first explore the general interface of <o>jit.bfg</o> and show how to create different types of procedural functions and fill a <o>jit.matrix</o> with our results.</p>

<h2>jit.bfg</h2>

<p>Once the patch loads, take a look at the different objects being used. Notice that we have a <o>metro</o> object attached to the <o>jit.bfg</o> object. Once activated, a <m>bang</m> message will notify <o>jit.bfg</o> to evaluate and output a Jitter matrix just like most other Jitter objects. In this example, <o>jit.bfg</o> has been set up to generate a single plane matrix of type <m>float32</m> and size <m>128x128</m>.</p>

<bullet>Click on the <o>toggle</o> box connected to the <o>metro</o> object to begin sending <m>bang</m> messages to <o>jit.bfg</o>.</bullet>
<p>Notice that the <o>jit.pwindow</o> object remains solid black in color!  Since <o>jit.bfg</o> has not been told what basis function evaluate, <o>jit.bfg</o> is not outputting a matrix and <o>jit.pwindow</o> remains unchanged. </p>

<bullet>Select the <m>noise.cell</m> basis function from the list in the <o>umenu</o> object.</bullet>

<illustration><img src="images/jitterchapter50a.png"/>An evaluated basis function.</illustration>

<p>Now that <o>jit.bfg</o> has been given a function to evaluate, we can see the results of its calculation in <o>jit.pwindow</o>. Internally, <o>jit.bfg</o> is generating a series of Cartesian coordinates that it passes to the indicated <m>basis</m> function during its evaluation.</p>

<p>If we wanted to, we could adjust these coordinates and have <o>jit.bfg</o> perform the evaluation over a different domain. </p>

<bullet>Change the value of the <o>number</o> box connected to the <m>scale</m> <o>message</o> box.</bullet>
<p>Notice that the results of <o>jit.bfg</o> change as we adjust the domain.</p>

<bullet>Select the <m>distance.euclidean</m> basis function from the list in the <o>umenu</o> object.</bullet>
<bullet>Again change the value of the <o>number</o> box connected to the <m>scale</m> <o>message</o> box.</bullet>
<p>Notice that positive values in the <m>scale</m> <o>number</o> box have little effect on the results being shown in <o>jit.pwindow</o>, whereas negative values flip the image components from white to black. What is going on?  Distance should always be positive and increase outward from the origin, right?</p>

<h2>jit.normalize</h2>
<p>The output of <o>jit.bfg</o> goes into a <o>jit.normalize</o> object connected to the <o>jit.pwindow</o>. This object will examine an incoming matrix and scale the minimum and maximum values into a normalized range of <m>0</m>-<m>1</m>.</p>

<p>When we changed the <m>scale</m> values being sent to <o>jit.bfg</o> for evaluating the <m>distance.euclidean</m> function from positive to negative, the highest and lowest values that were being outputted from <o>jit.bfg</o> switched as we crossed over the origin. Since <o>jit.normalize</o> always scales the input matrix maximum to <m>1</m> and the minimum to <m>0</m>, our colors flipped. </p>

<p>Since the output range of <o>jit.bfg</o> may yield extremely large results, especially when evaluating unbounded functions such as fractals, we need to normalize our output in order to map the results for display.</p>

<h2>Basis Categories</h2>
<p>Now that we are familiar with the basic interface for setting up <o>jit.bfg</o> and specifying a basis function to evaluate, let's examine the contents of each function category.</p>

<h2>Distance Functions</h2>
<p>The functions in the <m>distance</m> category each define a unique metric for determining the positional difference from a given point to the global origin.</p>

<p>Descriptions of each of these functions are provided in the following list.</p>

<bullet><m>chebychev</m>:  Absolute maximum difference between two points.</bullet>
<illustration><img src="images/jitterchapter50b.png"/></illustration>
<bullet><m>euclidean</m>: True straight line distance in Euclidean space.</bullet>
<illustration><img src="images/jitterchapter50c.png"/></illustration>
<bullet><m>euclidean.squared</m>: Squared Euclidean distance.</bullet>
<illustration><img src="images/jitterchapter50d.png"/></illustration>
<bullet><m>manhattan</m>: Rectilinear distance measured along axes at right angles.</bullet>
<illustration><img src="images/jitterchapter50e.png"/></illustration>
<bullet><m>manhattan.radial</m>: Manhattan distance with radius fall-off control.</bullet>
<illustration><img src="images/jitterchapter50f.png"/></illustration>
<bullet><m>minkovsky</m>: Exponentially controlled distance.</bullet>
<illustration><img src="images/jitterchapter50g.png"/></illustration>
<p>The <m>noise.voronoi</m> object requires one of these<m> distance</m> objects to be specified as part of its evaluation.</p>

<h2>Filter Functions</h2>
<p>The <m>filter</m> category contains signal processing filters which can be used to perform image sampling and reconstruction or to create pre-computed kernels for a general convolution.</p>

<p>Descriptions of each of these functions are provided in the following list.</p>

<bullet><m>box</m>:  Sums all samples in the filter area with equal weight.</bullet>
<illustration><img src="images/jitterchapter50h.png"/></illustration>
<bullet><m>gaussian</m>: Weights samples in the filter area using a bell curve.</bullet>
<illustration><img src="images/jitterchapter50i.png"/></illustration>
<bullet><m>lanczossinc</m>: Weights samples using a steep windowed sinc curve.</bullet>
<illustration><img src="images/jitterchapter50j.png"/></illustration>
<bullet><m>mitchell</m>: Weights samples using a controllable cubic polynomial.</bullet>
<illustration><img src="images/jitterchapter50k.png"/></illustration>
<bullet><m>disk</m>: Sums all samples inside the filter's radius with equal weight.</bullet>
<illustration><img src="images/jitterchapter50l.png"/></illustration>
<bullet><m>sinc</m>: Weights samples using an un-windowed sinc curve.</bullet>
<illustration><img src="images/jitterchapter50m.png"/></illustration>
<bullet><m>catmullrom</m>: Weights samples using a Catmull-Rom cubic polynomial.</bullet>
<illustration><img src="images/jitterchapter50n.png"/></illustration>
<bullet><m>bessel</m>: Weights samples with a linear phase response.</bullet>
<illustration><img src="images/jitterchapter50o.png"/></illustration>
<bullet><m>triangle</m>: Weights samples in the filter area using a pyramid.</bullet>
<illustration><img src="images/jitterchapter50p.png"/></illustration>
<p>These objects are used as parameters to both the <m>noise.value.convolution</m> and the <m>noise.sparse.convolution</m> objects, which expect to be given a <m>filter</m> object as part of their evaluation.</p>

<h2>Transfer Functions</h2>
<p>Functions that map input to a different output are contained in the <m>transfer</m> category. Most of these functions operate only on a single dimension within the unit interval <m>0</m>-<m>1</m>.</p>

<p>A brief description of these functions is contained in the list below.</p>

<bullet><m>step</m>:  Always <m>1</m> if given value is less than threshold.</bullet>
<illustration><img src="images/jitterchapter50q.png"/></illustration>
<bullet><m>smoothstep</m>: Step function with cubic smoothing at boundaries.</bullet>
<illustration><img src="images/jitterchapter50r.png"/></illustration>
<bullet><m>bias</m>: Polynomial similar to gamma but remapped to unit interval.</bullet>
<illustration><img src="images/jitterchapter50s.png"/></illustration>
<bullet><m>cubic</m>: Generic 3<sup>rd</sup> order polynomial with controllable coefficients.</bullet>
<illustration><img src="images/jitterchapter50t.png"/></illustration>
<bullet><m>saw</m>: Periodic triangle pulse train.</bullet>
<illustration><img src="images/jitterchapter50u.png"/></illustration>
<bullet><m>quintic</m>: Generic 5th order polynomial with controllable coefficients.</bullet>
<illustration><img src="images/jitterchapter50v.png"/></illustration>
<bullet><m>gain</m>: S-Shaped polynomial evaluated inside unit interval. Note: the default settings will result in a linear curve instead of the descriptive S-curve shape.</bullet>
<illustration><img src="images/jitterchapter50w.png"/></illustration>
<bullet><m>pulse</m>: Periodic step function.</bullet>
<illustration><img src="images/jitterchapter50x.png"/></illustration>
<bullet><m>smoothpulse</m>: Periodic step function with cubic smoothing at boundaries.</bullet>
<illustration><img src="images/jitterchapter50y.png"/></illustration>
<bullet><m>sine</m>: Periodic sinusoidal curve.</bullet>
<illustration><img src="images/jitterchapter50z.png"/></illustration>
<bullet><m>linear</m>: Linear function across unit interval.</bullet>
<bullet><m>solarize</m>: Scales given value if threshold is exceeded.</bullet>
<p>These <m>transfer</m> functions can be used inside of several of the <m>noise</m> objects to change their smoothing function and/or alter their output.</p>

<h2>Noise Functions</h2>
<p>Deterministic stochastic patterns (aka pseudo-random coherent noise functions) are the cornerstone of nearly every procedural model. They allow a controllable amount of complexity to be created by adding visual detail. </p>

<p>A brief description of these functions is contained in the list below.</p>

<bullet><m>cellnoise</m>: Coherent blocky noise.</bullet>
<illustration><img src="images/jitterchapter50za.png"/></illustration>
<bullet><m>checker</m>: Periodic checker squares.</bullet>
<illustration><img src="images/jitterchapter50zb.png"/></illustration>
<bullet><m>value.cubicspline</m>: Polynomial smoothed pseudo-random values.</bullet>
<illustration><img src="images/jitterchapter50zc.png"/></illustration>
<bullet><m>value.convolution</m>: Convolution filtered pseudo-random values.</bullet>
<illustration><img src="images/jitterchapter50zd.png"/></illustration>
<bullet><m>sparse.convolution</m>: Convolution filtered pseudo-random feature points.</bullet>
<illustration><img src="images/jitterchapter50ze.png"/></illustration>
<bullet><m>gradient</m>: Directionally weighted polynomially interpolated values.</bullet>
<illustration><img src="images/jitterchapter50zf.png"/></illustration>
<bullet><m>simplex</m>: Simplex weighted pseudo-random values.</bullet>
<illustration><img src="images/jitterchapter50zg.png"/></illustration>
<bullet><m>voronoi</m>: Distance weighted pseudo-random feature points.</bullet>
<illustration><img src="images/jitterchapter50zh.png"/></illustration>
<bullet><m>distorted</m>: Domain distorted combinational noise.</bullet>
<illustration><img src="images/jitterchapter50zi.png"/></illustration>
<p>All of these functions are generators with the exception of the <m>noise.distorted</m> object, which is a binary operator and uses two existing functions for its evaluation.</p>

<h2>Fractal Functions</h2>
<p>Fractals provide a specialized form of generation by combining multiple scales or octaves of another basis function. This process forms the characteristic self-similarity exhibited by all fractals.</p>

<p>A brief description of these functions is contained in the list below.</p>

<bullet><m>mono</m>: Additive fractal with global simularity across scales.</bullet>
<illustration><img src="images/jitterchapter50zj.png"/></illustration>
<bullet><m>multi</m>: Multiplicative fractal with varying simularity across scales.</bullet>
<illustration><img src="images/jitterchapter50zk.png"/></illustration>
<bullet><m>multi.hybrid</m>: A hybrid additive and multiplicative fractal.</bullet>
<illustration><img src="images/jitterchapter50zl.png"/></illustration>
<bullet><m>multi.hetero</m>: Heterogenous multiplicative fractal.</bullet>
<illustration><img src="images/jitterchapter50zm.png"/></illustration>
<bullet><m>multi.ridged</m>: Multiplicative fractal with sharp ridges.</bullet>
<illustration><img src="images/jitterchapter50zn.png"/></illustration>
<bullet><m>turbulence</m>: Additive mono-fractal with sharp ridges.</bullet>
<illustration><img src="images/jitterchapter50zo.png"/></illustration>

<h2>Other Attributes &amp; Messages</h2>
<bullet>Select the <m>noise.checker</m> basis function from the <o>umenu</o> object.</bullet>
<p>Notice that in addition to the <m>scale</m> message that we used previously, we can also transform the evaluation coordinates through <m>rotation</m>, translation (via <m>offset</m>) and by adjusting their <m>origin</m>.</p>

<bullet>Change the 1<sup>st</sup> and 2<sup>nd</sup> <o>number</o> boxes connected to <m>origin</m> to change the <i>x</i> and <i>y</i> origin.</bullet>
<bullet>Change the 1<sup>st</sup> and 2<sup>nd</sup> <o>number</o> boxes connected to <m>offset</m> to change the <i>x</i> and <i>y</i> offset position.</bullet>
<bullet>Change the 1<sup>st</sup> <o>number</o> box connected to <m>rotation</m> to change our rotation angle about the <i>x</i> axis.</bullet>
<p>Notice the effect of the transform. Also notice the drop in performance when a <m>rotation</m> is performed &#x2013; we will always get better frame rates if the <m>rotation</m> attribute is left at <m>0</m> for each matrix dimension.</p>

<div>
<techdetail><i>Technical Detail:</i> In addition to the internal coordinate generation already described, <o>jit.bfg</o> also accepts an input matrix of coordinates to evaluate (XYZ map to planes <m>0-2</m>, and the input matrix must be the same <m>dim</m> as the <o>jit.bfg</o> output matrix).</techdetail>
</div>
<bullet>Change the 1<sup>st</sup> <o>number</o> box connected to <m>rotation</m> to <m>0</m> to disable rotation.</bullet>
<bullet>Click the <o>toggle</o> box connected to <m>autocenter</m> to enable automatic centering.</bullet>
<p>If the <m>autocenter</m> attribute is set to <m>1</m>, the current matrix <m>dim</m> sizes will be used to place the origin in the center of the output matrix, overriding any values already set for the origin.</p>

<bullet>Click the <o>toggle</o> box connected to <m>autocenter</m> again to disable automatic centering.</bullet>
<bullet>Select the <m>noise.gradient</m> basis function from the <o>umenu</o> object.</bullet>
<bullet>Click the <m>dim 128 128 1</m> <o>message</o> box.</bullet>
<p>As mentioned previously, all of the basis functions that Jitter provides can be evaluated over any number of dimensions. This message has changed our output matrix to be a 3D matrix, and has correspondingly set the evaluation to be performed in 3-dimensional space. Since our display is still a 2D screen, we only need to evaluate a single slice in 3D, and thus our 3<sup>rd</sup> dim is set to 1.</p>

<bullet>Change the 3<sup>rd</sup> <o>number</o> box connected to <m>offset</m> to change the <i>z</i> evaluation position.</bullet>
<p>Notice how our results change. We are now traversing along the <i>z</i>-axis as if we were moving forward/backwards through a volume aligned with the screen.</p>

<bullet>Select <m>float64</m> from the <o>umenu</o> connected to the <m>precision</m> message.</bullet>
<p>The <m>precision</m> message can be used to change the <o>jit.bfg</o> object&#x2019;s internal evaluation precision. This may be desirable if we need more or less accurate results without changing the output matrix type.</p>

<bullet>Change the 3<sup>rd</sup> <o>number</o> box connected to <m>offset</m> to change the <i>z</i> evaluation position.</bullet>
<p>Notice how the higher precision affects the frame rate reported by the <o>jit.fpsgui</o> object. We should be careful to only use <m>float64</m> precision when needed. </p>

<bullet>Select <m>float32</m> from the <o>umenu</o> connected to the <m>precision</m> message.</bullet>
<bullet>Change the <m>planecount</m> for <o>jit.bfg</o> from <m>1</m> to <m>3</m> to enable RGB output.</bullet>
<p>In addition to <i>n</i>-dimensional evaluation, <o>jit.bfg</o> can generate up to 32 planes per dimension. Each plane is offset by a pseudo-random fractional amount controlled by the <m>align</m> attribute. </p>

<bullet>Change the <o>number</o> box connected to <m>align</m> for <o>jit.bfg</o>.</bullet>
<p>Notice how the planes separate and become more visible as the <m>align</m> amount gets larger.</p>

<bullet>To see more specific examples for different combinations of <i>basis</i> functions, open the help patch for the <o>jit.bfg</o> object and look in the subpatchers for each category of function..</bullet>
<div>
<techdetail><i>Technical Detail:</i> The output of <o>jit.bfg</o> can actually be used as an input to another <o>jit.bfg</o> to perform domain distortion, similar to the way <m>noise.distorted</m> operates. Check out the example patch in <i>jit-examples/other/jit.bfg.distorter.pat.</i></techdetail>
</div>

<h2>Summary</h2>
<p>The <o>jit.bfg</o> object gives us access to a library of procedural basis functions and generators that we can use to define a procedural model for creating textures and modifying geometry. Internally <o>jit.bfg</o> generates Cartesian coordinates along a grid. These coordinates can be transformed using the corresponding <m>origin</m>, <m>offset</m>, and <m>rotation</m> attributes, or overridden altogether via an input matrix containing evaluation coordinates.</p>

	<seealsolist>
		<seealso name="jit.bfg">Evaluates a procedural basis function graph</seealso>
		<seealso name="jit.matrix">The Jitter Matrix!</seealso>
		<seealso name="jit.normalize">Normalize a matrix</seealso>
		<seealso name="jit.pwindow">In-Patcher Window</seealso>
		<seealso name="umenu">Pop-up menu, to display and send commands</seealso>
	</seealsolist>
	</chapter>
