/*
fakesubss2.sl Fake Sub-Surface Scattering Class-Based Shader
Written by: Tim Chrismer
Special Thanks to Stephen Winters for his Voronoi Noise methods and Jeff Wyner for
his examples of the implementations
*/
#define vsnoise(x) (2*(vector noise(x))-1)
void
voronoi_f1f2_3d (point P;
float jitter;
output float f1; output point pos1;
output float f2; output point pos2;)
{
point thiscell = point (floor(xcomp(P))+0.5,floor(ycomp(P))+0.5,floor(zcomp(P))+0.5);
f1 = f2 = 1000;
uniform 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 * (vector cellnoise (testcell) -0.5);
vector offset = pos - P;
float dist = offset . offset;
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);
}
vector
vfBm(point p; uniform float octaves, lacunarity, gain)
{
uniform float amp = 1;
varying point pp = p;
varying vector sum = 0;
uniform float i;
for (i=0; i<octaves; i+=1){
sum += amp * vsnoise(pp);
amp *= gain; pp*=lacunarity;
}
return sum;
}
color envmapping (normal norm;
vector in;
string mapname;
string coordname;
float kenv)
{
color envcolor = 0;
if(mapname != ""){
normal n = normalize(norm);
vector i = normalize(in);
normal nf = faceforward(n, i);
vector R = reflect(i, nf);
R = transform(coordname, R);
envcolor = environment(mapname, R) * kenv;
}
return envcolor;
}
color layer (normal norm;
vector in;
float ka, kd, ks,roughness;
color hilitecolor)
{
normal n = normalize(norm);
vector i = normalize(in);
normal nf = faceforward(n, i);
color amb = ka * ambient();
color dif = kd * diffuse(nf);
color spc = ks * specular(nf, -i, roughness) * hilitecolor;
return (amb + dif + spc);
}
class fakesubss3(float Kd = 1, /* basic brightness */
Ks = 0.7, /* hilight brightness */
Ka = .5, /* ambient brightness */
subKa = 1, /* subsurf amb " */
subKd = 0.5, /* subsurf diffuse " */
subKs = 0.7, /* subsurf hilight " */
roughness = 0.5,/* roughness of the surface */
Km = 0.1, /* displacement magnitude */
CellJitter = 0.5, /* jitter for each cell */
CellFreq = 4.0, /* frequency of cells */
RutFreq = 0.15, /* frequency of border edges */
RutJitter = 1.0, /* jitter for the border edges */
RutThickness = 0.1, /* thickness of the edges */
RutSoftness = 0.1, /* softness or harshness of the ruts */
Kenv = 0.4, /* environment contrib */
Ktop = 0.5, /* scales the top color */
Ksub = 0.5; /* scales the sub color */
color hicolor = 0.8, /* top hilight color */
locolor = 0.5, /* sub-surf hilight color */
subCs = (0.5, 0.55, 0.3); /* sub-surf color */
string envname = "",
envspace = "world")
{
varying normal originalN = 0;
varying point originalP, displacedP;
varying normal displacedN;
public void displacement(output point P; output normal N) {
originalP = P;
originalN = N;
normal n = normalize(N);
point pp = originalP;
float Cells, fcolor = 1, bcolor = 0;
point pos1, pos2;
float f1, f2;
//Jitter in each cell//
point PP = (pp + RutFreq * vfBm(2*pp, 4, 2, CellJitter));
//function called//
voronoi_f1f2_3d (PP*CellFreq, RutJitter, f1, pos1, f2, pos2);
//Here I create the cells
Cells = smoothstep (RutThickness-RutSoftness, RutThickness+RutSoftness, f2-f1);
float hump = (smoothstep (bcolor, fcolor, Cells))*-1; // get some displacement value
P = P - n * hump * Km;
N = calculatenormal(P);
displacedP = P;
displacedN = N;
P = originalP;
N = originalN;
}
public void surface(output color Ci, Oi) {
vector i = normalize(I);
normal n = normalize(N);
color envcolor = envmapping(n, i, envname, envspace, Kenv);
color topcolor = layer(n, i, Ka, Kd, Ks, roughness, hicolor) * Ktop;
color sublight = layer(normalize(displacedN), i, subKa, subKd, subKs, roughness, locolor) * Ksub;
color subcolor = sublight * subCs;
Oi = Os;
Ci = Oi * Cs * (envcolor + topcolor + subcolor);
}
}