Permalink
Browse files

Add two conversions of renderman utility scripts.

  • Loading branch information...
1 parent 92718a8 commit 4e5882a74ab9598aa5d4def9f0245a0b322749d5 sambler committed Apr 20, 2013
Showing with 613 additions and 0 deletions.
  1. +340 −0 lib/noises_osl.h
  2. +273 −0 lib/patterns_osl.h
View
340 lib/noises_osl.h
@@ -0,0 +1,340 @@
+/*
+ * noises_osl.h
+ * from https://github.com/sambler/osl-shaders
+ */
+
+/************************************************************************
+ * noises_osl.h - OSL version of noises.h (see below)
+ * for use with Blender/Cycles #include "noises_osl.h"
+ *
+ ************************************************************************/
+
+ /************************************************************************
+ * noises.h - various noise-based patterns
+ *
+ * Author: Larry Gritz (gritzl@acm.org), though they're obvious to any
+ * experience shader writer.
+ *
+ * Reference:
+ * _Advanced RenderMan: Creating CGI for Motion Picture_,
+ * by Anthony A. Apodaca and Larry Gritz, Morgan Kaufmann, 1999.
+ *
+ * $Revision: 1.7 $ $Date: 2006/03/17 17:31:39 $
+ *
+ ************************************************************************/
+
+#ifndef CCL_STDOSL_H
+#include "stdosl.h"
+#endif
+#ifndef NOISES_H
+#define NOISES_H 1
+
+#ifndef PATTERNS_H
+#include "patterns_osl.h" /* Needed for filteredabs */
+#endif
+
+
+#define snoise2(x) (2.5*(noise(x)-0.5)) /* need to check this one */
+#define vsnoise(p) (2 * (vector noise(p)) - 1)
+#define DNoise(x) ((2*(point noise(x))) - point(1,1,1))
+#define fnoise(p,width) (noise(p) * (1-smoothstep (0.2,0.75,width)))
+#define adjustNoise(x, y, minVal, maxVal) snoise (x,y) * ((maxVal)-(minVal)+(minVal))
+
+
+/* uniformly distributed noise
+ * #define udn(x,lo,hi) (smoothstep(.25, .75, noise(x)) * ((hi) - (lo)) + (lo))
+ * #define udn2(x,y,lo,hi) (smoothstep(.25, .75, noise(x,y)) * ((hi)-(lo))+(lo))
+ */
+float udn(float x, float lo, float hi){
+ return smoothstep(.25, .75, noise(x)) * (hi-lo) + (lo);
+ }
+float udn2(float x, float y, float lo, float hi){
+ return smoothstep(.25, .75, noise(x,y)) * (hi-lo) + (lo);
+ }
+
+float f3f(point p){
+ return (p[0] + p[1] + p[2]) * (1.0 / 3.0);
+}
+
+
+/* If we know the filter size, we can crudely antialias snoise by fading
+ * to its average value at approximately the Nyquist limit.
+ * #define filteredsnoise(p,width) (snoise(p) * (1-smoothstep (0.2,0.75,width)))
+ * #define filteredvsnoise(p,width) (vsnoise(p) * (1-smoothstep (0.2,0.75,width)))
+ */
+
+ point filteredvsnoise(point p, float width) {
+ return snoise(p) * (1.0-smoothstep(0.2,0.75,width));
+}
+
+ float filteredsnoise(point p, float width) {
+
+ return f3f(filteredvsnoise(p,width));
+}
+
+
+
+/* fractional Brownian motion
+ * Inputs:
+ * p, filtwidth position and approximate inter-pixel spacing
+ * octaves max # of octaves to calculate
+ * lacunarity frequency spacing between successive octaves
+ * gain scaling factor between successive octaves
+ */
+float fBm (point p, float filtwidth,
+ float octaves, float lacunarity, float gain)
+{
+ float amp = 1;
+ point pp = p;
+ float sum = 0;
+ float fw = filtwidth;
+ float i;
+
+ for (i = 0; i < octaves; i += 1) {
+ sum += amp * filteredsnoise(pp, fw);
+ amp *= gain; pp *= lacunarity; fw *= lacunarity;
+ }
+ return sum;
+}
+
+
+float fBm_default(point p){
+ return fBm(p, filterwidth(f3f(p)), 4, 2, 0.5);
+}
+
+
+
+/* A vector-valued antialiased fBm. */
+vector
+vfBm (point p, float filtwidth,
+ float octaves, float lacunarity, float gain)
+{
+ float amp = 1;
+ point pp = p;
+ vector sum = 0;
+ float fw = filtwidth;
+ float i;
+
+ for (i = 0; i < octaves; i += 1) {
+ sum += amp * filteredvsnoise (pp, fw);
+ amp *= gain; pp *= lacunarity; fw *= lacunarity;
+ }
+ return sum;
+}
+
+
+/* Typical use of vfBm: */
+vector vfBm_default(point p) {
+ return vfBm (p, filterwidth(f3f(p)), 4, 2, 0.5);
+ }
+
+
+/* The stuff that Ken Musgrave calls "VLNoise" */
+#define VLNoise(Pt,scale) (snoise(vsnoise(Pt)*scale+Pt))
+#define filteredVLNoise(Pt,fwidth,scale) \
+ (filteredsnoise(filteredvsnoise(Pt,fwidth)*scale+Pt,fwidth))
+
+
+float VLfBm (point p, float filtwidth,
+ float octaves, float lacunarity, float gain, float scale)
+{
+ float amp = 1;
+ point pp = p;
+ float sum = 0;
+ float fw = filtwidth;
+ float i;
+
+ for (i = 0; i < octaves; i += 1) {
+ sum += amp * filteredVLNoise (pp, fw, scale);
+ amp *= gain; pp *= lacunarity; fw *= lacunarity;
+ }
+ return sum;
+}
+
+
+/* Typical use of vfBm: */
+float VLfBm_default(point p){
+ return VLfBm (p, filterwidth(f3f(p)), 4, 2, 0.5, 1.0);
+}
+
+
+
+/* Antialiased turbulence. Watch out -- the abs() call introduces infinite
+ * frequency content, which makes our antialiasing efforts much trickier!
+ */
+
+float turbulence(point p, float filtwidth, float octaves, float lacunarity, float gain) {
+ float du, dv; /* Needed for filterwidth macro */
+ float amp = 1;
+ point pp = p;
+ float sum = 0, fw = filtwidth;
+ float i;
+
+ for (i = 0; i < octaves; i += 1) {
+ float n = filteredsnoise (pp, fw);
+ sum += amp * filteredabs (n, fw);
+ amp *= gain; pp *= lacunarity; fw *= lacunarity;
+ }
+ return sum;
+}
+
+
+/* Typical use of turbulence: */
+float turbulence_default(point p) {
+ return turbulence(p, filterwidth(f3f(p)), 4, 2, 0.5);
+ }
+
+
+
+
+/***************************************************************************
+ * Voronoi cell noise (a.k.a. Worley noise) functions
+ *
+ * These functions assume that space is filled with "features" (points
+ * of interest). There are interestingpatterns we can make by
+ * figuring out which feature we are closest to, or to what extent
+ * we're on the boundary between two features. Several varieties of
+ * these computations are below, categorized by the dimension of their
+ * domains, and the number of close features they are interested in.
+ *
+ * All these functions have similar inputs:
+ * P - position to test (for 3-D varieties; 2-D varieties use ss,tt)
+ * jitter - how much to jitter the cell center positions (1 is typical,
+ * smaller values make a more regular pattern, larger values
+ * make a more jagged pattern; use jitter >1 at your risk!).
+ * And outputs:
+ * f_n - distance to the nth nearest feature (f1 is closest, f2 is
+ * the distance to the 2nd closest, etc.)
+ * pos_n - the position of the nth nearest feature. For 2-D varieties,
+ * these are instead spos_n and tpos_n.
+ ***************************************************************************/
+
+/* Voronoi cell noise (a.k.a. Worley noise) -- 3-D, 1-feature version. */
+void voronoi_f1_3d (point P, float jitter, output float f1, output point pos1)
+{
+ point thiscell = point (floor(P[0])+0.5, floor(P[1])+0.5,
+ floor(P[2])+0.5);
+ f1 = 1000;
+ float i, j, k;
+ for (i = -1; i <= 1; i += 1) {
+ for (j = -1; j <= 1; j += 1) {
+ for (k = -1; k <= 1; k += 1) {
+ point testcell = thiscell + vector(i,j,k);
+ point pos = testcell +
+ jitter * ( cellnoise (testcell) - 0.5);
+ vector offset = pos - P;
+ float dist = dot(offset,offset); /* actually dist^2 */
+ if (dist < f1) {
+ f1 = dist; pos1 = pos;
+ }
+ }
+ }
+ }
+ f1 = sqrt(f1);
+}
+
+
+/* Voronoi cell noise (a.k.a. Worley noise) -- 3-D, 2-feature version. */
+void
+voronoi_f1f2_3d (point P,
+ float jitter,
+ output float f1, output point pos1,
+ output float f2, output point pos2
+ )
+{
+ point thiscell = point (floor(P[0])+0.5, floor(P[1])+0.5,
+ floor(P[2])+0.5);
+ f1 = f2 = 1000;
+ float i, j, k;
+ for (i = -1; i <= 1; i += 1) {
+ for (j = -1; j <= 1; j += 1) {
+ for (k = -1; k <= 1; k += 1) {
+ point testcell = thiscell + vector(i,j,k);
+ point pos = testcell +
+ jitter * (cellnoise (testcell) - 0.5);
+ vector offset = pos - P;
+ float dist = dot(offset,offset); /* actually dist^2 */
+ if (dist < f1) {
+ f2 = f1; pos2 = pos1;
+ f1 = dist; pos1 = pos;
+ } else if (dist < f2) {
+ f2 = dist; pos2 = pos;
+ }
+ }
+ }
+ }
+ f1 = sqrt(f1); f2 = sqrt(f2);
+}
+
+
+/* Voronoi cell noise (a.k.a. Worley noise) -- 2-D, 1-feature version. */
+void
+voronoi_f1_2d (float ss, float tt,
+ float jitter,
+ output float f1,
+ output float spos1, output float tpos1
+ )
+{
+ float sthiscell = floor(ss)+0.5, tthiscell = floor(tt)+0.5;
+ f1 = 1000;
+ float i, j;
+ for (i = -1; i <= 1; i += 1) {
+ float stestcell = sthiscell + i;
+ for (j = -1; j <= 1; j += 1) {
+ float ttestcell = tthiscell + j;
+ float spos = stestcell +
+ jitter * (cellnoise(stestcell, ttestcell) - 0.5);
+ float tpos = ttestcell +
+ jitter * (cellnoise(stestcell+23, ttestcell-87) - 0.5);
+ float soffset = spos - ss;
+ float toffset = tpos - tt;
+ float dist = soffset*soffset + toffset*toffset;
+ if (dist < f1) {
+ f1 = dist;
+ spos1 = spos; tpos1 = tpos;
+ }
+ }
+ }
+ f1 = sqrt(f1);
+}
+
+
+/* Voronoi cell noise (a.k.a. Worley noise) -- 2-D, 2-feature version. */
+void
+voronoi_f1f2_2d (float ss, float tt,
+ float jitter,
+ output float f1,
+ output float spos1, output float tpos1,
+ output float f2,
+ output float spos2, output float tpos2
+ )
+{
+ float sthiscell = floor(ss)+0.5, tthiscell = floor(tt)+0.5;
+ f1 = f2 = 1000;
+ float i, j;
+ for (i = -1; i <= 1; i += 1) {
+ float stestcell = sthiscell + i;
+ for (j = -1; j <= 1; j += 1) {
+ float ttestcell = tthiscell + j;
+ float spos = stestcell +
+ jitter * (cellnoise(stestcell, ttestcell) - 0.5);
+ float tpos = ttestcell +
+ jitter * (cellnoise(stestcell+23, ttestcell-87) - 0.5);
+ float soffset = spos - ss;
+ float toffset = tpos - tt;
+ float dist = soffset*soffset + toffset*toffset;
+ if (dist < f1) {
+ f2 = f1; spos2 = spos1; tpos2 = tpos1;
+ f1 = dist; spos1 = spos; tpos1 = tpos;
+ } else if (dist < f2) {
+ f2 = dist;
+ spos2 = spos; tpos2 = tpos;
+ }
+ }
+ }
+ f1 = sqrt(f1); f2 = sqrt(f2);
+}
+
+
+#endif /* NOISES_H */
+
View
273 lib/patterns_osl.h
@@ -0,0 +1,273 @@
+/*
+ * patterns_osl.h
+ * from https://github.com/sambler/osl-shaders
+ */
+
+/************************************************************************
+ * patterns_osl.h - OSL version of patterns.h (see below)
+ * (inc filterwidth.h) for use with Blender/Cycles
+ * uses BUILTIN functions where possible
+ * removed extern and uniform keywords,
+ * change "comp" to index e.g. foo[0],
+ * added check for def CCL_STDOSL_H
+ * added fadeout function from filterwidth.h
+ * filterwidth is now a BUILTIN function
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * patterns.h - Some handy functions for various patterns. Wherever
+ * possible, antialiased versions will also be given.
+ *
+ * Author: Larry Gritz (lg AT larrygritz DOT com)
+ *
+ * Reference:
+ * _Advanced RenderMan: Creating CGI for Motion Picture_,
+ * by Anthony A. Apodaca and Larry Gritz, Morgan Kaufmann, 1999.
+ *
+ * $Revision: 1.2 $ $Date: 2003/12/24 06:18:06 $
+ *
+ ************************************************************************/
+
+#ifndef CCL_STDOSL_H
+#include "stdosl.h"
+#endif
+
+#ifndef PATTERNS_H
+#define PATTERNS_H 1
+
+/* fadeout taken from filterwidth.h */
+float fadeout(float g, float g_avg, float featuresize, float fwidth) {
+ return mix (g, g_avg, smoothstep(.2,.6,fwidth/featuresize)) ;
+ }
+
+
+/* Handy square routine */
+float sqr (float x)
+{
+ return x*x;
+}
+
+
+
+/* Antialiased abs().
+ * Compute the box filter of abs(t) from x-dx/2 to x+dx/2.
+ * Hinges on the realization that the indefinite integral of abs(x) is
+ * sign(x) * 1/2 x*x;
+ */
+float filteredabs (float x, float dx)
+{
+ float integral (float t) {
+ return sign(t) * 0.5 * t*t;
+ }
+
+ float x0 = x - 0.5*dx;
+ float x1 = x0 + dx;
+ return (integral(x1) - integral(x0)) / dx;
+}
+
+
+
+
+/* Antialiased smoothstep(edge0,edge1,x).
+ * Compute the box filter of smoothstep(edge0,edge1,t) from x-dx/2 to x+dx/2.
+ * Strategy: divide domain into 3 regions: t < edge0, edge0 <= t <= edge1,
+ * and t > edge1. Region 1 has integral 0. Region 2 is computed by
+ * analytically integrating smoothstep, which is -2t^3+3t^2. Region 3
+ * is trivially 1.
+ */
+float filteredsmoothstep (float edge0, float edge1, float x, float dx)
+{
+ float integral (float t) {
+ return -0.5*t*t * (t*t - 2*t);
+ }
+
+ /* Compute x0, x1 bounding region of integration, and normalize so that
+ * edge0==0, edge1==1
+ */
+ float edgediff = edge1 - edge0;
+ float x0 = (x-edge0)/edgediff;
+ float fw = dx / edgediff;
+ x0 -= 0.5*fw;
+ float x1 = x0 + fw;
+
+ /* Region 1 always contributes nothing */
+ float integralv = 0;
+ /* Region 2 - compute integral in region between 0 and 1 */
+ if (x0 < 1 && x1 > 0)
+ integralv += integral(min(x1,1)) - integral(max(x0,0));
+ /* Region 3 - is 1.0 */
+ if (x1 > 1)
+ integralv += x1-max(1,x0);
+ return integralv / fw;
+}
+
+
+
+/* A 1-D pulse pattern: return 1 if edge0 <= x <= edge1, otherwise 0 */
+float pulse (float edge0, float edge1, float x)
+{
+ return step(edge0,x) - step(edge1,x);
+}
+
+
+
+float filteredpulse (float edge0, float edge1, float x, float dx)
+{
+ float x0 = x - dx/2;
+ float x1 = x0 + dx;
+ return max (0, (min(x1,edge1)-max(x0,edge0)) / dx);
+}
+
+
+
+/* A pulse train: a signal that repeats with a given period, and is
+ * 0 when 0 <= mod(x,period) < edge, and 1 when mod(x,period) > edge.
+ */
+float pulsetrain (float edge, float period, float x)
+{
+ return pulse (edge, period, mod(x,period));
+}
+
+
+/* Filtered pulse train: it's not as simple as just returning the mod
+ * of filteredpulse -- you have to take into account that the filter may
+ * cover multiple pulses in the train.
+ * Strategy: consider the function that is the integral of the pulse
+ * train from 0 to x. Just subtract!
+ */
+float filteredpulsetrain (float edge, float period, float x, float dx)
+{
+ /* First, normalize so period == 1 and our domain of interest is > 0 */
+ float w = dx/period;
+ float x0 = x/period - w/2;
+ float x1 = x0+w;
+ float nedge = edge / period; /* normalized edge value */
+
+ /* Definite integral of normalized pulsetrain from 0 to t */
+ float integral (float t) {
+ float nedge;
+ return ((1-nedge)*floor(t) + max(0,t-floor(t)-nedge));
+ }
+
+ /* Now we want to integrate the normalized pulsetrain over [x0,x1] */
+ return (integral(x1) - integral(x0)) / w;
+}
+
+
+
+float smoothpulse (float edge0, float edge1, float edge2, float edge3, float x)
+{
+ return smoothstep(edge0,edge1,x) - smoothstep(edge2,edge3,x);
+}
+
+
+float filteredsmoothpulse (float edge0, float edge1, float edge2, float edge3, float x, float dx)
+{
+ return filteredsmoothstep(edge0,edge1,x,dx) - filteredsmoothstep(edge2,edge3,x,dx);
+}
+
+
+
+/* A pulse train of smoothsteps: a signal that repeats with a given
+ * period, and is 0 when 0 <= mod(x/period,1) < edge, and 1 when
+ * mod(x/period,1) > edge.
+ */
+float smoothpulsetrain (float edge0, float edge1, float edge2, float edge3, float period, float x)
+{
+ return smoothpulse (edge0, edge1, edge2, edge3, mod(x,period));
+}
+
+
+
+/* varyEach takes a computed color, then tweaks each indexed item
+ * separately to add some variation. Hue, saturation, and lightness
+ * are all independently controlled. Hue adds, but saturation and
+ * lightness multiply.
+ */
+color varyEach(color Cin, float index, float varyhue, float varysat, float varylum)
+{
+ /* Convert to "hsl" space, it's more convenient */
+ color Chsl = transformc("hsl", Cin);
+ float h = Chsl[0], s = Chsl[1], l = Chsl[2];
+ /* Modify Chsl by adding Cvary scaled by our separate h,s,l controls */
+ h += varyhue * (cellnoise(index+3)-0.5);
+ s *= 1 - varysat * (cellnoise(index-14)-0.5);
+ l *= 1 - varylum * (cellnoise(index+37)-0.5);
+ Chsl = color (mod(h,1), clamp(s,0,1), clamp(l,0,1));
+ /* Clamp hsl and transform back to rgb space */
+ return transformc("hsl","rgb", Chsl) ;
+}
+
+
+
+/* Given 2-D texture coordinates ss,tt and their filter widths ds, dt,
+ * and the width and height of the grooves between tiles (assuming that
+ * tile spacing is 1.0), figure out which (integer indexed) tile we are
+ * on and what coordinates (on [0,1]) within our individual tile we are
+ * shading.
+ */
+float
+tilepattern (float ss, float tt, float ds, float dt,
+ float groovewidth, float grooveheight,
+ output float swhichtile, output float twhichtile,
+ output float stile, output float ttile)
+{
+ swhichtile = floor (ss);
+ twhichtile = floor (tt);
+ stile = ss - swhichtile;
+ ttile = tt - twhichtile;
+
+ return filteredpulsetrain (groovewidth, 1, ss+groovewidth/2, ds)
+ * filteredpulsetrain (grooveheight, 1, tt+grooveheight/2, dt);
+}
+
+
+
+/* basic brick tiling pattern --
+ * inputs:
+ * x, y positions on a 2-D surface
+ * tilewidth, tileheight dimensions of each tile
+ * rowstagger how much does each row stagger relative to
+ * the previous row
+ * rowstaggervary how much should rowstagger randomly vary
+ * jaggedfreq, jaggedamp adds noise to the edge between the tiles
+ * outputs:
+ * row, column index which tile the sample is in
+ * xtile, ytile position within this tile (0-1)
+ */
+void basicbrick (float x, float y,
+ float tilewidth, float tileheight,
+ float rowstagger, float rowstaggervary,
+ float jaggedfreq, float jaggedamp,
+ output float column, output float row,
+ output float xtile, output float ytile
+ )
+{
+ point PP;
+ float scoord = x, tcoord = y;
+
+ if (jaggedamp != 0.0) {
+ /* Make the shapes of the bricks vary just a bit */
+ PP = point(noise(x*jaggedfreq/tilewidth, y*jaggedfreq/tileheight));
+ scoord += jaggedamp * PP[0];
+ tcoord += jaggedamp * PP[1];
+ }
+
+ xtile = scoord / tilewidth;
+ ytile = tcoord / tileheight;
+ row = floor (ytile); /* which brick row? */
+
+ /* Shift the columns randomly by row */
+ xtile += mod (rowstagger * row, 1);
+ xtile += rowstaggervary * (noise (row+0.5) - 0.5);
+
+ column = floor (xtile);
+ xtile -= column;
+ ytile -= row;
+}
+
+
+
+#endif /* defined(PATTERNS_H) */
+

0 comments on commit 4e5882a

Please sign in to comment.