Directional AO

Thomaz Nardelli

Using traditional Ambient Occlusion is a common practice to increase realism in textures, but often produces unrealistic results in more complex objects.

Traditional ambient occlusion

A relatively cheap way to fix some of those problems is using a Directional Occlusion map, there are several ways to create/use one, I'll show my own approach with its pros and cons.

Bake

First step it bake it, I used cycles, it was pretty straight forward with the only headache being the different coordinate systems between blender and Unity.

All you gotta do is get the direction of the light ray as color, I created a sky texture with the correct coordinate system already applied and then simply baked it using the default cycles Diffuse BSDF.

The object being affected by the sky texture

Bake 2 images per direction, one positive and other negative, then composite them to encode in 0~1 range values, since Unity will not accept negative values from pngs.

While you are at it, you can also bake a Traditional AO map and encode it as Alpha.

After you finish you should have an image that looks almost exactly like an oject space normal map, in my case, this:

The encoded Directional AO

Then when you import to Unity remember to not use sRGB and keep the compression as low as possible.

Shader

To put it into use it's also pretty simple, sample it as a normal texture then decode it:

fixed4 directionalAO = tex2D(_DirectionalAO, i.uv);
directionalAO = (directionalAO * 2) - 1;

This will bring it to it's original -1~1 range.

Then you want to convert it from Object Space to World Space:

directionalAO.rgb = UnityObjectToWorldNormal(directionalAO.rgb);

And with that done you use it to sample your ambient light, in this case i'm using Unity's light probe:

fixed3 ambient = ShadeSH9(half4(directionalAO.rgb, 1));
ambient *= directionalAO.a;

And it's done!

However there are pros and cons to this technique.

Pros

Cons

There are other approaches to this, some know as bent normals, I also belive you can achieve similar results using Valve's ssbump.

Feel free to contact me with any questions or suggestions.