Procedural Eye Ball ShaderThis is procedural shader makes simple nurbs sphere into an eye ball. |

|
/* This shader is modified from Larry Gritz's eyeball.sl from http://www.renderman.org/RMR/Shaders/LGShaders/index.html and Matt Breit's irisdistort3.sl shader from http://www.sfdm.scad.edu/faculty/mkesson/vsfx419/wip/best/fall04/matthew_breit/eyeball.html modified by Yi-Ming Chu in Oct.2006 */ void worley(float ss, tt; float jitters, jittert; output float f1; output float spos1, tpos1; ) { float sthiscell = floor(ss)-0.5, tthiscell = floor(tt)-0.5; f1 = 1000; uniform 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 + jitters * (float cellnoise(stestcell, ttestcell)); float tpos = ttestcell + jittert * (float cellnoise(stestcell+20, ttestcell-80)-2.5); float soffset = spos - ss; float toffset = tpos - tt; //float dist = soffset*soffset + toffset*toffset; float dist = toffset*toffset; if (dist < f1) { f1 = dist; spos1 = spos; tpos1 = tpos; } } } f1 = sqrt(f1); } void dimple(float dent, irissize, ss, tt; normal n; output varying float sx, tx;) { normal left = (-1,0,0), up = (0,-1,0); float sdiff, tdiff, so, to, amt, len, nu, nl; len = abs(tt); nu = n.up; nl = n.left; sx = ss; tx = tt; amt = (irissize-len) / irissize; amt = spline(amt, -0.5, 0 , 1 , 1); so = dent * ( amt ) * nl; to = dent * ( amt ) * nu; if ( len < irissize ) { sx += so; tx += to; } } void irisPatternOne( float irisAmt, normangle, pupil, radialperiod, circumperiod, radialjitter, circumjitter; output varying float irisColor;) { float worleydist = 0, worleys = 0, worleyt = 0; /* Worley: ss, tt, jitters, jittert, dist, spos, tpos */ worley(irisAmt * radialperiod, normangle * circumperiod, radialjitter, circumjitter, worleydist, worleys, worleyt); float irisMidAmt = abs(irisAmt - 0.5) * 2; float worleydistSpline = spline(worleydist, -1, 0, 1, 0); float worleydistKapow = pow(worleydist, 3); irisColor = spline(irisAmt, pow(worleydist, 3), pow(worleydist, 2), worleydist, pow(worleydist, 0.667), pow(worleydist, 0.4)); } surface LGEyeBall_modify(float Ka = .75, Kd = 0.75, Ks = 0.9, roughness = 0.1; color specularcolor = 1, irisColor = (0.152, 0.443, 0.074), corneaColor = (1.0, 0.831, 0.243), irisinnercolor = (0.086, 0.054, 0.0), eyeballcolor = (1.0, 0.831, 0.243), bloodcolor = (0.137, 0.345, 0.070), pupilcolor = 0; float pupilsize = 0.05, pupilmargin = 0.02, irissize = 0.12, irismargin = 0.025, dent = 0.5, radialperiod = 2, circumperiod = 20, radialjitter = 0.8, circumjitter = 0.3, blursamples = 32, blurRadius = 1.5, bloodshot = 1.0, veinfreq = 8, veinlevel = 8, index = 0; string envMap = ""; float envblend = 0.5;) { #define snoise(P) (2*noise(P)-1) #define MINFILTERWIDTH 1.0e-7 color Ct; point PP, PO; float i, turb, newturb, freq, f2; float displayed, newdisp; color Cball, Ciris; float irisstat, pupilstat; float bloody, tt; float ks, rough; float twidth, cutoff; normal Nn = normalize(N); normal Nf = faceforward (normalize(Nn), I);; vector V = -normalize(I); float irisAmt = 1, irisMidAmt, normangle, angle, gAngle = 0, gNormAngle = 0, gIrisAmt = 0, anglestep = 140, gRadius = 0, shade = 0, irisVal = 0, irisVal2 = 0, irisVal3 = 0, irisBlurVal = 0, irisBlurTotal = 0, irisNeg = 0, irisMasked = 0, irisHeight = 0; /* Calculate an appropriate filter width for antialiasing */ twidth = max (abs(Du(t)*du) + abs(Dv(t)*dv), MINFILTERWIDTH); PO = transform ("object", P) + index; tt = 1-t; irisstat = smoothstep (irissize, irissize+twidth, tt); pupilstat = smoothstep (pupilsize, pupilsize+twidth, tt); bloody = bloodshot * (smoothstep (-irissize, 2.5*irissize, tt)); if (irisstat * bloody > 0.001) { turb = bloody; freq = veinfreq; displayed = 0; for (i = 1; (i <= veinlevel) && (turb > 0.1); i += 1) { newturb = 1 - abs (snoise(PO*freq + point(0, 0, 20*freq))); newdisp = pow (smoothstep (.85, 1, newturb), 10); displayed += (1-displayed) * newdisp * smoothstep (.1, .85, turb * turb); turb *= newturb; freq *= 2; } Cball = mix (eyeballcolor, bloodcolor, smoothstep(0,.75,displayed)); } else { Cball = eyeballcolor; } Ciris = mix(irisColor, corneaColor, smoothstep(irissize*.8, irissize, tt)); /* If we're somewhere in the iris, calculate the iris pattern */ if ( irisstat == 0 && pupilstat != 0) { float sx, tx, lenx, leng; float sa = mod(s * 5, 1); dimple(dent, irissize, sa, tt, Nn, sx, tx); lenx = abs(tt); angle = atan(tt, 0.5 - sx); normangle = 0.5 + angle * (1/(2 * PI)); irisAmt = ( tt - pupilsize ) / ( irissize - pupilsize -irismargin); irisMidAmt = 2 * (abs(irisAmt - 0.5)); irisPatternOne( irisAmt, normangle, pupilsize, radialperiod, circumperiod, radialjitter, circumjitter, irisVal); irisVal = spline(irisAmt, pow(irisVal, 3), pow(irisVal, 2), irisVal, pow(irisVal, 0.667), pow(irisVal, 0.4)); irisVal2 = spline(irisAmt, 0, irisAmt, pow(irisVal, 3), irisVal, irisAmt, 1); irisPatternOne( irisAmt, normangle, pupilsize, radialperiod, circumperiod*2.5, radialjitter, circumjitter*0.5, irisVal3); for(i = 0; i < blursamples; i+= 1) { gAngle = anglestep * i; gRadius = blurRadius * pow( ( i / blursamples ), 0.75 ) * 0.01; float tg = tx + sin(gAngle)*gRadius; gIrisAmt = ( 1 - tg - pupilsize ) / ( irissize - pupilsize ); gAngle = atan( 1 - tg, sx ); gNormAngle = 0.5 + gAngle * ( 1 / ( 2 * PI ) ); irisPatternOne( gIrisAmt, gNormAngle, pupilsize, radialperiod, circumperiod, radialjitter, circumjitter, irisBlurVal); irisBlurTotal += irisBlurVal; } irisBlurVal = irisBlurTotal / blursamples; irisNeg = 0.5 * ( ( 1 - irisBlurVal ) + irisVal ); irisMasked = smoothstep(0.565, 0.575, (irisNeg + irisAmt * 0.15 + clamp(irisAmt - 0.7, 0, 0.2) ) ); irisHeight = (irisMasked*.1); if (irisMasked == 0) { shade = smoothstep (0.4, 0.565, irisNeg); Ciris *= (Ciris + irisVal3) * 0.5; } else { shade = 0; Ciris = (1-irisNeg)*irisColor; } shade *= 1-irisMidAmt; if (tt - pupilsize <= pupilmargin) { /* Caculate the pattern in the inner edge of the iris */ Ciris = spline( abs( tt - pupilsize ) / pupilmargin, pupilcolor,pupilcolor, irisinnercolor, Ciris,irisinnercolor); irisHeight = spline( abs ( tt - pupilsize ) / pupilmargin, 0, 0, irisHeight, irisHeight); } else if (tt-irissize <= irismargin) { /* Caculate the pattern in the outer edge of the iris */ Ciris = spline( ( abs( tt - irissize )/ irismargin ), Cball, corneaColor, corneaColor*Ciris/3,Ciris, Ciris, Ciris); irisHeight = spline( ( abs( tt - irissize ) / irismargin ), 0, 0, irisHeight, irisHeight); } else { Ciris *= irisColor; } } /* OK, now calculate a surface texture color (Ct) */ Ct = mix (Ciris, Cball, irisstat); Ct = mix (pupilcolor, Ct, pupilstat); /* Make the eye a little glossier on the iris and pupil */ ks = Ks * (1+2*(1-irisstat)); rough = roughness * (1 - .75*(1-irisstat)); if(envMap != "") { vector Rray = vector transform("world", point "world" (0,0,0) + reflect(-V,Nf)); Ct = mix(Ct, color environment(envMap, Rray), envblend); } color spec1 = ks * specular(Nf, V, rough); point pDu = P - Nn * irisHeight * 0.05; normal pNn = calculatenormal(pDu); normal pNf = faceforward (normalize(pNn), I); color diffColor = Kd * diffuse(pNf)*(1-shade); color ambiColor = Ka * ambient(); color spec = specular(pNf, V, rough); //float spec2 = comp(spec, 0); //spec2 += smoothstep(0.1, 0.4, spec2); color specColor = max(spec1,spec)*specularcolor; Oi = Os; Ci = Oi * Ct*(ambiColor + diffColor) + specColor; } |
![]() |
![]() |