Anisotropic Highlight Shader

From Unify Community Wiki
(Difference between revisions)
Jump to: navigation, search
(Description)
(Shader Code)
Line 40: Line 40:
 
_BumpMap ("Normal (Normal)", 2D) = "bump" {}
 
_BumpMap ("Normal (Normal)", 2D) = "bump" {}
 
_AnisoTex ("Anisotropic Direction (RGB)", 2D) = "bump" {}
 
_AnisoTex ("Anisotropic Direction (RGB)", 2D) = "bump" {}
_AnisoRamp ("Anisotropic Ramp (RGB)", 2D) = "black" {}
+
_AnisoOffset ("Anisotropic Highlight Offset", Range(-1,1)) = -0.2
_AnisoOffset ("Anisotropic Highlight Offset", Range(-0.5,0.5)) = -0.2
+
 
_Cutoff ("Alpha Cut-Off Threshold", Range(0,1)) = 0.5
 
_Cutoff ("Alpha Cut-Off Threshold", Range(0,1)) = 0.5
 
}
 
}
Line 60: Line 59:
 
};
 
};
  
sampler2D _AnisoRamp;
 
 
float _AnisoOffset, _Cutoff;
 
float _AnisoOffset, _Cutoff;
 
inline fixed4 LightingAniso (SurfaceOutputAniso s, fixed3 lightDir, fixed3 viewDir, fixed atten)
 
inline fixed4 LightingAniso (SurfaceOutputAniso s, fixed3 lightDir, fixed3 viewDir, fixed atten)
 
{
 
{
fixed3 h = normalize(lightDir + viewDir);
+
fixed3 h = normalize(normalize(lightDir) + normalize(viewDir));
float nh = saturate(dot(s.Normal, h));
+
float NdotL = dot(s.Normal, lightDir);
 
+
fixed NdotL = saturate(dot(s.Normal, lightDir));
+
 
fixed HdotA = dot(normalize(s.Normal + s.AnisoDir.rgb), h);
 
fixed HdotA = dot(normalize(s.Normal + s.AnisoDir.rgb), h);
 
+
float aniso = max(0, sin(radians((HdotA + _AnisoOffset) * 180)));
float2 anisoUV = float2(HdotA, 0.5);
+
anisoUV.x += _AnisoOffset;
+
float spec = saturate(dot(s.Normal, h));
fixed3 aniso = pow(tex2D(_AnisoRamp, anisoUV), s.Gloss * 128) * s.Specular;
+
spec = saturate(pow(lerp(spec, aniso, s.AnisoDir.a), s.Gloss * 128) * s.Specular);
 
+
fixed3 spec = fixed3(pow(nh, s.Gloss * 128) * s.Specular);
+
spec = lerp(spec, aniso, s.AnisoDir.a);
+
  
 
fixed4 c;
 
fixed4 c;

Revision as of 16:09, 30 June 2011


Originally done by James O'Hare.

Description

Anisotropic highlights on brushed metal.

This shader gives an anisotropic highlight, similar to the highlights found on brushed metal or hair. The highlight can be blended from anisotropic to blinn based on the blue channel of the specular map.

Supports diffuse, normal, specular and gloss shading with alphatested transparency. Gloss and specular values also apply to the anisotropic highlight.

The highlight can be shifted up or down the surface using the Anisotropic Highlight Offset value.

The direction of the surface for anisotropic highlight is defined using a directional texture like these. These act similarly to tangent space normal maps, defining the direction of the surface. However, they should not be converted to normal maps in Unity.

Anisotropic directional texture mimicking brushed metal.
Anisotropic directional texture mimicking brushed metal.

Usage

  • Anisotropic Direction: Direction of the surface highlight. Follows the same directional values as a tangent space normal map.
  • Specular: The specular level is defined in the red channel of the specular texture. This controls the brightness of the specular highlight.
  • Gloss: The gloss level is defined in the green channel of the specular texture. This controls how sharp (full green) or wide (no green) the specular highlight is. It's best to keep this value non-zero.
  • Anisotropic Mask: The blue channel of the specular texture is used to blend between anisotropic and blinn highlights. Full blue = full anisotropic, no blue = full blinn.
  • Anisotropic Offset: Can be used to push the highlight towards or away from the centre point.

Shader Code

<shaderlab> Shader "Bumped Anisotropic Specular" { Properties { _Color ("Main Color", Color) = (1,1,1,1) _MainTex ("Diffuse (RGB) Alpha (A)", 2D) = "white" {} _SpecularTex ("Specular (R) Gloss (G) Anisotropic Mask (B)", 2D) = "gray" {} _BumpMap ("Normal (Normal)", 2D) = "bump" {} _AnisoTex ("Anisotropic Direction (RGB)", 2D) = "bump" {} _AnisoOffset ("Anisotropic Highlight Offset", Range(-1,1)) = -0.2 _Cutoff ("Alpha Cut-Off Threshold", Range(0,1)) = 0.5 }

SubShader{ Tags { "RenderType" = "Opaque" }

CGPROGRAM

struct SurfaceOutputAniso { fixed3 Albedo; fixed3 Normal; fixed4 AnisoDir; fixed3 Emission; half Specular; fixed Gloss; fixed Alpha; };

float _AnisoOffset, _Cutoff; inline fixed4 LightingAniso (SurfaceOutputAniso s, fixed3 lightDir, fixed3 viewDir, fixed atten) { fixed3 h = normalize(normalize(lightDir) + normalize(viewDir)); float NdotL = dot(s.Normal, lightDir);

fixed HdotA = dot(normalize(s.Normal + s.AnisoDir.rgb), h); float aniso = max(0, sin(radians((HdotA + _AnisoOffset) * 180)));

float spec = saturate(dot(s.Normal, h)); spec = saturate(pow(lerp(spec, aniso, s.AnisoDir.a), s.Gloss * 128) * s.Specular);

fixed4 c; c.rgb = ((s.Albedo * _LightColor0.rgb * NdotL) + (_LightColor0.rgb * spec)) * (atten * 2); clip(s.Alpha - _Cutoff); c.a = 1; return c; }

#pragma surface surf Aniso #pragma target 3.0

struct Input { float2 uv_MainTex; float2 uv_AnisoTex; };

sampler2D _MainTex, _SpecularTex, _BumpMap, _AnisoTex;

void surf (Input IN, inout SurfaceOutputAniso o) { o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb; o.Alpha = tex2D(_MainTex, IN.uv_MainTex).a; o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_MainTex)); fixed3 spec = tex2D(_SpecularTex, IN.uv_MainTex).rgb; o.Specular = spec.r; o.Gloss = spec.g; o.AnisoDir = fixed4(tex2D(_AnisoTex, IN.uv_AnisoTex).rgb, spec.b); } ENDCG } FallBack "Transparent/Cutout/Bumped Specular" } </shaderlab>

Personal tools
Namespaces

Variants
Actions
Navigation
Extras
Toolbox