Shaders



two_lane_blacktop - A procedural shader for a street surface

 
/*-______________________________________________________________________
** 
** two_lane_blacktop shader... dsward@webnation.com
** 
** based on Steve May's Renderman notes at http://www.cgrg.ohio-state.edu/~smay/RManNotes
** and _Texturing and Modeling, A Procedural Approach_ by Darwyn Peachey, et al, ISBN 0-12-228760-6
** ______________________________________________________________________
*/
#define rotate2d(x,y,rad,ox,oy,rx,ry) \
  rx = ((x) - (ox)) * cos(rad) - ((y) - (oy)) * sin(rad) + (ox); \
  ry = ((x) - (ox)) * sin(rad) + ((y) - (oy)) * cos(rad) + (oy)
#define whichtile(x,freq) (floor((x) * (freq)))
#define pulse(a,b,fuzz,x) (smoothstep((a)-(fuzz),(a),(x)) - \
			   smoothstep((b)-(fuzz),(b),(x)))
#define blend(a,b,x) ((a) * (1 - (x)) + (b) * (x))
#define repeat(x,freq)    (mod((x) * (freq), 1.0))
#define MINFILTERWIDTH  1e-7
#define filterwidth_point(p) (max(sqrt(area(p)), MINFILTERWIDTH))
 
 
surface 
two_lane_blacktop 
(
		float asphalt_turbulence  = 16.0;
		
		float stripe_rotation     = 0.0;
		color center_stripe_color = color(1.0, 1.0, 0.0);
		color edge_stripe_color   = color(1.0, 1.0, 1.0);
		
		float stripe_width        = 41;
		float center_stripe_count = 4; 
		float center_stripe_length = 0.5;
 
		float fuzz_s              = 0.05;
		float fuzz_t              = 0.005;
)
{
	color surface_color;
	color surface_opac = color(1);
	point PP;
	float ss, tt;
	float theCol, centerpos;
	point Nf, V;
	float pixelsize, twice, scale, weight, turbulence;
	float mixval;
 
    float shading_method      = 2;
    float Ka                  = 0.5;
    float Kd                  = 1;
    float Ks                  = 0.5;
    float roughness           = 1;
    color specular_color      = 1;
 
	/* generate turbulence for asphalt surface - based on Pixar marble shader */
	PP = transform("shader", P) * asphalt_turbulence;
	pixelsize = sqrt(area(PP)); 
	twice = 2 * pixelsize;
 
	turbulence = 0;
	for (scale = 1; scale > twice; scale /= 2) 
	{
		turbulence += scale * abs(noise(PP / scale) - 0.5);
	}
	
	/* gradual fade out of highest freq component near visibility limit */
	if (scale > pixelsize) 
	{
		weight = (scale / pixelsize) - 1;
		weight = clamp(weight, 0, 1);
		turbulence += weight * scale * abs(noise(PP / scale) - 0.5);
	}
	
	/* turbulence range is 0:2, but mostly between 0.75 and 1. */
	surface_color = turbulence;
	
	/* setup coordinate system for stripes */
	rotate2d(s, t, radians(stripe_rotation), 0.5, 0.5, ss, tt);
	
	/* subdivide the road surface into columns for the stripes */
	theCol = whichtile(ss, stripe_width);
	
	if (theCol == 1) || (theCol == stripe_width - 2)
	{
		/* we are in a solid edge stripe area */
		mixval = pulse(fuzz_s, 1, fuzz_s, repeat(ss, stripe_width));
		if (filterwidth_point(PP) > 1) mixval /= filterwidth_point(PP);
		surface_color = blend(surface_color, edge_stripe_color, mixval);
		Ka = blend(0.5, 1.0, mixval);
		Ks = blend(0.5, 1.0, mixval);
	}
 
	if (theCol == floor((stripe_width - 1) / 2))
	{
		/* we are in the center stripe area */
		mixval = pulse(fuzz_s, 1, fuzz_s, repeat(ss, stripe_width)) * 
				pulse(fuzz_t, center_stripe_length, fuzz_t, repeat(tt, center_stripe_count));
		if (filterwidth_point(PP) > 1) mixval /= filterwidth_point(PP);
		surface_color = blend(surface_color, center_stripe_color, mixval);
		Ka = blend(0.5, 1.0, mixval);
		Ks = blend(0.5, 1.0, mixval);
	}
 
	Nf = faceforward(normalize(N), I);
	V = -normalize(I);
	surface_color = surface_opac * (surface_color * (Ka * ambient() + Kd * diffuse(Nf)) + 
			specular_color * Ks * specular(Nf, V, roughness));
	
	Ci = surface_color;
	Oi = surface_opac;
}

HOME

NEW

LINKS

GALLERY

ARTICLES

PLUG-INS

RENDERMAN

Switch to Frame View




Copyright © 1997 by WebNation
All trademarks are the property of their respective holders