Last active
May 16, 2021 19:42
-
-
Save rbnelr/b6f689b3684b639efc096392cc7cd265 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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