From 80ff13d702d27d4a4517db5e462ee9751cc1ce43 Mon Sep 17 00:00:00 2001 From: EKNr1 Date: Thu, 19 Oct 2023 16:13:27 +0200 Subject: [PATCH] Chapter completed: Packed Data --- mesh/chunk.py | 4 +-- mesh/chunk_builder.py | 80 ++++++++++++++++++++++++++----------------- shaders/chunk.vert | 38 +++++++++++++++++--- 3 files changed, 83 insertions(+), 39 deletions(-) diff --git a/mesh/chunk.py b/mesh/chunk.py index 344298a..487fe30 100644 --- a/mesh/chunk.py +++ b/mesh/chunk.py @@ -12,9 +12,9 @@ class ChunkMesh(BaseMesh): self.ctx = self.app.ctx self.program = self.app.shader_program.chunk - self.vbo_format = "3u1 1u1 1u1 1u1 1u1" + self.vbo_format = "1u4" self.format_size = sum(int(fmt[:1]) for fmt in self.vbo_format.split()) - self.attributes = ("in_position", "voxel_id", "face_id", "ao_id", "flip_id") + self.attributes = ("packed_data",) self.vao = self.get_vao() def get_vertex_data(self): diff --git a/mesh/chunk_builder.py b/mesh/chunk_builder.py index d36f582..3bc9295 100644 --- a/mesh/chunk_builder.py +++ b/mesh/chunk_builder.py @@ -44,10 +44,27 @@ def get_ao(local_pos, world_pos, world_voxels, plane): @njit -def to_uint8(x, y, z, voxel_id, face_id, ao_id, flip_id): - return (uint8(x), uint8(y), uint8(z), - uint8(voxel_id), uint8(face_id), uint8(ao_id), uint8(flip_id) - ) +def pack_data(x, y, z, voxel_id, face_id, ao_id, flip_id): + # x: 6bit, y: 6bit, z: 6bit, voxel_id: 8bit, face_id: 3bit, ao_id: 2bit, flip_id: 1bit + a, b, c, d, e, f, g = x, y, z, voxel_id, face_id, ao_id, flip_id + + a_bit, b_bit, c_bit, d_bit, e_bit, f_bit, g_bit = 6, 6, 6, 8, 3, 2, 1 + fg_bit = f_bit + g_bit + efg_bit = e_bit + fg_bit + defg_bit = d_bit + efg_bit + cdefg_bit = c_bit + defg_bit + bcdefg_bit = b_bit + cdefg_bit + + packed_data = ( + a << bcdefg_bit | + b << cdefg_bit | + c << defg_bit | + d << efg_bit | + e << fg_bit | + f << g_bit | g + ) + + return packed_data @njit @@ -84,16 +101,15 @@ def is_void(local_voxel_pos, world_voxel_pos, world_voxels): @njit def add_data(vertex_data, index, *vertices): for vertex in vertices: - for attribute in vertex: - vertex_data[index] = attribute - index += 1 + vertex_data[index] = vertex + index += 1 return index @njit def build_chunk_mesh(chunk_voxels, format_size, chunk_pos, world_voxels): - vertex_data = numpy.empty(CHUNK_VOL * 18 * format_size, dtype="uint8") + vertex_data = numpy.empty(CHUNK_VOL * 18 * format_size, dtype="uint32") index = 0 for x in range(CHUNK_SIZE): @@ -117,10 +133,10 @@ def build_chunk_mesh(chunk_voxels, format_size, chunk_pos, world_voxels): flip_id = ao[1] + ao[3] > ao[0] + ao[2] # format: x, y, z, voxel_id, face_id, ao_id - v0 = to_uint8(x , y + 1, z , voxel_id, 0, ao[0], flip_id) - v1 = to_uint8(x + 1, y + 1, z , voxel_id, 0, ao[1], flip_id) - v2 = to_uint8(x + 1, y + 1, z + 1, voxel_id, 0, ao[2], flip_id) - v3 = to_uint8(x , y + 1, z + 1, voxel_id, 0, ao[3], flip_id) + v0 = pack_data(x , y + 1, z , voxel_id, 0, ao[0], flip_id) + v1 = pack_data(x + 1, y + 1, z , voxel_id, 0, ao[1], flip_id) + v2 = pack_data(x + 1, y + 1, z + 1, voxel_id, 0, ao[2], flip_id) + v3 = pack_data(x , y + 1, z + 1, voxel_id, 0, ao[3], flip_id) if flip_id: index = add_data(vertex_data, index, v1, v0, v3, v1, v3, v2) @@ -133,10 +149,10 @@ def build_chunk_mesh(chunk_voxels, format_size, chunk_pos, world_voxels): ao = get_ao((x, y - 1, z), (wx, wy - 1, wz), world_voxels, plane="Y") flip_id = ao[1] + ao[3] > ao[0] + ao[2] - v0 = to_uint8(x , y, z , voxel_id, 1, ao[0], flip_id) - v1 = to_uint8(x + 1, y, z , voxel_id, 1, ao[1], flip_id) - v2 = to_uint8(x + 1, y, z + 1, voxel_id, 1, ao[2], flip_id) - v3 = to_uint8(x , y, z + 1, voxel_id, 1, ao[3], flip_id) + v0 = pack_data(x , y, z , voxel_id, 1, ao[0], flip_id) + v1 = pack_data(x + 1, y, z , voxel_id, 1, ao[1], flip_id) + v2 = pack_data(x + 1, y, z + 1, voxel_id, 1, ao[2], flip_id) + v3 = pack_data(x , y, z + 1, voxel_id, 1, ao[3], flip_id) if flip_id: index = add_data(vertex_data, index, v1, v3, v0, v1, v2, v3) @@ -149,10 +165,10 @@ def build_chunk_mesh(chunk_voxels, format_size, chunk_pos, world_voxels): ao = get_ao((x + 1, y, z), (wx + 1, wy, wz), world_voxels, plane="X") flip_id = ao[1] + ao[3] > ao[0] + ao[2] - v0 = to_uint8(x + 1, y , z , voxel_id, 2, ao[0], flip_id) - v1 = to_uint8(x + 1, y + 1, z , voxel_id, 2, ao[1], flip_id) - v2 = to_uint8(x + 1, y + 1, z + 1, voxel_id, 2, ao[2], flip_id) - v3 = to_uint8(x + 1, y , z + 1, voxel_id, 2, ao[3], flip_id) + v0 = pack_data(x + 1, y , z , voxel_id, 2, ao[0], flip_id) + v1 = pack_data(x + 1, y + 1, z , voxel_id, 2, ao[1], flip_id) + v2 = pack_data(x + 1, y + 1, z + 1, voxel_id, 2, ao[2], flip_id) + v3 = pack_data(x + 1, y , z + 1, voxel_id, 2, ao[3], flip_id) if flip_id: index = add_data(vertex_data, index, v3, v0, v1, v3, v1, v2) @@ -165,10 +181,10 @@ def build_chunk_mesh(chunk_voxels, format_size, chunk_pos, world_voxels): ao = get_ao((x - 1, y, z), (wx - 1, wy, wz), world_voxels, plane="X") flip_id = ao[1] + ao[3] > ao[0] + ao[2] - v0 = to_uint8(x, y , z , voxel_id, 3, ao[0], flip_id) - v1 = to_uint8(x, y + 1, z , voxel_id, 3, ao[1], flip_id) - v2 = to_uint8(x, y + 1, z + 1, voxel_id, 3, ao[2], flip_id) - v3 = to_uint8(x, y , z + 1, voxel_id, 3, ao[3], flip_id) + v0 = pack_data(x, y , z , voxel_id, 3, ao[0], flip_id) + v1 = pack_data(x, y + 1, z , voxel_id, 3, ao[1], flip_id) + v2 = pack_data(x, y + 1, z + 1, voxel_id, 3, ao[2], flip_id) + v3 = pack_data(x, y , z + 1, voxel_id, 3, ao[3], flip_id) if flip_id: index = add_data(vertex_data, index, v3, v1, v0, v3, v2, v1) @@ -181,10 +197,10 @@ def build_chunk_mesh(chunk_voxels, format_size, chunk_pos, world_voxels): ao = get_ao((x, y, z - 1), (wx, wy, wz - 1), world_voxels, plane="Z") flip_id = ao[1] + ao[3] > ao[0] + ao[2] - v0 = to_uint8(x , y , z, voxel_id, 4, ao[0], flip_id) - v1 = to_uint8(x , y + 1, z, voxel_id, 4, ao[1], flip_id) - v2 = to_uint8(x + 1, y + 1, z, voxel_id, 4, ao[2], flip_id) - v3 = to_uint8(x + 1, y , z, voxel_id, 4, ao[3], flip_id) + v0 = pack_data(x , y , z, voxel_id, 4, ao[0], flip_id) + v1 = pack_data(x , y + 1, z, voxel_id, 4, ao[1], flip_id) + v2 = pack_data(x + 1, y + 1, z, voxel_id, 4, ao[2], flip_id) + v3 = pack_data(x + 1, y , z, voxel_id, 4, ao[3], flip_id) if flip_id: index = add_data(vertex_data, index, v3, v0, v1, v3, v1, v2) @@ -197,10 +213,10 @@ def build_chunk_mesh(chunk_voxels, format_size, chunk_pos, world_voxels): ao = get_ao((x, y, z + 1), (wx, wy, wz + 1), world_voxels, plane="Z") flip_id = ao[1] + ao[3] > ao[0] + ao[2] - v0 = to_uint8(x , y , z + 1, voxel_id, 5, ao[0], flip_id) - v1 = to_uint8(x , y + 1, z + 1, voxel_id, 5, ao[1], flip_id) - v2 = to_uint8(x + 1, y + 1, z + 1, voxel_id, 5, ao[2], flip_id) - v3 = to_uint8(x + 1, y , z + 1, voxel_id, 5, ao[3], flip_id) + v0 = pack_data(x , y , z + 1, voxel_id, 5, ao[0], flip_id) + v1 = pack_data(x , y + 1, z + 1, voxel_id, 5, ao[1], flip_id) + v2 = pack_data(x + 1, y + 1, z + 1, voxel_id, 5, ao[2], flip_id) + v3 = pack_data(x + 1, y , z + 1, voxel_id, 5, ao[3], flip_id) if flip_id: index = add_data(vertex_data, index, v3, v1, v0, v3, v2, v1) diff --git a/shaders/chunk.vert b/shaders/chunk.vert index 985238c..0960ecb 100644 --- a/shaders/chunk.vert +++ b/shaders/chunk.vert @@ -1,10 +1,12 @@ #version 330 core -layout (location = 0) in ivec3 in_position; -layout (location = 1) in int voxel_id; -layout (location = 2) in int face_id; -layout (location = 3) in int ao_id; -layout (location = 4) in int flip_id; +layout (location = 0) in uint packed_data; + +int x, y, z; +int voxel_id; +int face_id; +int ao_id; +int flip_id; uniform mat4 m_proj; uniform mat4 m_view; @@ -42,8 +44,34 @@ vec3 hash31(float p) { } +void unpack(uint packed_data) { + // a, b, c, d, e, f, g = x, y, z, voxel_id, face_id, ao_id, flip_id + uint b_bit = 6u, c_bit = 6u, d_bit = 8u, e_bit = 3u, f_bit = 2u, g_bit = 1u; + uint b_mask = 63u, c_mask = 63u, d_mask = 255u, e_mask = 7u, f_mask = 3u, g_mask = 1u; + + uint fg_bit = f_bit + g_bit; + uint efg_bit = e_bit + fg_bit; + uint defg_bit = d_bit + efg_bit; + uint cdefg_bit = c_bit + defg_bit; + uint bcdefg_bit = b_bit + cdefg_bit; + + x = int(packed_data >> bcdefg_bit); + y = int((packed_data >> cdefg_bit) & b_mask); + z = int((packed_data >> defg_bit) & c_mask); + + voxel_id = int((packed_data >> efg_bit) & d_mask); + face_id = int((packed_data >> fg_bit) & e_mask); + ao_id = int((packed_data >> g_bit) & f_mask); + flip_id = int(packed_data & g_mask); +} + + void main() { + unpack(packed_data); + + vec3 in_position = vec3(x, y, z); int uv_index = gl_VertexID % 6 + ((face_id & 1) + flip_id * 2) * 6; + uv = uv_coords[uv_indices[uv_index]]; voxel_color = hash31(voxel_id); shading = face_shading[face_id] * ao_values[ao_id];