This crazy real time ambient occlusion

I saw this link on Aras’ site to a demoscene that features real time ambient occlusion and a paper about it…

Heres the demo: http://www.youtube.com/watch?v=9AX8gNyrSWc

And paper: http://rgba.scenesp.org/iq/computer/articles/ssao/ssao.htm

As for how they generate the mesh in the demo I have no clue whatsoever but it looks awesome.

Anyway, now comes the inevitable question… Is this possible in unity? Seems like it should be not that hard. I did a little experiment and drew the depth of the scene on a cube in front of the camera.

I have some questions. Right now on LateUpdate I do a switcheroo of all the materials and the camera settings, then camera.Render();, then set everything back the way it was and place the RenderTexture on the cube.

How would one really approach this? It almost seems like it could be a full screen image effect. I tried at first to make a full screen pixel correct render texture but that didn’t work, I got an error message when placing the render texture on the cube saying the dimensions were wrong or something, and I got garbage on the cube. Making it power of two using mipmaps fixed it.

From the screenshots I’ve seen it looks like it actually works, and the shader doesn’t look extremely complex to make so this is exciting.

![](http://rgba.scenesp.org/iq/computer/articles/ssao/julia03_peq.jpg)

Reminds me of one of my favorite pieces…Gestalt… not realtime but uses similar fractal quaternion geometry.

Let me know Forest if you’re getting fancy with realtime AO and quaternion fractal based race tracks… our race cars might need some modding to cope with this :wink:

Seriously though, any experiments on this front are very interesting.

Ethan

There are several components to make such realtime AO (SSAO for “screen space ambient occlusion”) practical:

  1. Support for high precision, single channel render textures, so you can render linear depth to them. D3D9 has that, the hardware supports that since 2002, but unfortunately OpenGL does not have that. The only workaround on OpenGL is to burn 4x times more VRAM and 4x times more bandwidth and use a 4 channel floating point render texture. Duh. This is probably the major reason why high precision single channel render textures are not exposed in Unity; as it’s just not practical on OpenGL.

  2. An easy way to say “render from this camera, and make everything use this shader”. Currently this can be done with some manual work; just like you did - swap the materials before rendering, restore them back after rendering. Someday we’ll add a built-in feature to do this.

  3. Support for quite long fragment shaders, as good looking SSAO needs lots of samples to look good. Again, this would be easy on D3D9 with pixel shader 3.0; and on OpenGL possibly GLSL could be used (with lots of praying that it will actually work).

So yeah, the effect is cool, but it’s tricky to do in practical way mostly because of 1st and 3rd points.

…oh, and that demo does raytracing against a fractal in a pixel shader. So actually there’s no fractal geometry whatsoever. And it runs oh so slow, but then it’s also very cool.

So you are saying with point 1 that simply encoding the depth into the render texture as the alpha channel or a color channel will not be precise enough? It seems one could also spread the depth out over a few channels to get more precision, but that just makes your depth shader and SSAO shader more complicated, right?

And point 3 I can understand, although I have never tested the limits of how long a fragment program can be. Is it a hard limit or specific to each card?

Maybe I shouldn’t have been thinking about this so hard, cause now I’m really itching to try it out. I had some other ideas about how to improve it, like storing the “average depth” of each object in an unused channel in the render texture to help get rid of artifacts where you get a black line around things in the foreground.

(this problem seen in the bottom right project offset screenshot)

Its alive!

Awesome Yoggy.

I’ve been playing a bit with this too, the effect is too cool to stay away from. I already had the depthmap from my dof effect so I thought it would be easy. Haven’t cracked it yet though. Good work

/Patrik

sweet yoggy - though what is causing the blotchy effect?

Ooh. :slight_smile: The artifacts are actually rather pretty.

I’d guess he’s not yet got to the “Second Trick” section here, which talks about banding:
http://rgba.scenesp.org/iq/computer/articles/ssao/ssao.htm

Cheers,
-Jon

Yeah I thought so too, jon. Looks like pencil shading sometimes :smile:

Its caused by depth buffer imprecision induced by the fact that I am only using 1 channel of a render texture to store the depth.

I am going to try to save up enough instructions to add noise too it too, which will probably help quite a bit. Then I’ve got to figure out the blur pass too.

Oh and patrik / anyone else who wants to have a look so far, heres a WIP package:

63400–2323–$ssao_519.zip (14.7 KB)

“The second trick”

63420--2326--$test_copy_182.jpg

just too cool - and I agree - the artifacts actually add to it, kill the CG ness by making it gritty, sorta like sharcoal - wonder if you can make it look like watercolor or clay too

Its coming along quite nicely, I added some interactivity to showcase it’s realtimeness.

Just need to figure out the blur now.

http://yogware.bluegillstudios.com/SSAO/SSAO.html

Edit: The shader isn’t working in the webplayer here… Oh well, I need to sleep…

63469–2327–$ssao_163.unitypackage (564 KB)
63469--2328--$picture_19_189.png

hi Yoggy

Just wanted to let you know its working in the webplayer here on my pc:
windows xp sp2
explorer 7
geforce 8800 gts 320mb
2 gb ram

Also; thats bloody amazing! I remember being in awe when I saw a demonstration of CryEngine2 that included realtime AO and now Unity has it too. Thats just soo cool!

Congrats on your smartness :stuck_out_tongue:

Yoggy that is stunning. I also agree the rougher dotted artifacts really help get rid of that too clean computer generated look, but the web player is magnificant. I want one :smile:
A question which is way too early to ask - could this be applied to the terrain stuff so that trees and detail meshes look properly grounded? :slight_smile:
Nice work
Boxy

Very cool Forest!

I download the SSAO.unityPackage and import this to a new scene, but I get blank screen when I run this!!

Amazing stuff, I really hope you continue the work and release an even more pulished version.

Just one question: it only works on Unity Pro, isn’t it?

Really looking forward to updates on this :smile:.

I have a friend who runs a local games studio and he’s working on a little xbla game and is using this kind of thing (AO is calculated in real time, while all his models etc mostly just have block colours on)

I get a blank screen when running it maximized, and non maximized it dosent seem to work :S

It does work in the webplayer tho on both my mac and pc.

When loading up the package in Unity I get the error “Cg in program “frag”: error C6003: Arithmatic instruction limit of 64 exceeded; 70 arithmatic instructions needed to compile program at line 21.”

Thats really cool.

To speed things up, couldn’t you kinda bake any self AO or static AO?

Just an idea.

Keep it up.

Geoff