Hey all,
I wanted to share some work I've been doing on computing ambient occlusion in voxel based environments. I actually added this to PolyVox SVN a couple of weeks ago but didn't get a chance to post about it yet.
Ambient occlusion is basically a measure of how much ambient light can reach a given point in the scene. It's simply a scale factor which you can multiply by the ambient light in your scene in order to make it darker inside caves, creavices, etc.
In order to compute the ambient occlusion for a given point, you can cast a large number of rays in different directions from the point in question. Then you simply count how many of these rays hit solid geometry. The percentage of rays which do not hit geometry gives a measure for how visible the point is to ambient light. The actul casting of rays can be performed using the Raycast class which was recently added to PolyVox.
The results can look something like the following. Note that there are no lights in the scene shown below - the variation in shading is completely due the ambient occlusion:


There is also the question of how this ambient oclcusion data should be stored. The new AmbientOcclusionCalculator class stores the results in a 3D array which I upload to the GPU as a volume texture. I'm using an ambient occlusion volume which is 1/4 the size of the main volume along each axis (so 1/64 the memory), but this still won't be appropriate for very large volumes. In that case, you'll probably want to investigate storing the data in the vertices instead. I can give more information if people are interested in this, you'll need to do some implementation yourself but you can still build on the Raycast class and use the existing work as an example.
The example scene above is 256x256x64, and the ambient occusion volume texture is 64x64x16. For each element in the ambient occlusion texture I cast 256 rays meaning a total of 16 million rays were cast. This took about 10 seconds on my machine. However, it's worth noting that ambient occlusion is a local effect, so that when the volume changes you only need to update the ambient occlusion for parts of the volume which are nearby. In Thermite it's close to realtime - I think that the flashes from explosions, etc will cover up any artifacts during the fraction of a second it will take to recompute.
Anyway, I hope this is interesting/useful to someone
