Artur

Lets talk fur - Kajiya Kay

Rate this Entry
I've spend (or wasted) half a decade on projects involving some sort of furry/feathered creatures. Happy Feet, Where The Wild Things Are, Legend of the Guardians and Happy Feet 2. So, fur shading is going to be my first subject. I will start with a simple Kajiya Kay implementation in 3Delight. Safe to say that majority of hair shaders are using this model. From real-time hair shaders on GPUs to every project I've worked on. It's fast and relatively easy to understand.

Code:
//======================================
/ diffuse component of the shading model
//======================================
color KajiyaKayHairDiffuse( vector T; )
{
        // Accumulate incoming radiance from lights in C
        color C = 0;
        extern point P;
        illuminance( P )
        {
                // Must declare extern L & Cl because we're in a function
                extern vector L;
                extern color Cl;
                float nondiff = 0;
                lightsource( "__nondiffuse", nondiff );
                if( nondiff < 1 )
                {
                        vector LN = normalize( L );
                        C += ( 1 - nondiff ) * Cl * sin( acos( T.LN ) );
                }
        }
        return C;
}

//======================================
// specular component of the shading model
//======================================
color KajiyaKayHairSpecular( vector T; vector V; float sharpness; )
{
        // Accumulate highlights from lights in C
        color C = 0;
        extern point P;
        illuminance( P )
        {
                // Must declare extern L & Cl because we're in a function
                extern vector L;
                extern color Cl;
                float nonspec = 0;
                lightsource( "__nonspecular", nonspec );
                if( nonspec < 1 )
                {
                        vector LN = normalize( L );
                        C += ( 1 - nonspec ) * Cl * pow( cos( abs( acos( T.LN ) - acos( -T.V ) ) ), sharpness );
                        
                        //C += ( 1 - nonspec ) * Cl * pow( sin( acos( T.LN ) ) * sin( acos( T.V ) ), sharpness );
                        //C += ( 1 - nonspec ) * Cl * pow( sin( acos( T.LN ) ) * sin( acos( T.V ) ), sharpness );
                }
        }
        return C;
}
Kajiya Kay model is actually from 1989! There are a lot of improved modifications since and diffuse component is probably the first part you'd like to address. Using purely curve tangent for diffuse shading doesn't look all that natural so without going into much details, check out how Sony ImageWorks made things happen on Stuart Little: http://www.renderman.org/RMR/Publications/infbeyond.pdf

In a nutshell, it mixes the surface normal vector at the base of the hair with the tangent vector at the current point on the hair. Amount of mix is based on the angle between the tangent vector at the current point on the hair, and the surface normal vector at the base of the hair. Now say it very quickly.

Before I'm going to get Marschner model working I will provide a shader with implemented 'Stuart Little' trick and a working RIB. Additionally I'd like to show how to simulate Marschner's refractive properties with Kajiya Kay model. Easy!

Submit "Lets talk fur - Kajiya Kay" to Digg Submit "Lets talk fur - Kajiya Kay" to del.icio.us Submit "Lets talk fur - Kajiya Kay" to StumbleUpon Submit "Lets talk fur - Kajiya Kay" to Google

Updated 11-23-2010 at 02:17 AM by Artur

Tags: None Add / Edit Tags
Categories
Technical

Comments

  1. Anton's Avatar
    extern vector L;
    extern color Cl;
    float nondiff = 0;

    what? float nondiff is clearly wrong.