Files
space_game/shaders/cs_cubes.sc
2026-01-29 17:06:34 +01:00

104 lines
3.0 KiB
Python

#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
);
}
}