cheap realistic skin shading. overview popular skin models new skin model – ideas ideas – brdf...
TRANSCRIPT
Cheap Realistic Skin Shading
Overview• Popular Skin Models• New Skin Model
– Ideas– BRDF– Layers– Back Scattering– Blended Normals– Shadows– Extras
• Results• Conclusion
Popular Skin Models
Popular Skin Models• Red wrapped lighting
– http://http.developer.nvidia.com/GPUGems/gpugems_ch16.html
• Texture-space diffusion– http://http.developer.nvidia.com/GPUGems3/gpugems3_ch14.html
• Texture-space diffusion (12-tap)– http://advances.realtimerendering.com/s2010/Hable-Uncharted2(SIGGRAPH 2010 Advanced RealTime Rendering Co
urse).pptx
• Screen-space diffusion– http://giga.cps.unizar.es/~diegog/ficheros/pdf_papers/TAP_Jimenez_LR.pdf
• Blended Normals– http://advances.realtimerendering.com/s2010/Hable-Uncharted2(SIGGRAPH 2010 Advanced RealTime Rendering Co
urse).pptx
• Offline “Fast-Skin Shaders”– http://www.google.ca/#hl=en&source=hp&biw=1920&bih=965&q=fast+skin+shader&aq=f&aqi=g-m5&aql=&oq=&gs
_rfai=&fp=bc38547320fe36d4
Popular Skin Models (cont.)
• The diffusion approximation techniques are the most popular when it comes to high-fidelity realism.
• Each model is in the extremes.– Either extremely cheap/poor approximation or really
good/expensive.• Wrapped lighting can work in practice but fails in sharp lighting.
• Need a good alternative that’s somewhere in the middle.– Has to be cheap but still look up-to-par.
New Skin Model
New Skin Model
New Skin Model - Ideas• Use concepts from other models.
– Use Kelemen/Szirmay-Kalos BRDF.• Looks great.• Can be relatively cheap with proper optimizations.
– Simulate “Fast-Skin Shaders” Multiple layers.• Each layer has it’s own texture (epidermal, subdermal).• Epidermal layer is blurred lightly.• Subdermal layer is blurred a lot.• Diffuse is not blurred at all.• Sum the layers at the end.
– Soften normal map using blended normals.• Gives soft look without washing out lighting.
New Skin Model - BRDF
New Skin Model – BRDF (Code)Don’t use these textures, compute them yourself for better precision.// Computes beckmann distribution
// To bake to texture: texCoord.x = NdotH, texCoord.y = Expfloat4 GetBeckmannDistribution( float NdotH, float Exp ) { // Some roughness weights float4 m = half4(1, 0.12, 0.023, 0.012) * (Exp * Exp); float alpha = acos( NdotH ); float ta = tan( alpha ); float4 val = 1.0 / (m * pow(NdotH, 4.0)) * exp(-(ta * ta) / m);
// Scale the value to fit within [0-1] return 0.5 * pow( val , 0.1 ); }
// Computes fresnel reflectance (can be computed on the fly no problem)// To bake to texture: HdotV = texCoord.x, texCoord.y = F0float GetFresnelKS( float3 HdotV, float F0 ) {
float base = 1.0 - HdotV; float exponential = pow( base, 5.0 );return exponential + F0 * ( 1.0 - exponential );
}
Code modified from NVIDIA’s implementation.
New Skin Model – BRDF (Code)float KelemenSzirmayTex( float3 N, float3 L, float3 V, float Exp, float F0 ){
// Pretty straightforwardfloat NdotL = saturate(dot(N, L));float h = L + V;float H = normalize(h);float HdotV = dot(H, V);
// Get fresnel from texture; 0.028 is a good value for F0float fFresnel = tex2D(fresnelTex, float2(HdotV, F0));// float fFresnel = GetFresnelKS(HdotV, F0 ); // Math version.
// Get beckmann distributions from texturefloat4 fBeckmann = pow(2.0 * tex2D(beckmannSampler, float2(NdotH, Exp)), 10); float4 fSpec = max( (fBeckmann * fFresnel) / dot( h, h ), 0 );
// Weight results using dot productfloat result = saturate( NdotL ) * dot(fSpec, half4(1.0, 0.625, 0.075, 0.005));
return result;}
New Skin Model – BRDF (Result)
(Image intensified for clarity)
New Skin Model - Layers
New Skin Model – Layers (Textures)
Diffuse Epidermal Subdermal
Back Scattering Specular Normal
New Skin Model – Layers (Image)
New Skin Model – Back Scattering
New Skin Model – Back Scattering (Code)
float3 BackLighting(float3 lightColor, float NdotL, float shadowMap, float transTex){ // Calculate back scattering. float backLight = lerp(NdotL, 1.0, transTex) - lerp(NdotL, 1.0, 0.4);
float3 result = saturate(backLight) * lightColor * shadowMap * backScatterStrength * backScatterColor; return result;}
New Skin Model – Back Scattering (Image)
New Skin Model – Blended Normals• Use blended normals to soften bump-mapping.
– Calculate N·L for vertex normals and bumped normals.– Blend between them with different strengths for different color
channels.• Use “lerp(0.0, max, intensity)” for intensity of each channel
– Prevents perfectly smooth normals (we don’t want those).– Good values for max:
» Red = 0.5 – 0.7» Green/Blue = 0.15 – 0.4
– Intensity is contstant for all» 0-1
– Use new value for N·L for diffuse lighting.
New Skin Model – Blended Normals (Code)float3 BlendNormals(float lightDiffusion, float vertexNdotL, float bumpNdotL, float3
lightPos){
// Tweak max values as you see fit.float redIntensity = lerp(0.0f, 0.6f, skinDiffusionAmount);
float greenBlueIntensity = lerp(0.0f, 0.4f, skinDiffusionAmount);
float red = lerp(vertexNdotL, bumpNdotL, redIntensity); float greenBlue = lerp(vertexNdotL, bumpNdotL, greenBlueIntensity);
greenBlue = min(red, greenBlue); // remove unwanted green/blue
// Put it all together.float3 result = float3(red, greenBlue.xx);return saturate(result);
}
New Skin Model – Blended Normals (Image)
New Skin Model – Shadows
New Skin Model - Shadows (cont.)
New Skin Model - Shadows (cont.)
New Skin Model – Shadows (Code)float3 BlendShadows(float2 shadowPow, float shadowMap){
// Calculate 2 different power factors. float shadowR = pow(shadowMap, shadowPow.x); float shadowGB = pow(shadowMap, shadowPow.y);
// Blend shadows float red = lerp(shadowGB, shadowR, skinDiffusionAmount); float greenBlue = lerp(shadowGB, shadowR, skinDiffusionAmount * 0.5); float3 result = float3( red, greenBlue.xx );
// Result may be a bit too red, desaturate it a bit. result = lerp(result, dot(result, float3(0.33, 0.59, 0.11)), 0.75);
return saturate(result);}
New Skin Model – Shadows (Image)
Pure diffuse layer Pure epidermal/subdermal layers
New Skin Model - Extras
New Skin Model – Notes
• Shadow sharpening doesn’t need to be done for every layer.– Can simplify and apply single blended shadows
beforehand.– Can still provide good bleeding.
• Can do blended normals more than once.– Create variety between bump strengths for each layer.
• Not limited to constant color for backscattering.– Subdermal texture.– Translucency ramp.
Results
Results
Results (cont.)
Standard NdotL + Blinn-phong (physical model) Skin Shading, no SSS Skin Shading, full SSS
Conclusion• Use Kelemen/Szirmay-Kalos BRDF.
– Bake beckmann distribution and fresnel into textures.– Use 4 specular terms instead of 1.
• Approximate subsurface scattering with lightly wrapped texture layers.– Epidermal, subdermal.– Keep wrapping at a minimum to avoid washing out the lighting.
• Use blended normals to soften normal maps.• Sharpen shadows for layers using pow() to create bleeding shadows.
– Faster than blurring.
• Use simple masked N·L calculations for backscattering.– Really cheap and easy to do.
• Can add rim lighting or melanin for extra effect.• Might prove more effective if mixed with more methods (diffusion
maybe?)
Conclusion (cont.)
Thanks for viewing! • References:• Screen-Space Perceptual Rendering of Human Skin, Jorge Jimenez, Veronica Sundstedt,
Diego Gutierrez, 2009– http://giga.cps.unizar.es/~diegog/ficheros/pdf_papers/TAP_Jimenez_LR.pdf
• Efficient Rendering of Human Skin, Eugene d'Eon, David Luebke, and Eric Enderton, Eurographics 2007
– http://http.developer.nvidia.com/GPUGems3/gpugems3_ch14.html
• Real-Time Approximations to Subsurface Scattering, Simon Green, 2004– http://http.developer.nvidia.com/GPUGems/gpugems_ch16.html
• Uncharted 2: Character Lighting and Shading, John Hable, 2010• http://advances.realtimerendering.com/s2010/Hable-Uncharted2(SIGGRAPH%202010%20Advanced
%20RealTime%20Rendering%20Course).pptx
• Crafting Physically Motivated Shading Models for Game Development, Naty Hoffman, 2010– http://renderwonk.com/publications/s2010-shading-course/hoffman/
s2010_physically_based_shading_hoffman_b.pdf
• Real-Time Realistic Skin Translucency, Jorge Jimenez, David Whelan, Veronica Sundstedt, Diego Gutierrez, 2010
• http://giga.cps.unizar.es/~diegog/projects/IEEE/ieee.html
FinHead model available at Infinite-3D