Hair Rendering
Hair Rendering
Shading
Thorsten Scheuermann
3D Application Research Group
ATI Research, Inc.
Overview
• Several layers of
patches to approximate
volumetric qualities of
hair
• Ambient occlusion to
approximate self-
shadowing
– Per vertex
• Base texture
– Stretched noise
• Alpha texture
– should have fully
opaque regions
• Specular shift
texture
More on these later…
• Specular noise
texture
Vertex Shader
• Just passes down tangent, normal, view vector,
light vector, ambient occlusion term
Pixel Shader
• Diffuse Lighting
– Kajiya-Kay diffuse term sin(T, L) looks too bright
without proper self-shadowing
– We use a tweaked N.L term
• Two shifted specular highlights
• Combining terms
// diffuse lighting: the lerp shifts the shadow boundary for a softer look
float3 diffuse = saturate (lerp (0.25, 1.0, dot(normal, lightVec));
diffuse *= diffuseColor;
// specular lighting
float3 specular = specularColor1 * StrandSpecular (t1, viewVec, lightVec,
specExp1);
// add 2nd specular term, modulated with noise texture
float specMask = tex2D (tSpecMask, uv); // approximate sparkles using texture
specular += specularColor2 * specMask * StrandSpecular (t2, vieVec, lightVec,
specExp2);
// final color assembly
float4 o;
o.rgb = (diffuse + specular) * tex2D (tBase, uv) * lightColor;
o.rgb *= ambOcc; // modulate color by ambient occlusion term
o.a = tex2D (tAlpha, uv); // read alpha texture
return o;
}
Pros:
• Low geometric complexity
– Lessens load on vertex engine
– Makes depth sorting faster
• Usable on lower-end hardware with simpler shaders or
fixed-function pipeline
Cons:
• Sorting scheme assumes little animation in hair model
– Things like dangling pony tails need to be handled
separately
– Sort geometry at run-time to overcome this
• Not suitable for all hair styles