#version 450 layout(binding = 0) uniform UniformBufferObject { mat4 model; mat4 geom_rot; mat4 view; mat4 proj; vec3 camera_pos; bool[16] use_geom_shader; } ubo; layout(binding = 3) readonly buffer CompoundBuffer { uint compounds[]; }; layout(binding = 4) readonly buffer ColorBuffer { uint grid_in[]; }; layout(binding = 9) readonly buffer TransparentBuffer { bool transparent_grid[]; }; layout(binding = 7) buffer SizeBuffer2D { uint grid_out[]; }; layout(binding = 8) readonly buffer SizeBuffer3D { uint grid_size_in[]; }; layout (local_size_x = 16, local_size_y = 1, local_size_z = 1) in; void main() { uint index = gl_GlobalInvocationID.x; uint output_offset = 0; uint compound_start = 0; // iterate over the compounds and find the work index inside of it while (index > compounds[compound_start] * compounds[compound_start]) { output_offset += compounds[compound_start] * compounds[compound_start] * compounds[compound_start] * 2; index -= compounds[compound_start] * compounds[compound_start]; compound_start = compounds[compound_start + 2]; } // grid pos in the task uint compound_grid_size = compounds[compound_start]; float compound_scale = uintBitsToFloat(compounds[compound_start + 1]); vec3 mid_offset = vec3(compound_scale * 0.5, compound_scale * 0.5, compound_scale * 0.5); uint x = index % compound_grid_size; uint z = (index - x) / compound_grid_size; vec3 compound_pos = vec3(uintBitsToFloat(compounds[compound_start + 5]), uintBitsToFloat(compounds[compound_start + 6]), uintBitsToFloat(compounds[compound_start + 7])); // iterate upwards along the x axis bool seen_empty = false; uint start = 0; uint start_x_size = 0; uint last_col = 0; for (uint y=0; y < compound_grid_size; y++) { uint color_val = grid_in[output_offset + x * compound_grid_size * compound_grid_size + y * compound_grid_size + z]; bool transparent = transparent_grid[output_offset + x * compound_grid_size * compound_grid_size + y * compound_grid_size + z]; uint current_x_size = grid_size_in[output_offset + x * compound_grid_size * compound_grid_size + y * compound_grid_size + z]; grid_out[output_offset + (x * compound_grid_size * compound_grid_size + y * compound_grid_size + z) * 2] = 0; grid_out[output_offset + (x * compound_grid_size * compound_grid_size + y * compound_grid_size + z) * 2 + 1] = 0; // check if we need to stop a volume if (color_val != 0 && !transparent) { // check if we are in a volume right now if (seen_empty) { // close the current volume grid_out[output_offset + (x * compound_grid_size * compound_grid_size + start * compound_grid_size + z) * 2] = start_x_size; grid_out[output_offset + (x * compound_grid_size * compound_grid_size + start * compound_grid_size + z) * 2 + 1] = y - start; seen_empty = false; last_col = 0; } } else { // check if transparency changed if (seen_empty && ((transparent && last_col != color_val) || (start_x_size != current_x_size))) { // if we switch colors or size close the current volume and prepare for a new one grid_out[output_offset + (x * compound_grid_size * compound_grid_size + start * compound_grid_size + z) * 2] = start_x_size; grid_out[output_offset + (x * compound_grid_size * compound_grid_size + start * compound_grid_size + z) * 2 + 1] = y - start; seen_empty = false; } // start a new volume if we are not in one right now if (!seen_empty && current_x_size != 0) { seen_empty = true; start = y; start_x_size = current_x_size; last_col = color_val; } } } if (seen_empty) { grid_out[output_offset + (x * compound_grid_size * compound_grid_size + start * compound_grid_size + z) * 2] = start_x_size; grid_out[output_offset + (x * compound_grid_size * compound_grid_size + start * compound_grid_size + z) * 2 + 1] = compound_grid_size - start; } }