/* * DWParquetTile.osl by Shane Ambler * from https://github.com/sambler/osl-shaders * * original script from - * http://www.renderman.org/RMR/RMRShaders.html * * DWParquetTile.sl -- yet another surface shader for wood *-was: * parquet_plank.sl -- another surface shader for wood. * * DESCRIPTION: * Makes texture of wooden planks in s-t space. This wood looks rather * like oak plank parquet floor tiles. The actual wood and plank pattern * is based on my "planks" shader. This shader works best if "s" and "t" * units are both the same size in world space. * * PARAMETERS: * Ka, Kd, Ks, specular, roughness - work just like the plastic shader * txtscale - overall scaling factor for the texture * plankwidth - width of each plank (in terms of s/t) * plankspertile - number of planks in each parquet tile * ringscale - scaling for the ring spacing * grainscale - scaling for the fine grain * groovewidth - width of the grooves between the planks (in terms of s/t) * lightwood, darkwood - surface colors for the wood itself * groovecolor - the color of the "grooves" between the planks * plankvary - controls how much wood color varies from plank to plank * grainy - relative graininess (0 = no fine grain) * wavy - relative wavyness of the ring pattern * * ANTIALIASING: this shader does a pretty good job of antialiasing itself, * even with low sampling densities. * * AUTHOR: written by Larry Gritz, the George Washington University * email: gritz AT seas DOT gwu DOT edu * snail: Dept. of EE & CS * 801 22nd St. NW, Rm. T-624-G * Washington, DC 20052 * * HISTORY: * 10 Feb 1995 - written by Larry Gritz, based on my "plank" shader. * 10 Feb 1995 - modified by wave to change the name * 18 Dec 2012 - converted to blender osl shader by Shane Ambler * * last modified 10 Feb 1995 by wave * * * modified again by Dan Weeks on 08 Dec 1996 * - made one plank per tile like the flooring in our lab * - comments appear where changes are made * - many thanks to Larry Gritz and wave for creating the original * * modified by Shane Ambler 18 Dec 2012 * - convert to work as blender osl shader * - capitalise various user visible variable names * - remove Ka - no ambient interaction calculated within shader * - rename Kd to DiffuseAmt * - rename Ks to SpecularAmt * - rename txtscale to TextureScale * - change PlanksPerTile to an int */ /* * changed: * - name from LGParquetPlank to DWParquetTile * - ringscale from 15 to 25 * - grainscale from 60 to 55 * - plankspertile from 4 to 1 * - plankwidth from .05 to .2 */ shader DWParquetTile ( vector Vector = P, float DiffuseAmt = 0.75 , float SpecularAmt = 0.15, float Roughness = 0.025, color SpecularColor = color(1.0), float RingScale = 25.0, float GrainScale = 55.0, float Grainy = 1.0, float Wavy = 0.08, float TextureScale = 5.0, color LightWood = color (0.57, 0.292, 0.125), color DarkWood = color (0.275, 0.15, 0.06), color GrooveColor = color (0.05, 0.04, 0.015), int PlanksPerTile = 1, float PlankWidth = 0.2, float PlankVary = 0.6, float GrooveWidth = 0.1, output closure color BSDF = diffuse(N) ) { #define snoise(x) (2 * noise((x)) - 1) #define boxstep(a,b,x) (clamp(((x)-(a))/((b)-(a)),0,1)) #define MINFILTERWIDTH 1.0e-7 float su = Vector[0]; float tv = Vector[1]; float r, r2; point Nf; float whichrow, whichplank; float swidth, twidth, fwidth, ss, tt, w, h, fade, ttt; color Ct, woodcolor; float groovy; float PGWIDTH, PGHEIGHT, GWF, GHF; float tilewidth, whichtile, tmp, planklength; PGWIDTH = PlankWidth+GrooveWidth; planklength = PGWIDTH * PlanksPerTile - GrooveWidth; PGHEIGHT = planklength+GrooveWidth; GWF = GrooveWidth*0.05/PGWIDTH; GHF = GrooveWidth*0.05/PGHEIGHT; /* Determine how wide in s-t space one pixel projects to */ swidth = (max (abs(Dx(su)*su) + abs(Dy(su)*tv), MINFILTERWIDTH) / PGWIDTH) * TextureScale; twidth = (max (abs(Dx(tv)*su) + abs(Dy(tv)*tv), MINFILTERWIDTH) / PGHEIGHT) * TextureScale; fwidth = max(swidth,twidth); ss = (TextureScale * su) / PGWIDTH; whichrow = floor (ss); tt = (TextureScale * tv) / PGHEIGHT; whichplank = floor(tt); if (mod (whichrow/PlanksPerTile + whichplank, 2) >= 1) { ss = TextureScale * tv / PGWIDTH; whichrow = floor (ss); tt = TextureScale * su / PGHEIGHT; whichplank = floor(tt); tmp = swidth; swidth = twidth; twidth = tmp; } ss -= whichrow; tt -= whichplank; whichplank += 20*(whichrow+10); /* * Figure out where the grooves are. The value groovy is 0 where there * are grooves, 1 where the wood grain is visible. Do some simple * antialiasing. */ if (swidth >= 1) w = 1 - 2*GWF; else { w = clamp (boxstep(GWF-swidth,GWF,ss), max(1-GWF/swidth,0), 1) - clamp (boxstep(1-GWF-swidth,1-GWF,ss), 0, 2*GWF/swidth); } if (twidth >= 1) h = 1 - 2*GHF; else { h = clamp (boxstep(GHF-twidth,GHF,tt), max(1-GHF/twidth,0),1) - clamp (boxstep(1-GHF-twidth,1-GHF,tt), 0, 2*GHF/twidth); } /* This would be the non-antialiased version: * w = step (GWF,ss) - step(1-GWF,ss); * h = step (GHF,tt) - step(1-GHF,tt); */ groovy = w*h; /* * Add the ring patterns */ fade = smoothstep (1/RingScale, 8/RingScale, fwidth); if (fade < 0.999) { ttt = tt/4+whichplank/28.38 + Wavy * noise (8*ss, tt/4); r = RingScale * noise (ss-whichplank, ttt); r -= floor (r); r = 0.3 + 0.7 * smoothstep(0.2, 0.55, r) * (1 - smoothstep(0.75, 0.8, r)); r = (1-fade)*r + 0.65*fade; /* * Multiply the ring pattern by the fine grain */ fade = smoothstep (2/GrainScale, 8/GrainScale, fwidth); if (fade < 0.999) { r2 = 1.3 - noise (ss*GrainScale, (tt*GrainScale/4)); r2 = Grainy * r2*r2 + (1-Grainy); r *= (1-fade)*r2 + (0.75*fade); } else r *= 0.75; } else r = 0.4875; /* Mix the light and dark wood according to the grain pattern */ woodcolor = mix (LightWood, DarkWood, r); /* Add plank-to-plank variation in overall color */ woodcolor *= (1-PlankVary/2 + PlankVary * noise (whichplank+0.5)); Ct = mix (GrooveColor, woodcolor, groovy); Nf = normalize(N); BSDF = Ct * DiffuseAmt * diffuse(Nf); BSDF += SpecularColor * SpecularAmt * microfacet_beckmann(Nf,Roughness); }