Real Shaders (for real)

After I finished my Animation degree, I participated in an online workshop for modelling game assets.  I was able to produce the case that is in this blog and displayed it in UDK for my portfolio.  I was thinking that I could do the same in Unity, but using shaders that will handle the diffuse, normal, and specular maps.  The problem with the way I was able to handle UDK at the time, was that it was difficult not to have a texture that was washed out.  I wasn’t able to get the crate to look the way I wanted it to look.

I found a shader that suited the bill on this discussion : http://answers.unity3d.com/questions/306921/add-specular-map-to-shader.html

The full shader is as follows:

Shader “Custom/DiffuseNormalSpecular” {
Properties {
_Color (“Main Color”, Color) = (1,1,1,1)
_SpecColor (“Specular Color”, Color) = (0.5, 0.5, 0.5, 1)
_Shininess (“Shininess”, Range (0.03, 1)) = 0.078125
_MainTex (“Base (RGB) Gloss (A)”, 2D) = “white” {}
_BumpMap (“Normalmap”, 2D) = “bump” {}
_SpecMap (“Specular map”, 2D) = “black” {}
}
SubShader {
Tags {
“RenderType”=”Opaque”
}
LOD 400
CGPROGRAM #pragma surface surf BlinnPhong

sampler2D _MainTex;
sampler2D _BumpMap;
sampler2D _SpecMap;
fixed4 _Color;
half _Shininess;

struct Input {
float2 uv_MainTex;
float2 uv_BumpMap;
float2 uv_SpecMap;
};

void surf (Input IN, inout SurfaceOutput o) {
fixed4 tex = tex2D(_MainTex, IN.uv_MainTex);
fixed4 specTex = tex2D(_SpecMap, IN.uv_SpecMap);
o.Albedo = tex.rgb * _Color.rgb;
o.Gloss = specTex.r;
o.Alpha = tex.a * _Color.a;
o.Specular = _Shininess * specTex.b;
o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
}
ENDCG
}

FallBack “Specular” }

 

I set my scene up in Unity and included some point lights surrounding the crate and a spotlight attached as a child to the camera. Using this shader with the “Shininess” set about 33% along the way, I get this image.

Stock standard options with about 33% shininess.

Stock standard options with about 33% shininess.

I think that the light is a bit too bright, but reducing the strength of the light means that the image is not as clear.  My first job is to try and intensify the colours so that there is a bit more depth. Multiplying the o.Albedo by 5  and then dividing by 5 made me realise the we must have been in the ballpark and tiny increments were needed to get the color intensity right.  I decided on multiplying the o.Albedo by a factor of 0.5 and had an immediate effect on the light intensity.

o.Albedo multiplied by factor of 0.5.

o.Albedo multiplied by factor of 0.5.

o.Gloss = specTex.r; was the next I wanted to look at.  It is still a tad too shiny so I tried multiplying by the blue channel of specTex and ended up multiplying that by a factor of 0.7 to get this:

o.Gloss multiplied by specTex.b and a factor of 0.7.

o.Gloss multiplied by specTex.b and a factor of 0.7.

This has reduced the effect of the spotlight and cleared out the unrealistic highlights at the rear of the object.  You can now see clearly the caution sticker on the front of the crate.

I am quite happy with this result, but there are still alpha and shininess to look at.  There are no alphas to worry about for this image, so we move on to shininess.  As I thought, there was nothing to be gained that couldn’t be achieved by sliding the Shininess toolbar on the material inspector.

I now have an interesting asset to display utilising both my degrees …. as soon as I work out how to use ambient occlusion and or shadows in Unity.  The model itself has ambient occlusion baked into the diffuse map but this scene needs more.

As a result, my final shader that I used in this project is :

Shader “Custom/DiffuseNormalSpecular” {
Properties {
_Color (“Main Color”, Color) = (1,1,1,1)
_SpecColor (“Specular Color”, Color) = (0.5, 0.5, 0.5, 1)
_Shininess (“Shininess”, Range (0.03, 1)) = 0.078125
_MainTex (“Base (RGB) Gloss (A)”, 2D) = “white” {}
_BumpMap (“Normalmap”, 2D) = “bump” {}
_SpecMap (“Specular map”, 2D) = “black” {}
}
SubShader {
Tags {
“RenderType”=”Opaque”
}
LOD 400
CGPROGRAM #pragma surface surf BlinnPhong

sampler2D _MainTex;
sampler2D _BumpMap;
sampler2D _SpecMap;
fixed4 _Color;
half _Shininess;

struct Input {
float2 uv_MainTex;
float2 uv_BumpMap;
float2 uv_SpecMap;
};

void surf (Input IN, inout SurfaceOutput o) {
fixed4 tex = tex2D(_MainTex, IN.uv_MainTex);
fixed4 specTex = tex2D(_SpecMap, IN.uv_SpecMap);
o.Albedo = tex.rgb * _Color.rgb * 0.5;
o.Gloss = specTex.r * specTex.b * 0.7
o.Alpha = tex.a * _Color.a;
o.Specular = _Shininess * specTex.b;
o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
}
ENDCG
}

FallBack “Specular” }

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s