Saturday, November 6, 2010

Step By Step Pixar Style Eyes Shader. Step1: Iris Texturing











First of all, this solution was realised how ST projection.
I mean, position and of Eye Iris is depend from UV mapping only,
not from 3d projection. The image below demonstrate is UV-layout
of polygonal eye.




And second of all, model quality is such as it is - I am not modeller.
I use RSL2.0 style, but You can rewrite to old RSL style - code is simple. I devide this tutor on some few articles -
Iris Texturing, Diffuse shading, Fake caustic, Reflection components.
So is code below:

class cEyeShader(
    uniform float EyeIrisXPosition = 0.5;
    uniform float EyeIrisYPosition = 0.5;
    uniform color EyeIrisInColor = (0.025, 0.05, 0.01);
    uniform color EyeIrisMidColor = (0.7, 0.3, 0.02);
    uniform color EyeIrisOutColor = (0.025, 0.05, 0.01);
    uniform float EyePupilRadius = 0.04;
    uniform float EyeIrisRadius = 0.06;
    uniform float EyeIrisSeed = 1;
    uniform float EyeIrisCircularNoiseLevel = 0.2;
    uniform float EyeIrisRadialNoiseLevel = 0.75;
    uniform float EyeIrisRadialShift = 0.3;
    )
{

float linstep(float min, max, x)
    {
    float f;
    if (x < min) f = 0;
    if (x >= max) f = 1;
    f = (x-min)/(max-min);
    return f;
    }

float IrisNoise()
    {
    float angle;
    uniform float noiseScale1 = 100;
    uniform float noiseScale2 = 500;
    
    float d = distance(point(EyeIrisXPosition, EyeIrisXPosition, 0), point(s, t, 0));
        if (d != 0)     angle = asin((EyeIrisYPosition-t)/d);
        else   angle = 0;
        if (EyeIrisXPosition-s < 0) angle = PI - angle;
    
    float n1 = noise(s*noiseScale1, t*noiseScale1) * clamp(noise(s*noiseScale2, t
                *noiseScale2),.5, 1) * 2;
    float n2 = noise(angle*5+EyeIrisSeed);
        
    n1 = (n1 * EyeIrisCircularNoiseLevel) + (1-EyeIrisCircularNoiseLevel);
    n2 = (n2 * EyeIrisRadialNoiseLevel) + (1-EyeIrisRadialNoiseLevel);
    
    return n1*n2;
    }
    
public void surface(output color Ci, Oi)
    {
    
    // Dummy Difuse Color
    color Diffuse = color(1);
    // Pupil color (You can make your self solution for Pupil Lighting. But I use siple black color.
    color PupilColor = color(0);   
    
    float RadialDistribution = sqrt(pow((s-EyeIrisXPosition), 2) + pow((t-EyeIrisYPosition),2));
        
    float reDistribution = RadialDistribution / (EyeIrisRadius-EyePupilRadius);
    float kKorrection  = EyePupilRadius / (EyeIrisRadius-EyePupilRadius);
    
    float kSpline = float spline( "solvecatrom", reDistribution, kKorrection, 
                    kKorrection, (EyeIrisRadialShift + kKorrection), 
                    (1 + kKorrection), (1 + kKorrection));
    color IrisPainting = color spline( "catrom", kSpline, EyeIrisInColor, 
                    EyeIrisInColor, EyeIrisMidColor, EyeIrisOutColor, EyeIrisOutColor);
    
    IrisPainting = IrisPainting * IrisNoise(); // Add Noise to Iris
    
    color IrisColor_W_Pupil = mix(PupilColor, IrisPainting , 
                    clamp(linstep( EyePupilRadius, (EyePupilRadius +(EyePupilRadius/100)), 
                    RadialDistribution),0,1));
    color IrisColor_W_Diffuse = mix(IrisColor_W_Pupil, Diffuse,  
                    filterstep(EyeIrisRadius, RadialDistribution));
    
    color outcolor = IrisColor_W_Diffuse;
    Oi = color(1); 
    Ci = outcolor;
    }
}
In first we making circular ramp for RadialDistribution:
float RadialDistribution = sqrt(pow((s-EyeIrisXPosition), 2) + pow((t-EyeIrisYPosition),2));

float reDistribution = RadialDistribution / (EyeIrisRadius-EyePupilRadius);
























Next step - bulding Circular ramp and multiply it on special Noise function. I brought in a separate float function IrisNoise(). It is a bit complicate with radial and circular components.
And this release function might potential problems in case radical uv-offseting of position center Iris.

float kSpline = float spline( "solvecatrom", reDistribution, kKorrection, 
                    kKorrection, (EyeIrisRadialShift + kKorrection), 
                    (1 + kKorrection), (1 + kKorrection));
    color IrisPainting = color spline( "catrom", kSpline, EyeIrisInColor, 
                    EyeIrisInColor, EyeIrisMidColor, EyeIrisOutColor, EyeIrisOutColor);
    IrisPainting = IrisPainting * IrisNoise(); // Add Noise to Iris

Now we add pupil component:

color IrisColor_W_Pupil = mix(PupilColor, IrisPainting , 
            clamp(linstep( EyePupilRadius, (EyePupilRadius +(EyePupilRadius/100)), 
            RadialDistribution),0,1));

And in final this article we cropped Iris by outside circle:

color IrisColor_W_Diffuse = mix(IrisColor_W_Pupil, Diffuse,  
        filterstep(EyeIrisRadius, RadialDistribution));

To be continued...
step 2
step 3

3 comments:

  1. Even I took interest into this. ) Waiting for continuation.

    ReplyDelete
  2. thank you for this! It's rare to see RSL posts.

    ReplyDelete
  3. May I ask, how is this different from this?
    http://www.creativecrash.com/renderman/downloads/shaders/c/dl_eyeball-slim

    ReplyDelete