#version 330 core layout (location = 0) in vec3 quad; layout (std140) uniform Matrices { mat4 proj; mat4 view; }; // world chunk position const int CHUNK_SIZE = 16; uniform ivec3 chunk_position; const int MAX_FACES = CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE; layout (std140) uniform Face { // normaly a uint but std140 layout // requires 16-byte alignment uvec4 face_data[MAX_FACES / 4]; }; flat out uvec2 pass_data; uint get_half(int index) { int arr_index = index / 4; int vec_index = index % 4; return face_data[arr_index][vec_index]; } uvec2 get_data(int index) { uint lower = get_half(index * 2); uint upper = get_half(index * 2 + 1); return uvec2(lower, upper); } vec3 get_quad(uint face, uint width, uint height) { vec3 squad = quad; squad.x *= width; squad.y *= height; switch(face) { case 0u: // PX return squad.yzx + vec3(1, 0, 0); case 1u: // NX return squad.yxz; case 2u: // PY return squad.xyz + vec3(0, 1, 0); case 3u: // NY return squad.zyx; case 4u: // PZ return squad.zxy + vec3(0, 0, 1); case 5u: // NZ return squad.xzy; } // should not happen return vec3(0); } void main(void) { // get face data uvec2 data = get_data(gl_InstanceID); uint x = (data.x >> 0) & 31u; uint y = (data.x >> 5) & 31u; uint z = (data.x >> 10) & 31u; uint width = (data.x >> 15) & 31u; uint height = (data.x >> 20) & 31u; uint face = (data.x >> 25) & 7u; // get quad verts vec3 quad = get_quad(face, width, height); // get position vec3 position = vec3(x, y, z); position += chunk_position * CHUNK_SIZE; position += quad; // draw gl_Position = proj * view * vec4(position, 1.0); pass_data = data; }