Real time AO in ray marched voxel worlds
Hello everyone. I'm in the process of building a minecraft-like voxel game, however unlike most implementations, I wanted to test it out using ray marching as the primary rendering technique.
Yesterday I developed an algorithm that calculates ambient occlusion by sampling the 9 neighbors directly in front of the face that was hit by a ray. The core idea is not too different from how most ray marched voxel renderers implement it, but I see most implementations rely on calculating the distance between the uv coordinate and the neighbor's uvs to act as the weight (the smaller the distance, the greater the ao)
In my version, I realized I only really care about the existence of the neighbors, since the uv coordinate of the face that was hit gives you all the information you need to know. We use the uvs to calculate weights for each combination of the edges of the face. For example, the bottom edge could be the inverse of the y coordinate, (so if uv.y = 0.2, then b= 0.8). Then the influence of the neighbors is just some combination of these weights.
So no distance calculations are needed.
The best part of this is that since the face's uvs are pre-calculated, the weights can be too. This makes the neighbor checking loop very minimal. We simply check for the neighbor's existence, and if its there, we add the corresponding weight to a running sum.
After that, we map the weight to a value between 0.0 and 1.0 to be used as the ao factor.
This worked surprisingly well, and is not too expensive. Here are the results:
My AO implementation on its own.
My AO + Textures (borrowed from Clarity 32x)
I'm sure it could be optimized further. On my system however I find that it's plenty fast enough.
Does anyone know of a similar technique?