armory3d / armory

3D Engine with Blender Integration
https://armory3d.org/engine
zlib License
3.08k stars 316 forks source link

Accelerate Voxel Cone Tracing with fixed cone directions #1225

Closed FeodorVolguine closed 5 years ago

FeodorVolguine commented 5 years ago

Hello. I apologize if this is the incorrect place to put this (I'm still a noob with Github).

I have a suggestion that will take about 5-10 minutes to implement and will greatly speedup voxel cone tracing for diffuse and AO. This is really easy to implement, but if you have any questions just ask!

In master/Shaders/std/conetrace.glsl "traceDiffuse" and "traceAO" functions, the incoming radiance is approximated by tracing a certain number of cones directed around the hemisphere oriented around the surface normal. Instead of having varying cone directions depending on the normal vector, a set of "fixed" cone directions can be used (which are the same for each pixel/voxel regardless of the normal). Directions that go underneath the hemisphere are skipped. This means the cone tracing is very coherent, and thus faster.

traceDiffuse and traceAO functions become as simple as:

vec4 col = vec4(0.0f);
for(int i = 0; i < NUM_CONES; i++)
{
    float cosTheta = dot(normal, diffuseConeDirections[i]);
    if(cosTheta < 0.0f)
        continue;

        col += traceCone(voxels, origin, diffuseConeDirections[i], aperture, MAX_DISTANCE, normal);
}

/* Half of the cones are going to be skipped, which gives a hemisphere instead of the full sphere, so only weigh the final color by half of the number of cones */
col /= NUM_CONES * 0.5f;
return col ;

I made my own renderer that uses voxel global illumination for an engine I'm working on, and I just implemented fixed cone directions yesterday, so I thought I'd share this with you guys! This idea is originally from https://www.gamasutra.com/view/news/286023/Graphics_Deep_Dive_Cascaded_voxel_cone_tracing_in_The_Tomorrow_Children.php which explains it in more detail and why this is faster.

Here are the cone directions and aperture values:

#ifdef _VoxelCones16
    const vec3 diffuseConeDirections[16] = { vec3(0.57735f, 0.57735f, 0.57735f), vec3(0.57735f, -0.57735f, -0.57735f), vec3(-0.57735f, 0.57735f, -0.57735f), vec3(-0.57735f, -0.57735f, 0.57735f), vec3(-0.903007f, -0.182696f, -0.388844f), vec3(-0.903007f, 0.182696f, 0.388844f), vec3(0.903007f, -0.182696f, 0.388844f), vec3(0.903007f, 0.182696f, -0.388844f), vec3(-0.388844f, -0.903007f, -0.182696f), vec3(0.388844f, -0.903007f, 0.182696f), vec3(0.388844f, 0.903007f, -0.182696f), vec3(-0.388844f, 0.903007f, 0.182696f), vec3(-0.182696f, -0.388844f, -0.903007f), vec3(0.182696f, 0.388844f, -0.903007f), vec3(-0.182696f, 0.388844f, 0.903007f), vec3(0.182696f, -0.388844f, 0.903007f) };  
    const float aperture = 0.872665f;
        #define NUM_CONES 16
#endif
#ifdef _VoxelCones32
    const vec3 diffuseConeDirections[32] = { vec3(0.898904f, 0.435512f, 0.0479745f), vec3(0.898904f, -0.435512f, -0.0479745f), vec3(0.898904f, 0.0479745f, -0.435512f), vec3(0.898904f, -0.0479745f, 0.435512f), vec3(-0.898904f, 0.435512f, -0.0479745f), vec3(-0.898904f, -0.435512f, 0.0479745f), vec3(-0.898904f, 0.0479745f, 0.435512f), vec3(-0.898904f, -0.0479745f, -0.435512f), vec3(0.0479745f, 0.898904f, 0.435512f), vec3(-0.0479745f, 0.898904f, -0.435512f), vec3(-0.435512f, 0.898904f, 0.0479745f), vec3(0.435512f, 0.898904f, -0.0479745f), vec3(-0.0479745f, -0.898904f, 0.435512f), vec3(0.0479745f, -0.898904f, -0.435512f), vec3(0.435512f, -0.898904f, 0.0479745f), vec3(-0.435512f, -0.898904f, -0.0479745f), vec3(0.435512f, 0.0479745f, 0.898904f), vec3(-0.435512f, -0.0479745f, 0.898904f), vec3(0.0479745f, -0.435512f, 0.898904f), vec3(-0.0479745f, 0.435512f, 0.898904f), vec3(0.435512f, -0.0479745f, -0.898904f), vec3(-0.435512f, 0.0479745f, -0.898904f), vec3(0.0479745f, 0.435512f, -0.898904f), vec3(-0.0479745f, -0.435512f, -0.898904f), vec3(0.57735f, 0.57735f, 0.57735f), vec3(0.57735f, 0.57735f, -0.57735f), vec3(0.57735f, -0.57735f, 0.57735f), vec3(0.57735f, -0.57735f, -0.57735f), vec3(-0.57735f, 0.57735f, 0.57735f), vec3(-0.57735f, 0.57735f, -0.57735f), vec3(-0.57735f, -0.57735f, 0.57735f), vec3(-0.57735f, -0.57735f, -0.57735f) };
    const float aperture = 0.628319f;
        #define NUM_CONES 32
#endif
luboslenco commented 5 years ago

Pure awesome, thanks for sharing here!