Unpacking Normals

I’ve been working into the shader I was doing in the last blog post a little more. As I was finished with transparency and set my alpha to 1, I noticed that the light seemed off, with a band of specular light across the middle. This was because I had forgotten to unpack my normal!

When a map is marked as a normal map in Unity (and many other game engines), it changes its GPU compression type to DXT5. DXT or BC 5 compression ditches the blue channel in order to reduce file size. This works well with normal maps as the blue channel in a normal map represents the Z component of the surface normal and the Z should always be facing in the opposite direction from the camera. As we need the blue channel in order to calculate our normals, we use the UnpackNormal function.

fixed4 n = tex2D(_Normal, IN.uv_Normal);
o.Normal = UnpackNormal(n); //unpacks from dxt5nm to rgb

Below is a comparison of an unpacked normal vs a dxt5  packed normal – in the packed version the Z is always set to 0, regardless of the result of the dot product with the camera heading.

 

 

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 )

Google photo

You are commenting using your Google 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 )

Connecting to %s