mardi 5 février 2013

Unity Shader : Silhouette

While I was at the university, the most interesting course was the shaders. It was also the hardest.

To sum my opinion about shaders, I'd say they are as hard as they are rewarding.

Today, for the game we are currently developing, I had to go back to the shaders, but also, I had to learn a lot from the shader system Unity offers.

It's really good, but it's really confusing. Plus, the tutorials don't have a clear starting point, nor a clear end.

I found nearly the exact shader I needed here, but I wanted to learn today.

So, With the help of the shader showed above, I created a pass that draws a colored overlay Silhouette of the character.

Shader "Player/Silhouette" {
Properties 
{
_MainTex ("Base (RGB)", 2D) = "white" {}
_BumpMap ("Normalmap", 2D) = "bump" {}
_SilhouetteColor ("Silhouette Color", Color) = (1,1,1,1)
}

SubShader {
Tags { "LightMode"="Always" "Queue" = "Transparent" }
LOD 250

//code dessinant la silhouette
Pass
{
Name "SILHOUETTE"
ZTest Greater
Offset 0 , -3000
cull back
ZWrite off

CGPROGRAM
#pragma fragment frag
#pragma vertex vert
#include "UnityCG.cginc"
float4 _SilhouetteColor;
struct v2f {
    float4 pos : SV_POSITION;
};

v2f vert (appdata_base v)
{
    v2f o;
    o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
    return o;
}

half4 frag (v2f i) : COLOR
{
    return _SilhouetteColor;
}
ENDCG
}
}

FallBack "Mobile/Diffuse"
}


To use it, add
usepass "Player/Silhouette/SILHOUETTE"
Before your shader, and add the property :
_SilhouetteColor ("Silhouette Color", Color) = (1,1,1,1)

And there you have it.

How it works
It's simple, really, yet I'm not sure I did it the right way.
It draws the silhouette whenever an object is overlapping (using the ZBuffer to determinate this) with a threshold of 3000 units.
Also, it doesn't change the Z-Buffer.

Hope It'll help !