Skip to content

Instantly share code, notes, and snippets.

@rbnelr
Last active May 16, 2021 19:42
Show Gist options
  • Save rbnelr/b6f689b3684b639efc096392cc7cd265 to your computer and use it in GitHub Desktop.
Save rbnelr/b6f689b3684b639efc096392cc7cd265 to your computer and use it in GitHub Desktop.
// Blocks of pixels
#define LOCAL_SIZE_X 8
#define LOCAL_SIZE_Y 8
// 12 cones for VCT around a hemisphere
#define LOCAL_SIZE_Z 12
#define NUM_CONES LOCAL_SIZE_Z
struct Geometry {
vec3 pos;
vec3 normal;
vec3 tangent;
};
shared Geometry geom [LOCAL_SIZE_Y*LOCAL_SIZE_X];
shared vec3 cone_results [LOCAL_SIZE_Y*LOCAL_SIZE_X][NUM_CONES];
void main () {
uint pxid = gl_LocalInvocationID.y * LOCAL_SIZE_X + gl_LocalInvocationID.x;
uint coneid = gl_LocalInvocationID.z;
uvec2 pxpos = gl_GlobalInvocationID.xy;
Hit hit;
if (coneid == 0u) {
//// raytrace from camera to surface per pixel (most warps idle)
vec3 ray_pos, ray_dir;
get_ray(vec2(pxpos), ray_pos, ray_dir); // get ray from screen pixel pos
bool did_hit = trace_ray(ray_pos, ray_dir, INF, B_AIR, hit, RAYT_PRIMARY); // raytrace
if (!did_hit) {
// ray went outside of world cube
geom[pxid].pos.x = INF; // signal this to other threads
imageStore(output_color, ivec2(pxpos), vec4(0,0,0,1)); // write black to screen
} else {
// ray hit voxel, record geometry data for other threads
geom[pxid].pos = hit.pos;
geom[pxid].normal = hit.TBN[2];
geom[pxid].tangent = hit.TBN[0];
}
}
barrier(); // other threads wait until raytrace is done
if (geom[pxid].pos.x == INF)
return; // ray miss
{ // compute the VCT cone for this thread
// retrieve geometry data from raytrace thread
vec3 cone_pos = geom[pxid].pos;
vec3 normal = geom[pxid].normal;
vec3 tangent = geom[pxid].tangent;
// calc TBN
vec3 bitangent = cross(normal, tangent);
mat3 TBN = mat3(tangent, bitangent, normal);
Cone c = cones.cones[coneid];
vec3 cone_dir = TBN * c.dir;
// Trace a single cone for diffuse voxel cone lighting
vec3 res = trace_cone(cone_pos, cone_dir, c.slope, vct_start_dist, 400.0, true).rgb * c.weight;
// record lighting value
cone_results[pxid][coneid] = res;
}
barrier(); // wait for all cones to be done
// Write out results for pixel (most warps idle)
if (coneid == 0u) {
// add up weighted cone lighting values
vec3 light = vec3(0.0);
for (uint i=0u; i<NUM_CONES; ++i)
light += cone_results[threadid][i];
imageStore(output_color, ivec2(pxpos), vec4(light, 1.0)); // write out final
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment