Wattle and Daub Tutorial The math used in this shader template is limited to Pythagoras' theorum for finding the hypoteneuse of a triangle (a²+b²=c²), and the cosine curve. To define the displacement of the basketweave, mod()
is used to divide the 0 to 1 ranges of s and t into a user-defined number
of blocks. Within each block, ss and tt will range from 0 to 1. The number
of blocks will be represented in the user controls as float ss = mod(s * numSections, 1), To start, the branches are defined as a stripe running through the center of each tt block. The width of the stripe is defined by branchRad. BranchRoot is by default 0.5 (halfway down the block) but could easily be changed if desired. float branchRoot = 0.5, However this formula will only give half the number of branches needed. A second row of branches will be added that uses 0 and 1 as its root instead of branchRoot. But since the branches overlap along tt with radii over 0.25, there isn't any point adding a second row until we've defined the curvature of the first row. Here is a cross section of a branch. Hump at its highest point (the middle of a branch) is equal to the radius of the branch. Pythagoras' theorum can be used to find the hump for any other value of the base of the triangle. Since the branch radius remains constant, the branch will form a perfect half-circle. float branchRoot = 0.5, Remember that depending on the number of branches, the aspect ratio of hump to tt will change, so the branch may not always appear perfectly round at rendertime. This can be resolved by multiplying hump by a user-defined constant at the end of the shader, so that a branch can be as flat or as tall as the user wants. At this point the second, interleaved row of branches can be added by offsetting them along tt by 0.5 before the final hump value is calculated. /* if we're within the area of a primary branch */ Here's where it gets more complicated. The branches need to appear to weave in and out of each other, without losing their curvature. This can be done by multiplying the hump value by a modified cosine wave along ss. I found that a cosine wave alone would push the branch too far through the "wattle" (hump=0 surface). It is also necessary to use 1-cosine so that the branch dips in the center instead of rising. /* if we're within the area of a primary branch */ Next, the poles are added. They are built basically the same way as the branches, but using ss instead of tt. Again, it's necessary to multiply by a constant so that the branches appear to be woven over and under the poles instead of penetrating them, as they would if the pole radius was the same as a branch radius. /* if we're within the area of a primary pole */ Last, some randomness is added to the radii of the branches (before anything else is calculated) to give a more organic, less mechanical look. The randomness factor pulls in user variables and then applies noise to them based on the value along s or t. If ss and tt were used instead, each branch would have identical distortion. float branchRad = userBranchRad + (((noise(s*branchRadVarianceS,
t*branchRadVarianceS)-0.5)*2)*branchRadVarianceT);
Shader Template in SLIM displacement /* custom variable declarations */ /* conversion of variables in convenient user scale to actual
scale, may need adjustment */ /* randomize user inputs */ /* STEP 1 - make a copy of the surface normal one unit in
length */ /* if we're within the area of a primary branch */ /* STEP 4 - calculate the new orientation of the surface
normal */ |

© Copyright 2006 by Joanna Erbach. Reproduce for educational purposes only.