Slide 1 CSCD 471 4/5/10
Surface Shader Writing CSCD 471 Slide 1 4/5/10 Plotting Functions - - PowerPoint PPT Presentation
Surface Shader Writing CSCD 471 Slide 1 4/5/10 Plotting Functions - - PowerPoint PPT Presentation
Surface Shader Writing CSCD 471 Slide 1 4/5/10 Plotting Functions in Shaders This is a trick but can be useful and very helpful in understanding how shaders work. Remember that each call to the shader happens at one specific X and Y value.
Slide 2 CSCD 471 4/5/10
Plotting Functions in Shaders
This is a trick but can be useful and very helpful in understanding how shaders work.
Remember that each call to the shader happens at one specific X and Y value. The following shader will plot the Y values of the smoothstep function at each X position:
Slide 3 CSCD 471 4/5/10
testplot.sl
surface testplot(float freq=1.0) { float delta=0.03; //consider just the x component of P point PP = transform("shader", P); float stepval1 = smoothstep(-0.75, -0.5, xcomp(PP)); float l1 = stepval1-2*delta*(stepval1); float u1 = stepval1+2*delta*(1-stepval1); float ss1 = smoothstep(l1-delta, l1, t); float ss2 = smoothstep(u1-delta, u1, t); float f1 = ss1-ss2; f1 = biasFunc(f1, 0.7); color blue = color(0,0,1); color black = color (0,0,0); color C1 = mix(black, blue, f1); Ci = C1; }
Slide 4 CSCD 471 4/5/10
Evaluate the Function to be Graphed
point PP = transform("shader", P); float stepval1 = smoothstep(-0.75, -0.5, xcomp(PP));
The transform is unnecessary in most cases since
- bject coordinates are shader coordinates
Smoothstep:
float step ( float min, value ) float smoothstep ( float min, max, value ) step returns 0 if value is less than min; otherwise it returns smoothstep returns 0 if value is less than min, 1 if value is greater than or equal to max, and performs a smooth Hermite interpolation between 0 and 1 in the interval min to max.
This call evaluates the smoothstep function for graphing – stepval1 is the Y value of this smoothstep function for the X component of PP.
Slide 5 CSCD 471 4/5/10
Bracketing Y values
float l1 = stepval1-2*delta*(stepval1); float u1 = stepval1+2*delta*(1-stepval1);
These calls set u1 and l1 to be values slightly above and below the Y value (stepval1) u1 and l1 essentially provide a small range of values that bracket stepval1.
Slide 6 CSCD 471 4/5/10
Decide if t is in the correct range
float ss1 = smoothstep(l1-delta, l1, t); float ss2 = smoothstep(u1-delta, u1, t); float f1 = ss1-ss2; f1 = biasFunc(f1, 0.7);
These calls use the surface parameter t (used in slicing) which represents the Y value in the final
- image. t varies from -1 to 1.
They produce one smoothstep that is 0 when t is less than (l1-delta) or (u1-delta), is 1 when t is greater than l1 or u1 and a smooth curve between 0 and 1 for t values between the limits. Subtracting produces a “pulse” function that determines the color to be used to draw this point.
Slide 7 CSCD 471 4/5/10
Choosing Color - mix
float ss1 = smoothstep(l1-delta, l1, t); float ss2 = smoothstep(u1-delta, u1, t); float f1 = ss1-ss2; f1 = biasFunc(f1, 0.7); color C1 = mix(black, blue, f1); Ci = C1;
biasFunc changes f1 by pow(f1, -(log (0.7)/log(2))) f1 is used as a mixing factor in mix()
color mix( color color0, color color1, float value) { return (1-value) * color0 + (value) * color2; }
So if value is 0 return color0 and if value is 1 return color2 – otherwise colors are blended.
float biasFunc(float t; float a;) { return pow(t, -(log (a)/log(2))); }
Slide 8 CSCD 471 4/5/10
Possible Color Values
t ss1 ss2 f1 color mix(black, blue, f1) t < (l1-△) 1-f1*black+ f1*blue = black (l1-△)≤t≤l1 [0,1] [0,1] 1-f1*black+ f1*blue = black/blue l1≤t≤(u1-△) 1 1 1-f1*black+ f1*blue = blue (u1-△)≤t≤u1 1 [0,1] [0,1] 1-f1*black+ f1*blue = black/blue t > u1 1 1 1-f1*black+ f1*blue = black
l1-△ l1 u1-△ u1
Slide 9 CSCD 471 4/5/10
testplot.rib
Display "testplot.tiff" "tiff" "rgba" WorldBegin Surface "testplot" "float freq" [5.0] Polygon "P" [-1 -0.9 30 1 -0.9 30 1 1.0 30 -1 1.0 30] WorldEnd
Slide 10 CSCD 471 4/5/10
testplot Output
testplot output
Slide 11 CSCD 471 4/5/10
Other Function Graphs
smoothstep(-0.75, -0.5, xcomp(PP)) smoothstep(0.25, 0.5, xcomp(PP)) pulse (-0.5, 0.5, 0.25, xcomp(PP))
smoothstep((-0.5-0.25), -0.5, xcomp(PP))- smoothstep((0.5-0.25), 0.5, xcomp(PP))
Slide 12 CSCD 471 4/5/10
Other Function Graphs
float tt = (t/2.0)+0.5; float ss = (t/2.0)+0.5; plot2=ss; plot1=biasFunc(ss, 0.7);
Slide 13 CSCD 471 4/5/10
Plotting Noise
#define snoise(p) (2 * (float noise(p)) - 1) #define pulse(a,b,fuzz,x) (smoothstep((a)-(fuzz), (a), (x)) - \ smoothstep((b) - (fuzz), (b), (x))) float biasFunc(float t; float a;) { return pow(t, -(log (a)/log(2))); } surface snoiseplot(float freq=5.0) { float delta=0.03; point PP = transform("shader", P); float noiseval = snoise(freq * xcomp(PP)); float usnoiseval = noiseval/2.0+0.5; //unsigning noiseval color noisecol = color(usnoiseval, usnoiseval, usnoiseval); float l = noiseval-2*delta*(noiseval); float u = noiseval+2*delta*(1-noiseval); float f = pulse(l, u, delta, t); color wh = color(1,1,1); f = biasFunc(f, 0.25); Ci = mix(noisecol, wh, f); }
Slide 14 CSCD 471 4/5/10
Plotting Noise- RIB File
Display "snoiseplot.ortho.tiff" "tiff" "rgba" // default orthographic projection WorldBegin Surface "snoiseplot" "float freq" [5.0] Polygon "P" [-1 -0.9 30 1 -0.9 30 1 0.9 30 -1 0.9 30] WorldEnd
Slide 15 CSCD 471 4/5/10
Varying Frequency Noise
freq = 5.0
Slide 16 CSCD 471 4/5/10
Varying Frequency Noise
freq = 10.0
Slide 17 CSCD 471 4/5/10
Varying Frequency Noise
freq = 15.0
Slide 18 CSCD 471 4/5/10
Turbulence
Turbulence (or Fractional Brownian Motion) is composited or layered noise at different frequences and amplitudes.
A common way to create turbulence is to start producing noise with low frequencies and high amplitudes and at each level: increase frequency of noise decrease amplitude of noise At each level layer or composite new values (at increased frequency and decreased amplitude) with values from previous levels into the final turbulence value.
Slide 19 CSCD 471 4/5/10
Fractional Brownian Motion - non-filtered
float nonfilt_fBM (point p; uniform float octaves, lacunarity, gain, ampl0, freq0) { varying point pp = p; varying float sum = 0; uniform float i; for (i = 0; i < octaves; i += 1) { float f = pow(lacunarity, i); float a = pow(gain, -i); sum += a*ampl0 *snoise (freq0*f*pp); } return sum; } surface turbtest( string sspace="shader"; float freq0=0.5, ampl0=1, octaves = 4, filterwidth =0.3, lacunarity=2, gain=2, contrast=0.5) { float t =0, i; point PP= transform(sspace, P); t = nonfilt_fBM(PP, octaves, lacunarity, gain, ampl0, freq0); t = pow(t, contrast); Oi= Os; Ci = Oi*Cs*color(t,t,t); }
Slide 20 CSCD 471 4/5/10
Turbulence Definitions
lacunarity - the base by which frequency changes
from layer to layer. Each layer the power of lacunarity increases by 1. gain (or persistence) - the base by which amplitude decreases from layer to layer. Each layer the power
- f gain decreases by 1 starting at 0.
- ctaves – the number of layers to be summed.
for (i = 0; i < octaves; i += 1) { float f = pow(lacunarity, i); float a = pow(gain, -i); sum += a*ampl0 *snoise (freq0*f*pp); }
Slide 21 CSCD 471 4/5/10
Fractional Brownian Motion vs. Perlin Turbulence
The only change from Fractional Brownian Motion is the use of abs on the signed noise.
sum += a*ampl0 *snoise (freq0*f*pp); <-- fBM sum += a*ampl0 *abs(snoise (freq0*f*pp)); <-- Turbulence (Perlin)
both images – gain=2 lacunarity=2 octaves=4 freq0=0.2 contrast=1.0 Fractional Brownian Motion Turbulence (Perlin)
Slide 22 CSCD 471 4/5/10
Filtered Turbulence
Since we are sampling a function at a point the possibility exists for aliasing if sampling rate is below the Nyquist Limit This is made even more likely since noise frequency can get very high as we composite additional layers The frequency value f increases exponentially (f = pow(lacunarity, i); ) as we iterate between levels. Filtering allows us to retrieve a "sampled" value that is an areal average of values thus smoothing
- ut any aliasing while allowing contributions by
the lower frequency levels to the composite color.
Slide 23 CSCD 471 4/5/10
Filtered Turbulence
#include "noises.h" float filt_turbulence (point p; uniform float octaves, lacunarity, gain, ampl0, freq0) { extern float du, dv; /* Needed for filterwidth macro */ varying point pp = p; varying float sum = 0, fw =filterwidthp(p); uniform float i; for (i = 0; i < octaves; i += 1) { float f = pow(lacunarity, i); float a = pow(gain, -i); float n = filteredsnoise (freq0*f*pp, fw); sum += a*ampl0 * filteredabs (n, fw); fw *= lacunarity; } return sum; } From Advanced RenderMan.
Slide 24 CSCD 471 4/5/10
Non-filtered vs. filtered Turbulence
both images – gain=2 lacunarity=2 octaves=4 freq0=0.2 contrast=1.0 Filtered Turbulence Non-Filtered Turbulence
Slide 25 CSCD 471 4/5/10
Effects of Filtering at Different Frequencies
freq = 0.1 freq = 0.2 freq = 0.5 freq = 1.0
Slide 26 CSCD 471 4/5/10
Effects of Differing Number of Octaves
Octaves = 4 Octaves = 3 Octaves = 2 Octaves = 1
Slide 27 CSCD 471 4/5/10
Texture Mapping - txmake
RenderMan textures are created with the txmake command. Builds mip-maps and encodes how texture coordinate values < 0.0 or > 1.0 will be mapped. Texture mapping modes – specified with txmake -mode MODE periodic – simply repeat (tile) textures black – any (s,t) values are replaced with black clamp – last color seen is continuously used. Textures are made from tiff files with or without transparency. Example: txmake -mode black teapot.tiff teapot.tx
Slide 28 CSCD 471 4/5/10
Texture Mapping – texel lookup
Done with the texture function (overloaded).
texture(“mytex.tx”); Looks up the texel at the current (s, t) value in the texture mytex.tx . Remember that texture coordinates (s,t) must be set (usually in RIB file) for each vertex or they default to (x, y). texture(“mytex.tx”, s, t); Looks up the texel at the specific (s,t) values regardless of the global (s,t) at this point.
Slide 29 CSCD 471 4/5/10
Texture Mapping in Surface Shaders
surface simptex(string txnm="";) { Oi = Os; if(txnm!="") Ci =Oi * color texture(txnm, s, t); else Ci = Oi*Cs; } RIB File: Display "simptex.ortho.tiff" "tiff" "rgba" WorldBegin Surface "simptex" "string txnm" ["turbtest.tx"] Polygon "P" [1 0.9 30 -1 0.9 30 -1 -0.9 30 1 -0.9 30 ] "st" [0 0 1 0 1 1 0 1] WorldEnd
Slide 30 CSCD 471 4/5/10
Texture Mapped Output
From the above shader and RIB:
Slide 31 CSCD 471 4/5/10
Image Processing with Textures
Since the current (s,t) values do not have to be used – other values can be looked up or calculated. Example: creating concentric ripples over the texture by modifying the given (s,t) values for the point being shaded. Steps in creating ripples:
move the origin from the upper left of the image to the center.
ss = s-0.5; tt = t-0.5;
Slide 32 CSCD 471 4/5/10
Ripple Shader
Steps in creating ripples(con't):
move the origin from the upper left of the image to the center.
ss = s-0.5; tt = t-0.5;
convert (ss,tt) from Cartesian coordinates to polar coordinate equivalents.
float r = sqrt(ss*ss+tt*tt); float theta = atan(tt,ss);
displace r radially by an amount based on the sin function to create sinsoidal ripples.
float del_r = ampl*sin(r*freq); r += del_r;
Slide 33 CSCD 471 4/5/10
Ripple Shader
Steps in creating ripples(con't):
using the adjusted value of r convert back to new Cartesian coordinate values of (s,t) and return origin to upper left.
sss=r*cos(theta); ttt=r*sin(theta); sss = sss +0.5; ttt = ttt +0.5;
use sss and ttt to perform texel lookup and scale by Oi.
Ci = Oi*color texture(txnm, sss, ttt);
Slide 34 CSCD 471 4/5/10
IP_ripples.sl
surface IP_ripples( string txnm=""; float ampl=1.0; float freq=1.0; ) { Oi = Os; if(txnm!=""){ float ss, tt, sss, ttt; ss = s-0.5; tt = t-0.5; float r = sqrt(ss*ss+tt*tt); float theta = atan(tt,ss); float del_r = ampl*sin(r*freq); r += del_r; sss=r*cos(theta); ttt=r*sin(theta); sss = sss +0.5; ttt = ttt +0.5; Ci = Oi*color texture(txnm, sss, ttt); } else Ci = Oi*Cs; }
Slide 35 CSCD 471 4/5/10
IP_ripples.rib
Display "IP_ripples.tiff" "tiff" "rgba" WorldBegin Surface "IP_ripples" "string txnm" ["teapot.tx"] "float ampl" [0.01] "float freq" [200.0] Polygon "P" [ 1 0.9 30 -1 0.9 30 -1 -0.9 30 1 -0.9 30 ] "st" [0 0 1 0 1 1 0 1] WorldEnd
Slide 36 CSCD 471 4/5/10
Ripples Results
ampl = 0.01 freq = 200.0
Slide 37 CSCD 471 4/5/10
Transparency Mapping
Uses the alpha channel from the texture map to produce a decal texture.
To retrieve the alpha value use the float
- verload of texture and the subscript of the
specific pixel needed: float a = float texture(txnm[3], s, t); txnm[3] specifies the fourth value in the pixel which is the alpha value and assigns it to a single float variable. Oi = a; set Oi to the alpha value Ci = Oi * color texture (txnm, s, t);
- utput color is multiplied by Oi so if Oi is
zero, the textured pixel would be black.
Slide 38 CSCD 471 4/5/10
Transparency Mapping
Ci = Oi * color texture (txnm, s, t);
- utput color is multiplied by Oi so: