#include "orientations.sh" #include "bgfx_compute.sh" // INPUT // grids (matrices) BUFFER_RO(grids, vec4, 0); // chunks (grid_id, offset_x, _y, _z) BUFFER_RO(chunks, vec4, 1); // blocks (chunk_id, transform [pos in chunk, rotation], idx_buf_offset, num_indices) BUFFER_RO(blocks, vec4, 2); // block selection (visible blocks post-culling) BUFFER_RO(block_selection, float, 3); // OUTPUT // indirect draw calls BUFFER_WR(indirectBuffer, uvec4, 4); // matrices for each instance BUFFER_WR(instanceBuffer, vec4, 5); uniform vec4 u_cubes_compute_params; // Use 64*1*1 local threads NUM_THREADS(64, 1, 1) void main() { int tId = int(gl_GlobalInvocationID.x); int numDrawItems = int(u_cubes_compute_params.w); int numToDrawPerThread = numDrawItems/64 + 1; int idxStart = tId*numToDrawPerThread; int idxMax = min(numDrawItems, (tId+1)*numToDrawPerThread); for (int k = idxStart; k < idxMax; k++) { uint block_id = block_selection[k]; // get block data uint b_chunk_id = blocks[block_id].x; uint b_transform = blocks[block_id].y; uint b_index_buf_offset = blocks[block_id].z; uint b_num_indices = blocks[block_id].w; // get chunk data uint c_grid_id = chunks[b_chunk_id].x; vec3 c_offset = chunks[b_chunk_id].yzw; // get grid data mat4 g_mtx = mtxFromRows(grids[c_grid_id*4 + 0], grids[c_grid_id*4 + 1], grids[c_grid_id*4 + 2], grids[c_grid_id*4 + 3]); // calc block offset // b_transform == [off_x | off_y | off_z | orientation] uint b_orientation = b_transform & 0x1F; // 5 bit vec3 b_offset; b_offset.x = (b_transform >> 11) & 0x7; // 3 bit b_offset.y = (b_transform >> 8) & 0x7; // 3 bit b_offset.z = (b_transform >> 5) & 0x7; // 3 bit b_offset = b_offset + (c_offset * 8); // rotate block -> offset block -> apply g_mtx // apply orientation mat3 b_mtx_orientation = orientations[b_orientation]; // apply offset mat4 b_mtx = mat4(b_mtx_orientation); // Note: glsl matrices are colum major //mat4 b_mtx; //b_mtx[0] = vec4(1,0,0,0); //b_mtx[1] = vec4(0,1,0,0); //b_mtx[2] = vec4(0,0,1,0); b_mtx[3] = vec4(b_offset, 1); // apply g_mtx mat4 mtx_model = mul(b_mtx, g_mtx); instanceBuffer[k*4+0] = mtx_model[0]; instanceBuffer[k*4+1] = mtx_model[1]; instanceBuffer[k*4+2] = mtx_model[2]; instanceBuffer[k*4+3] = mtx_model[3]; // Fill indirect buffer drawIndexedIndirect( // Target location params: indirectBuffer, // target buffer k, // index in buffer // Draw call params: b_num_indices, // number of indices for this draw call 1u, // number of instances for this draw call. You can disable this draw call by setting to zero b_index_buf_offset, // offset in the index buffer 0, // offset in the vertex buffer. Note that you can use this to "re-index" sub-meshes - all indices in this draw will be decremented by this amount k // offset in the instance buffer. If you are drawing more than 1 instance per call see "gpu driven rendering" for how to handle ); } }