# Consider adding very local ambient occlusion calculation to CubicSurfaceExtractor

Issue #26 new David Williams created an issue

A very fast and local AO approximation can be computed for each vertex of a cubic mesh by just looking at the eight surrounding voxels and counting how many of them are solid. This could be done in the CubicSurfaceExtractor.

1. reporter

I've given this quite some thought and think the feature should work as follows. Every cubic vertex is placed at a corner of a voxel, which means is is at the point where eight voxels touch. For each cubic vertex we call these eight voxels the neighbours. Give the CubicVertex a single uint8_t variable called 'neighbourhood'. During extraction, each bit of this variable is set or cleared according to whether a given neighbouring voxel is solid or not (note we don't handle transparency in this system, but it's not well supported in PolyVox anyway. This neighbourhood variable ends up encoding the visibility of the eight voxels surrounding a given vertex.

This neighbourhood information can be passed to the shader and used for at least two purposes:

1. It can be used to compute local ambient occlusion. A crude approach would be to simply count the number of set bits (probably tricky to do in a shader) and call this the amount of occlusion. A better an more practical approach would be to note that there are only 256 possible values - we can compute (offline) the occlusion factor which would correspond to each of these and to look up this value in the shader in a 256-entry lookup table (texture?).

2. It can be used to compute an approximate per-vertex normal. When working with cubic surface we generally don't want per-vertex normals as we prefer flat-shading and so compute the normals in the fragment shader with derivative operations. However, we have seen in Cubiquity that these can quite easily point in the opposite direction to that which is desired, depending on graphics API, OS, engine, etc. Having an approximate per-vertex normal would allow us to correct this by flipping the derivative-computed normal if it was significantly different from out per-vertex normal. Again, a 256-entry lookup table could be used here to get the normal from the 8-bit neighbourhood information.

2. reporter