104 lines
3.0 KiB
Python
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
|
|
);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|