Skin shader
Motivation, goal
Skin Shader imitating human skin with the aid of layers with diverse lighting diffusion. It's type of method like "fake subsurface scattering". Result should be similar like "SSS Fast Skin" material in Mental Ray.
Skin effect applies only to surface defined by masc (A-channel of SDM texture), on rest of surface is acts nearly as Super Shader.
Material is composed from 3 layers: unscattered, epidermal, subdermal. All 3 layers got mutual normal texture but differs by color.
unscattered - layer color is given by product of color from EP texture and color "unscattered color'
epidermal - layer color is given by EP texture
subdermal - layer color is given by SDM texture
Skin effects within preexposure by main light - individual layers got weight set to 1 in order that they were seen nicely (shown with aid of tuning parameters of CgFX version of Skin Shader for Maya)
Material parameters
unscatteredColor - modulation color for layer "unscattered"; default value [0.8, 0.9, 1.0]
unscatteredWeight, epidermalWeight, subdermalWeight - scales of individual layers; sum total should be approximately 1; it is possible set in interval <0.0, 1.0>; default values for standalone layers : 0.1, 0.4 and 0.5
epidermalMul, epidermalAdd - parameters defining light scattering inside epidermal layer; values in intervals <0.0, 2.0> and <-1.0, 1.0>; default values 0.8 and 0.2
subdermalMul, subdermalAdd - same meaning like with epidermal layer; default values 0.65 and 0.35
darkRimFactorEp, darkRimFactorSu - light decrease factor in accordance to angle between sight direction and normal line (something like "inverse fresnel"); values are in interval <0.0, 1.0>; default values: 0.3 and 0.7
Mask display generate by "dark rim" factor (gradually from from left: dark rim factor = 0.0, 0.5 and 1.0)
hemisphericSpecLevel - reflection intensity from hemispheric light; <0.0, 1.0>; default value 0.5
Definition of texture stages in material
0. Epidermal/Color map
1. Normal map (NO, NOHQ)
Normal map of type _NO or _NOHQ.
texture="#(argb,8,8,3)color(0.5,0.5,1,1)";
2. Macro map (MC)
Used same as with SuperShader.
texture="#(argb,8,8,3)color(0,0,0,0)";
3. Subdermal map and mask (SDM)
RGB channels contains color for subdermal layer. Within alpha change is mask which determine skin effect usage.
texture="#(argb,8,8,3)color(0,0,0,0)";
4. AmbientShadow map (AS)
Used same as with SuperShader.
texture="#(argb,8,8,3)color(0,1,1,1)";
5. Specular map (SMDI)
Specular map of type _SMDI. On the contrary map of type _SM isn't supported.
6. Fresnel function
Fresnel function is entered as procedural texture in following form: texture="#(ai,64,1,1)fresnel(N,K)";. For detailed see Super shader.
7. Environmental map
For the moment it is not used! Environmental reflection is replaced by hemispherical light reflection.
Temporary material solution
Because it is not possible easily prepare GUI for specific Skin Shader parameters (unscatteredWeight, epidermalWeight, epidermalMul, darkRimFactorEp...), let's use temporary solution.
unscattered layer color - constantly set to RGB = (0.6, 0.8, 1.0)
unscattered weight, epidermal weight, subdermal weight, hemis. specular level - parameters will read from RGBA components of color Forced Diffuse
epidermal mul par., epidermal dark rim factor, subdermal mul par., subdermal dark rim factor - parameters will read from RGBA of color Emissive
epidermal add par. - value obtained by calculation: 1 - epidermal mul par.
subdermal add par. - value obtained by calculation: 1 - subdermal mul par.
RGBA components meaning of colors Forced Diffuse and Emissive for Skin Shader (default values inside brackets):
Example of temporary ".rvmat" file
Specific parameters of Skin Shader are in Forced Diffuseand Emissive.
ambient[]={1.000000,1.000000,1.000000,1.000000}; diffuse[]={1.000000,1.000000,1.000000,1.000000}; forcedDiffuse[]={0.200000,0.400000,0.400000,0.500000}; emmisive[]={0.800000,0.300000,0.650000,0.700000}; specular[]={0.300000,0.300000,0.300000,1.000000}; specularPower=1.000000; PixelShaderID="Skin"; VertexShaderID="Skin"; class Stage1 { texture="hhl_NOHQ.tga"; uvSource="tex"; class uvTransform { aside[]={1.000000,0.000000,0.000000}; up[]={0.000000,1.000000,0.000000}; dir[]={0.000000,0.000000,0.000000}; pos[]={0.000000,0.000000,0.000000}; }; }; class Stage2 { texture="#(argb,8,8,3)color(0,0,0,0,MC)"; uvSource="tex"; }; class Stage3 { texture="CA\characters2\SkinShaderHead\hhl_SDM.tga"; uvSource="tex"; }; class Stage4 { texture="CA\characters2\SkinShaderHead\hhl_AS.tga"; uvSource="tex"; }; class Stage5 { texture="CA\characters2\SkinShaderHead\hhl_SMDI.tga"; uvSource="tex"; }; class Stage6 { texture="#(ai,64,1,1)fresnel(1.0,0.6)"; uvSource="none"; };
Example of optimal ".rvmat" file
For specific Skin Shader parameters is needed add support in engine and Objektiv.
ambient[]={1.000000,1.000000,1.000000,1.000000}; diffuse[]={1.000000,1.000000,1.000000,1.000000}; forcedDiffuse[]={0.000000,0.000000,0.000000,0.000000}; emmisive[]={0.000000,0.000000,0.000000,0.000000}; specular[]={1.000000,1.000000,1.000000,1.000000}; specularPower=10.000000; unscatteredColor[]={1.000000,1.000000,1.000000,1.000000}; unscatteredWeight=0.1; epidermalMul=0.8; epidermalAdd=0.2; darkRimFactorEp=0.3; epidermalWeight=0.4; subdermalMul=0.65; subdermalAdd=0.35; darkRimFactorSu=0.7; subdermalWeight=0.5; hemisphericSpecLevel=1.0; PixelShaderID="Skin"; VertexShaderID="Skin"; class Stage1 { texture="skin_NOHQ.tga"; uvSource="tex"; }; class Stage2 { texture="#(argb,8,8,3)color(0,0,0,0,MC)"; uvSource="tex"; }; class Stage3 { texture="skin_SDM.tga"; uvSource="tex"; }; class Stage4 { texture="skin_AS.tga"; uvSource="tex"; }; class Stage5 { texture="#(argb,8,8,3)color(0,0.1,0.1,0,SMDI)"; uvSource="tex"; }; class Stage6 { texture="#(ai,64,1,1)fresnel(1.0,0.6)"; uvSource="tex"; };
Texture preparation
Light penetration through human skin and it is following diffusion depends on wave length.Light with longer wave length (red part of spectrum) penetrates deepest under skin and respectively light with shorter wave length (blue-violet part of spectrum) nearly not penetrate at all. On following picture is comparison of individual colored channels on cutout from CO map.Individual channels are modified with help of curves to be approximately of equal brightness. On first look it is visible that red channel is in the skin area most 'blurred". That's just caused by larger share of light diffusion under skin.On the contrary blue channel contains most surface details.
Detail comparison in individual colored channels within segment of CO map:
Subdermal map and skin mask (SDM)
Subdermal texture looks like color shifted CO map to orange and more color saturated. Yet this technique isn't suitable. With regard to above information about dependence of light diffusion on wave length, it is probably most suitable prepare subdermal map with help of mixing channels (Photoshop->Layer->New Adjustment Layer->Channel Mixer...).)
SDM texture (rgb - subdermal map, alpha - skin mask):
Used settings of "Channel mixer" for individual RGB channels while preparing subdermal map from CO map:
Skin mask defines where it is used skin effect (white) and where is used material similar to Super Shader (black). Mask on the picture is prepared from red channel by help of curves and retouching with classic and de-inking brush.
Epidermal map
Epidermal map prepared like subdermal with aid of tool "Channel Mixer". In settings emphasize blue channel and suppress red one. Preparation of epidermal map with simple de-saturation of CO map is unrecommended.
Used settings of "Channel mixer" for individual RGB channels while preparing epidermal map from CO map:
With aid of skin mask insert resulting epidermal into CO map. There where is in CO map skin will be epidermal map, rest portions of CO map stays untouched. Within our sample cutout stay unchanged areas with hairs,beard and eyebrow.
Standalone epidermal map (left) and resulting CO map with epidermal map inserted in the skin area:
Normal and specular map (NOHQ and SMDI)
By materials with light diffusion under surface are visually appearing small surface asperities way less within light diffusion component but always stays expressive in specular component. For skin shader we would ideally need 4 normal maps (for each layer - subdermal, epidermal, unscattered, specular) with various surface niceness. For our case at the moment is sufficient compromise solution with one normal map along with not very indistinctive details suitable for diffuse component and specular map with amplified details. Actual normal map (hhl_NOHQ.tga) is high quality however SMDI map (hhl_SMDI.tga) has not needed level of details. Consequently new SMDI map was created by combining extracted details from normal and CO map. It needs still lot of retouching but it is enough for showcase.
Cut from green channel (specular mask) of example SMDI map:
Detail painting added by example SMDI map (right) against plain specular (left):