Ambient Occlusion for PolyVox

The past few days we were implementing ambient occlusion for the awesome PolyVox [1] library. There is an excellent article about pre-baked ambient occlusion in voxel based games at [2] which we based our implementation on. The details about our patch are basically all described in that blog post. I will just go over our implementation for PolyVox here - if you want to know more about the theory behind it, just check out the linked blog post.

PolyVox provides the cubic surface extractor (extractCubicMesh) which in the end generates a mesh with vertices from the volume you give to it. It was needed to hand in another functor here to determine whether a voxel contributes to ambient occlusion (e.g. you don't want air to contribute to AO). We extended the vertex structures by a byte for the ambient occlusion value. These can maybe get packed better - because only 3 bits of the byte are needed. The addVertex method was extended to do the ambient occlusion calculation - therefore it was needed to hand in some more voxel data into this function. After all the AO calculation was done, we modified the mergeQuads function to get back the original performance. It wasn't enough to merge just on the voxel data (color/material), but we of course also had to include the calculated ambient occlusion value (the same was true for the step before - the vertex reuse).

Last but not least we also implemented the quad flipping to generate good looking ambient occlusion for our PolyVox based voxel engine.

I hope the patch will be useful for others, too. You can find it at [3]. It's based on the develop branch of PolyVox. And now for the most interesting part - the screenshots:

The ambient occlusion as it looks right now.

The generated triangles after merging the quads again.

Please note that we didn't update the examples to completely work with AO. the basic code is there, but there is some work left to convince them to use the calculated ao value (mostly shader stuff).

In your shader, you can control how much each of the different AO states should contribute to the shading. You can e.g. do it like this:

   const float aovalues[] = float[](0.15, 0.6, 0.8, 1.0);
   v_ambientocclusion = aovalues[a_ao];

(assuming here that you use a_ao as the vertex array attribute name and v_ambientocclusion as the varying/out variable that is forwarded to your fragment shader.)

In your fragment shader you can just do something like this:

    o_color = color * v_ambientocclusion;

The next thing we are going to work on is most likely deferred rendering.


[1] PolyVox
[2] Ambient Occlusion for minecraft like worlds
[3] 0001-ambient-occlusion.patch.



Kommentar veröffentlichen

Beliebte Posts