Game Development Community

Ambient occlusion shader

by Phil Carlisle · in Torque Game Engine Advanced · 03/18/2007 (6:15 am) · 7 replies

I've been looking at NVIDIA's example ambient occlusion shader and it struck me that while the effect is nice, its a bit strange for a couple of reasons:

1) The effect is vertex lighting based as far as I can tell
2) They have to heavily tesselate the mesh in order for that to work.

My question is.

Does anyone know of a paper/example of ambient occlusion technique that is pixel based and works with dynamic meshes.

I figure it would actually work reasonbly well with a dynamic generated coverage map, basically sample the surface visibility into a simple texture, then blur that texture and apply it as a lighting pass. I thought thats what the nvidia sample was doing, until reading the shaders, which seam to be basically using the pixel shader to create the vertex colour values (certainly the coverage value is per vertex, but thats fine, I was suprised that it wasnt then written into a secondary image for use as a pixel shader pass is all).

#1
03/19/2007 (11:43 am)
Do you need this to happen in realtime? Ambient occlusion is usually applied as a lightmap or burned into a dynamic object's base texture. Doing it in realtime is much more complicated and expensive.
#2
03/19/2007 (3:51 pm)
Yeah, the object itself is animated and it does look kinda strange without it. The idea I have only requires a very VERY simple scene, so its not a huge killer to have a lot of GPU applied to this. But actually, its not really that bad. According to the nvidia paper, it can handle around 1.5 million patch calcs per frame, given that the average is somewhere around 2000 or so patches, I think there's plenty of headroom.

What I'm trying to get, by way of reference, is a look like POCOYO (google image it), its a nice sort of diffuse lighting. Doesnt have to be 100% accurate and the NVIDIA paper on the technique was just fine in realtime.
#3
04/06/2007 (10:30 pm)
It is doable, but you'll have to jump across a bunch of source code files to do it. If you start with only self-occlusion (object occludes itself, ignoring other objetcs), you can study how the real-time shadows render themselves and modify them to render coverage maps too.

You'll also need to add some calls to the GFX layer to check for vertex texture fetch support (it's only avaiable in some shader 3.0 cards - seems all Nvidias support it, but only a few ATIs, if any).
#4
04/07/2007 (12:56 am)
Manoel, from what I understand of the nvidia technique, it wouldnt require vertex texture fetch, it basically relies on generating "occlusion area" values for each potentially occluding vertex, you do that by calculating the coverage of each vertex.. then you simply write those values into a texture, run it through a pixel shader that calcs the occlusion term for each destination vertex. The second pass it with the actual objects vertices.

The problem of course, is that its a per vertex ambient occlusion, so its not really that accurate, but then its pretty diffuse anyway. Other problem is that the model really needs quite fine tesselation in order not to look like its vertex based..
#5
04/07/2007 (9:56 am)
Ah, I see what you mean. I was talking about TGEA implementation, while the actual problem is that you need a per-pixel, not per-vertex implementation of the technique.

By your description, it should be possible to modify the technique to render to a lightmap dynamically, like subsurface scattering does, but I'll need to read the Nvidia paper to get more details.

Is this it?
#6
04/07/2007 (10:43 am)
I read it, and took a look at the source code. Indeed, it doesn't use VTF, and works by writing the shadow emitters/receivers information directly into textures.

The interesting thing is the occlusion is already calculated per fragment. I can't make out all the details (been a while since I worked with Cg and OpenGL, plus the whole effect is a bit beyond my current level), using interpolated receiver information, so it should work with lower polygon objects the same way as long as they have enough geometry to cause self-occlusion.

I googled for your reference material, and they look like simply shapes which could be done with 3~5K triangles and still cause a nice self-occlusion, since they're composed of large shapes instead of fine details.

Mind if I ask what you're doing this for? It's a rather CPU and GPU intensive effect, and the reference you passed looked aimed at children, which are the least probable to have high end video cards. Unless you're working on a Xbox360/PS3 project, or your game is something different than your reference material (sorry if I assumed it wrong), I'd advice looking at cheaper alternatives, like pre-calculated occlusion maps. They can look very nice and can be done for free.
#7
04/07/2007 (2:39 pm)
Yeah, thats the paper. If you look at it, its quite ugly in terms of code, but the technique is simple enough.

I'm actually looking at doing it for a little demo. We have loads of open days at the University and I thought it'd be kinda fun to render something like a pocoyo scene for a "mascot" character, with lots of wiggly animations and whatnot.

Then we'll maybe show some normal mapped homo-erotic soldier too, maybe a flaming monster or something. Basically its a shader demo for our open day presentations.