SkinShader
m (Text replace - "<shaderlab>" to "<syntaxhighlight lang="shaderlab">") |
m (Text replace - "</shaderlab>" to "</syntaxhighlight>") |
||
| Line 223: | Line 223: | ||
} | } | ||
| − | </ | + | </syntaxhighlight> |
| Line 433: | Line 433: | ||
} | } | ||
| − | </ | + | </syntaxhighlight> |
Latest revision as of 23:56, 17 January 2012
Author: Aras Pranckevicius, artwork in the shots by Alpha-Loup.
See also: SkinShader2 that supports bumpmapping and where shading terms are controlled with textures.
Contents |
[edit] Description
A shader for skin rendering. This one expands on the built-in Glossy (Specular) shader:
- It uses "wrapped diffuse" lighting instead of regular diffuse. Gives softer look and more details in the shadowed sides of the object.
- It adds dedicated rim lighting in ambient pass.
It is a pixel-lit shader that requires vertex&fragment programs. Otherwise it falls back to built-in Specular|Glossy.
[edit] Usage
The shader exposes three additional properties in the material, compared to Glossy shader.
- Wrap lighting - the strength of "wrap diffuse". Slider on the left is regular diffuse, slider on the right is fully wrapped lighting. Usually it's best to decrease ambient light in render settings, and use higher wrap lighting instead.
- Rim color - the color of rim lighting.
- Rim power - how rim lighting spreads around the edges of the model.
Note that rim lighting happens only in the ambient pass; that means if you have vertex lights in your scene, there will be no rim lighting.
Unity 2.x version does not support receiving shadows on purpose, as shadows with wrap lighting don't look that good. It does cast shadows on any other objects though. If you want it to support shadows, replace "#pragma multi_compile_builtin_noshadows" with "#pragma multi_compile_builtin".
[edit] ShaderLab - SkinSpecular.shader for Unity 2.x
Invalid language.
You need to specify a language like this: <source lang="html4strict">...</source>
Supported languages for syntax highlighting:
4cs, 6502acme, 6502kickass, 6502tasm, 68000devpac, abap, actionscript, actionscript3, ada, algol68, apache, applescript, apt_sources, asm, asp, autoconf, autohotkey, autoit, avisynth, awk, bascomavr, bash, basic4gl, bf, bibtex, blitzbasic, bnf, boo, c, c_loadrunner, c_mac, caddcl, cadlisp, cfdg, cfm, chaiscript, cil, clojure, cmake, cobol, coffeescript, cpp, cpp-qt, csharp, css, cuesheet, d, dcs, delphi, diff, div, dos, dot, e, ecmascript, eiffel, email, epc, erlang, euphoria, f1, falcon, fo, fortran, freebasic, fsharp, gambas, gdb, genero, genie, gettext, glsl, gml, gnuplot, go, groovy, gwbasic, haskell, hicest, hq9plus, html4strict, html5, icon, idl, ini, inno, intercal, io, j, java, java5, javascript, jquery, kixtart, klonec, klonecpp, latex, lb, lisp, llvm, locobasic, logtalk, lolcode, lotusformulas, lotusscript, lscript, lsl2, lua, m68k, magiksf, make, mapbasic, matlab, mirc, mmix, modula2, modula3, mpasm, mxml, mysql, newlisp, nsis, oberon2, objc, objeck, ocaml, ocaml-brief, oobas, oracle11, oracle8, oxygene, oz, pascal, pcre, per, perl, perl6, pf, php, php-brief, pic16, pike, pixelbender, pli, plsql, postgresql, povray, powerbuilder, powershell, proftpd, progress, prolog, properties, providex, purebasic, pycon, python, q, qbasic, rails, rebol, reg, robots, rpmspec, rsplus, ruby, sas, scala, scheme, scilab, sdlbasic, smalltalk, smarty, sql, systemverilog, tcl, teraterm, text, thinbasic, tsql, typoscript, unicon, uscript, vala, vb, vbnet, verilog, vhdl, vim, visualfoxpro, visualprolog, whitespace, whois, winbatch, xbasic, xml, xorg_conf, xpp, yaml, z80, zxbasic
Shader "Skin/Specular" {
Properties {
_Color ("Main Color", Color) = (1,1,1,1)
_SpecColor ("Specular Color", Color) = (0.5, 0.5, 0.5, 1)
_Shininess ("Shininess", Range (0.01, 1)) = 0.078125
_MainTex ("Base (RGB) Gloss (A)", 2D) = "white" {}
_Wrap ("Wrap lighting", Range(0,1)) = 0.5
_RimColor ("Rim Color", Color) = (0.26,0.19,0.16,0.0)
_RimPower ("Rim Power", Range(0.5,8.0)) = 3.0
}
// ------------------------------------------------------------------
// Fragment program
SubShader {
Blend AppSrcAdd AppDstAdd
Fog { Color [_AddFog] }
TexCount 4
// Ambient pass
// This does ambient + rim lighting. Note that if you have vertexlit
// lights in the scene, then standard vertex lighting will be used instead,
// so you'll lose rim lighting.
Pass {
Name "BASE"
Tags {"LightMode" = "PixelOrNone"}
CGPROGRAM
#pragma fragment frag
#pragma vertex vert
#pragma fragmentoption ARB_fog_exp2
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
struct v2f {
V2F_POS_FOG;
float2 uv;
float3 viewDir;
float3 normal;
};
float4 _MainTex_ST;
v2f vert (appdata_base v)
{
v2f o;
PositionFog( v.vertex, o.pos, o.fog );
o.normal = v.normal;
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
o.viewDir = ObjSpaceViewDir( v.vertex );
return o;
}
uniform float4 _Color;
uniform float4 _RimColor;
uniform float _RimPower;
uniform sampler2D _MainTex;
float4 frag (v2f i) : COLOR
{
i.normal = normalize(i.normal);
i.viewDir = normalize(i.viewDir);
half4 texcol = tex2D( _MainTex, i.uv );
// rim factor
float rim = 1.0 - saturate(dot( i.normal, i.viewDir ));
half3 ambient = texcol.rgb * _PPLAmbient.rgb * 2;
half3 rimcolor = pow( rim, _RimPower ) * _RimColor.rgb;
return float4( ambient + rimcolor, texcol.a * _Color.a );
}
ENDCG
}
// Vertex lights
Pass {
Name "BASE"
Tags {"LightMode" = "Vertex"}
Lighting On
Material {
Diffuse [_Color]
Emission [_PPLAmbient]
Specular [_SpecColor]
Shininess [_Shininess]
}
SeparateSpecular On
CGPROGRAM
#pragma fragment frag
#pragma fragmentoption ARB_fog_exp2
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
half4 frag (v2f_vertex_lit i) : COLOR {
return VertexLight( i, _MainTex );
}
ENDCG
}
// Pixel lights
Pass {
Name "PPL"
Tags { "LightMode" = "Pixel" }
CGPROGRAM
#pragma fragment frag
#pragma vertex vert
#pragma multi_compile_builtin_noshadows
#pragma fragmentoption ARB_fog_exp2
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
#include "AutoLight.cginc"
struct v2f {
V2F_POS_FOG;
LIGHTING_COORDS
float3 uvK; // xy = UV, z = specular K
float3 viewDir;
float3 normal;
float3 lightDir;
};
uniform float _Shininess;
uniform float4 _MainTex_ST;
v2f vert (appdata_base v)
{
v2f o;
PositionFog( v.vertex, o.pos, o.fog );
o.normal = v.normal;
o.uvK.xy = TRANSFORM_TEX(v.texcoord,_MainTex);
o.uvK.z = _Shininess * 128;
o.lightDir = ObjSpaceLightDir( v.vertex );
o.viewDir = ObjSpaceViewDir( v.vertex );
TRANSFER_VERTEX_TO_FRAGMENT(o);
return o;
}
uniform sampler2D _MainTex;
uniform float _Wrap;
// Mostly copied from UnityCG.cginc; modified to use wrap lighting
// instead of regular diffuse.
inline half4 SpecularLightWrap( half3 lightDir, half3 viewDir, half3 normal, half4 color, float specK, half atten )
{
normal = normalize(normal);
lightDir = normalize(lightDir);
viewDir = normalize(viewDir);
half3 h = normalize( lightDir + viewDir );
// This would be regular diffuse component
//half diffuse = dot( normal, lightDir );
// This is "wrap diffuse" lighting.
// Note that if you know the _Wrap parameter you will use, the
// shader can be optimized. E.g. if _Wrap is 1.0, then putting that
// and simplifying the math becomes just
// half diffuse = dot(normal, lightDir) * 0.5 + 0.5;
half diffuse = max(0.0, (dot(normal, lightDir) + _Wrap) / (1.0 + _Wrap));
float nh = saturate( dot( h, normal ) );
float spec = pow( nh, specK ) * color.a;
spec *= diffuse;
half4 c;
c.rgb = (color.rgb * _ModelLightColor0.rgb * diffuse + _SpecularLightColor0.rgb * spec) * (atten * 2);
c.a = _SpecularLightColor0.a * spec * atten; // specular passes by default put highlights to overbright
return c;
}
half4 frag (v2f i) : COLOR
{
half4 texcol = tex2D( _MainTex, i.uvK.xy );
return SpecularLightWrap( i.lightDir, i.viewDir, i.normal, texcol, i.uvK.z, LIGHT_ATTENUATION(i) );
}
ENDCG
}
}
Fallback "Specular"
}
[edit] ShaderLab - SkinGlossy.shader for Unity 1.x
Invalid language.
You need to specify a language like this: <source lang="html4strict">...</source>
Supported languages for syntax highlighting:
4cs, 6502acme, 6502kickass, 6502tasm, 68000devpac, abap, actionscript, actionscript3, ada, algol68, apache, applescript, apt_sources, asm, asp, autoconf, autohotkey, autoit, avisynth, awk, bascomavr, bash, basic4gl, bf, bibtex, blitzbasic, bnf, boo, c, c_loadrunner, c_mac, caddcl, cadlisp, cfdg, cfm, chaiscript, cil, clojure, cmake, cobol, coffeescript, cpp, cpp-qt, csharp, css, cuesheet, d, dcs, delphi, diff, div, dos, dot, e, ecmascript, eiffel, email, epc, erlang, euphoria, f1, falcon, fo, fortran, freebasic, fsharp, gambas, gdb, genero, genie, gettext, glsl, gml, gnuplot, go, groovy, gwbasic, haskell, hicest, hq9plus, html4strict, html5, icon, idl, ini, inno, intercal, io, j, java, java5, javascript, jquery, kixtart, klonec, klonecpp, latex, lb, lisp, llvm, locobasic, logtalk, lolcode, lotusformulas, lotusscript, lscript, lsl2, lua, m68k, magiksf, make, mapbasic, matlab, mirc, mmix, modula2, modula3, mpasm, mxml, mysql, newlisp, nsis, oberon2, objc, objeck, ocaml, ocaml-brief, oobas, oracle11, oracle8, oxygene, oz, pascal, pcre, per, perl, perl6, pf, php, php-brief, pic16, pike, pixelbender, pli, plsql, postgresql, povray, powerbuilder, powershell, proftpd, progress, prolog, properties, providex, purebasic, pycon, python, q, qbasic, rails, rebol, reg, robots, rpmspec, rsplus, ruby, sas, scala, scheme, scilab, sdlbasic, smalltalk, smarty, sql, systemverilog, tcl, teraterm, text, thinbasic, tsql, typoscript, unicon, uscript, vala, vb, vbnet, verilog, vhdl, vim, visualfoxpro, visualprolog, whitespace, whois, winbatch, xbasic, xml, xorg_conf, xpp, yaml, z80, zxbasic
Shader "Skin/Specular" {
Properties {
_Color ("Main Color", Color) = (1,1,1,1)
_SpecColor ("Specular Color", Color) = (0.5, 0.5, 0.5, 1)
_Shininess ("Shininess", Range (0.01, 1)) = 0.078125
_MainTex ("Base (RGB) Gloss (A)", 2D) = "white" {}
_Wrap ("Wrap lighting", Range(0,1)) = 0.5
_RimColor ("Rim Color", Color) = (0.26,0.19,0.16,0.0)
_RimPower ("Rim Power", Range(0.5,8.0)) = 3.0
}
// ------------------------------------------------------------------
// Fragment program
SubShader {
Blend AppSrcAdd AppDstAdd
Fog { Color [_AddFog] }
TexCount 4
// Ambient pass
// This does ambient + rim lighting. Note that if you have vertexlit
// lights in the scene, then standard vertex lighting will be used instead,
// so you'll lose rim lighting.
Pass {
Name "BASE"
Tags {"LightMode" = "PixelOrNone"}
CGPROGRAM
// profiles arbfp1
// fragment frag
// vertex vert
// fragmentoption ARB_fog_exp2
// fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
struct v2f {
V2F_POS_FOG;
float2 uv : TEXCOORD0;
float3 viewDir : TEXCOORD1;
float3 normal : TEXCOORD2;
};
v2f vert (appdata_base v)
{
v2f o;
PositionFog( v.vertex, o.pos, o.fog );
o.normal = v.normal;
o.uv = TRANSFORM_UV(0);
o.viewDir = ObjSpaceViewDir( v.vertex );
return o;
}
uniform float4 _Color;
uniform float4 _RimColor;
uniform float _RimPower;
uniform sampler2D _MainTex : register(s0);
float4 frag (v2f i) : COLOR
{
i.normal = normalize(i.normal);
i.viewDir = normalize(i.viewDir);
half4 texcol = tex2D( _MainTex, i.uv );
// rim factor
float rim = 1.0 - saturate(dot( i.normal, i.viewDir ));
half3 ambient = texcol.rgb * _PPLAmbient.rgb * 2;
half3 rimcolor = pow( rim, _RimPower ) * _RimColor.rgb;
return float4( ambient + rimcolor, texcol.a * _Color.a );
}
ENDCG
SetTexture [_MainTex] {}
}
// Vertex lights
Pass {
Name "BASE"
Tags {"LightMode" = "Vertex"}
Lighting On
Material {
Diffuse [_Color]
Emission [_PPLAmbient]
Specular [_SpecColor]
Shininess [_Shininess]
}
SeparateSpecular On
CGPROGRAM
// profiles arbfp1
// fragment
// fragmentoption ARB_fog_exp2
// fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
half4 main (v2f_vertex_lit i) : COLOR {
return VertexLight( i, _MainTex );
}
ENDCG
SetTexture [_MainTex] {combine texture}
}
// Pixel lights
Pass {
Name "PPL"
Tags { "LightMode" = "Pixel" }
CGPROGRAM
// profiles arbfp1
// fragment frag
// vertex vert
// autolight 7
// fragmentoption ARB_fog_exp2
// fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
#include "AutoLight.cginc"
struct v2f {
V2F_POS_FOG;
float3 uvK : TEXCOORD0; // xy = UV, z = specular K
float3 viewDir : TEXCOORD1;
float3 normal : TEXCOORD2;
float3 lightDir : TEXCOORD3;
V2F_LIGHT_COORDS(TEXCOORD4);
};
struct v2f2 {
V2F_POS_FOG;
float3 uvK : TEXCOORD0; // xy = UV, z = specular K
float3 viewDir : TEXCOORD1;
float3 normal : TEXCOORD2;
float3 lightDir : TEXCOORD3;
};
uniform float _Shininess;
v2f vert (appdata_base v)
{
v2f o;
PositionFog( v.vertex, o.pos, o.fog );
o.normal = v.normal;
o.uvK.xy = TRANSFORM_UV(0);
o.uvK.z = _Shininess * 128;
o.lightDir = ObjSpaceLightDir( v.vertex );
o.viewDir = ObjSpaceViewDir( v.vertex );
PASS_LIGHT_COORDS(1);
return o;
}
uniform sampler2D _MainTex : register(s0);
uniform float _Wrap;
// Mostly copied from UnityCG.cginc; modified to use wrap lighting
// instead of regular diffuse.
inline half4 SpecularLightWrap(
half3 lightDir, half3 viewDir, half3 normal,
half4 color, float specK, half atten )
{
normal = normalize(normal);
lightDir = normalize(lightDir);
viewDir = normalize(viewDir);
half3 h = normalize( lightDir + viewDir );
// This would be regular diffuse component
//half diffuse = dot( normal, lightDir );
// This is "wrap diffuse" lighting.
// Note that if you know the _Wrap parameter you will use, the
// shader can be optimized. E.g. if _Wrap is 1.0, then putting that
// and simplifying the math becomes just
// half diffuse = dot(normal, lightDir) * 0.5 + 0.5;
half diffuse = max(0.0, (dot(normal, lightDir) + _Wrap) / (1.0 + _Wrap));
float nh = saturate( dot( h, normal ) );
float spec = pow( nh, specK ) * color.a;
spec *= diffuse;
half4 c;
c.rgb = (color.rgb * _ModelLightColor[0].rgb * diffuse +
_SpecularLightColor[0].rgb * spec) * (atten * 2);
// specular passes by default put highlights to overbright
c.a = _SpecularLightColor[0].a * spec * atten;
return c;
}
float4 frag (v2f2 i, LIGHTDECL(TEXUNIT1)) : COLOR
{
half4 texcol = tex2D( _MainTex, i.uvK.xy );
return SpecularLightWrap( i.lightDir, i.viewDir, i.normal, texcol, i.uvK.z, LIGHTATT );
}
ENDCG
SetTexture [_MainTex] {combine texture}
SetTexture [_LightTexture0] {combine texture}
SetTexture [_LightTextureB0] {combine texture}
}
}
Fallback " Glossy", 0
}