Chapter completed: Packed Data
This commit is contained in:
parent
b1edaf6fc1
commit
80ff13d702
3 changed files with 83 additions and 39 deletions
|
@ -12,9 +12,9 @@ class ChunkMesh(BaseMesh):
|
||||||
self.ctx = self.app.ctx
|
self.ctx = self.app.ctx
|
||||||
self.program = self.app.shader_program.chunk
|
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.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()
|
self.vao = self.get_vao()
|
||||||
|
|
||||||
def get_vertex_data(self):
|
def get_vertex_data(self):
|
||||||
|
|
|
@ -44,11 +44,28 @@ def get_ao(local_pos, world_pos, world_voxels, plane):
|
||||||
|
|
||||||
|
|
||||||
@njit
|
@njit
|
||||||
def to_uint8(x, y, z, voxel_id, face_id, ao_id, flip_id):
|
def pack_data(x, y, z, voxel_id, face_id, ao_id, flip_id):
|
||||||
return (uint8(x), uint8(y), uint8(z),
|
# x: 6bit, y: 6bit, z: 6bit, voxel_id: 8bit, face_id: 3bit, ao_id: 2bit, flip_id: 1bit
|
||||||
uint8(voxel_id), uint8(face_id), uint8(ao_id), uint8(flip_id)
|
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
|
@njit
|
||||||
def get_chunk_index(world_voxel_pos):
|
def get_chunk_index(world_voxel_pos):
|
||||||
|
@ -84,8 +101,7 @@ def is_void(local_voxel_pos, world_voxel_pos, world_voxels):
|
||||||
@njit
|
@njit
|
||||||
def add_data(vertex_data, index, *vertices):
|
def add_data(vertex_data, index, *vertices):
|
||||||
for vertex in vertices:
|
for vertex in vertices:
|
||||||
for attribute in vertex:
|
vertex_data[index] = vertex
|
||||||
vertex_data[index] = attribute
|
|
||||||
index += 1
|
index += 1
|
||||||
|
|
||||||
return index
|
return index
|
||||||
|
@ -93,7 +109,7 @@ def add_data(vertex_data, index, *vertices):
|
||||||
|
|
||||||
@njit
|
@njit
|
||||||
def build_chunk_mesh(chunk_voxels, format_size, chunk_pos, world_voxels):
|
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
|
index = 0
|
||||||
|
|
||||||
for x in range(CHUNK_SIZE):
|
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]
|
flip_id = ao[1] + ao[3] > ao[0] + ao[2]
|
||||||
|
|
||||||
# format: x, y, z, voxel_id, face_id, ao_id
|
# format: x, y, z, voxel_id, face_id, ao_id
|
||||||
v0 = to_uint8(x , y + 1, z , voxel_id, 0, ao[0], flip_id)
|
v0 = pack_data(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)
|
v1 = pack_data(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)
|
v2 = pack_data(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)
|
v3 = pack_data(x , y + 1, z + 1, voxel_id, 0, ao[3], flip_id)
|
||||||
|
|
||||||
if flip_id:
|
if flip_id:
|
||||||
index = add_data(vertex_data, index, v1, v0, v3, v1, v3, v2)
|
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")
|
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]
|
flip_id = ao[1] + ao[3] > ao[0] + ao[2]
|
||||||
|
|
||||||
v0 = to_uint8(x , y, z , voxel_id, 1, ao[0], flip_id)
|
v0 = pack_data(x , y, z , voxel_id, 1, ao[0], flip_id)
|
||||||
v1 = to_uint8(x + 1, y, z , voxel_id, 1, ao[1], flip_id)
|
v1 = pack_data(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)
|
v2 = pack_data(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)
|
v3 = pack_data(x , y, z + 1, voxel_id, 1, ao[3], flip_id)
|
||||||
|
|
||||||
if flip_id:
|
if flip_id:
|
||||||
index = add_data(vertex_data, index, v1, v3, v0, v1, v2, v3)
|
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")
|
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]
|
flip_id = ao[1] + ao[3] > ao[0] + ao[2]
|
||||||
|
|
||||||
v0 = to_uint8(x + 1, y , z , voxel_id, 2, ao[0], flip_id)
|
v0 = pack_data(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)
|
v1 = pack_data(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)
|
v2 = pack_data(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)
|
v3 = pack_data(x + 1, y , z + 1, voxel_id, 2, ao[3], flip_id)
|
||||||
|
|
||||||
if flip_id:
|
if flip_id:
|
||||||
index = add_data(vertex_data, index, v3, v0, v1, v3, v1, v2)
|
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")
|
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]
|
flip_id = ao[1] + ao[3] > ao[0] + ao[2]
|
||||||
|
|
||||||
v0 = to_uint8(x, y , z , voxel_id, 3, ao[0], flip_id)
|
v0 = pack_data(x, y , z , voxel_id, 3, ao[0], flip_id)
|
||||||
v1 = to_uint8(x, y + 1, z , voxel_id, 3, ao[1], flip_id)
|
v1 = pack_data(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)
|
v2 = pack_data(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)
|
v3 = pack_data(x, y , z + 1, voxel_id, 3, ao[3], flip_id)
|
||||||
|
|
||||||
if flip_id:
|
if flip_id:
|
||||||
index = add_data(vertex_data, index, v3, v1, v0, v3, v2, v1)
|
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")
|
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]
|
flip_id = ao[1] + ao[3] > ao[0] + ao[2]
|
||||||
|
|
||||||
v0 = to_uint8(x , y , z, voxel_id, 4, ao[0], flip_id)
|
v0 = pack_data(x , y , z, voxel_id, 4, ao[0], flip_id)
|
||||||
v1 = to_uint8(x , y + 1, z, voxel_id, 4, ao[1], flip_id)
|
v1 = pack_data(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)
|
v2 = pack_data(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)
|
v3 = pack_data(x + 1, y , z, voxel_id, 4, ao[3], flip_id)
|
||||||
|
|
||||||
if flip_id:
|
if flip_id:
|
||||||
index = add_data(vertex_data, index, v3, v0, v1, v3, v1, v2)
|
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")
|
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]
|
flip_id = ao[1] + ao[3] > ao[0] + ao[2]
|
||||||
|
|
||||||
v0 = to_uint8(x , y , z + 1, voxel_id, 5, ao[0], flip_id)
|
v0 = pack_data(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)
|
v1 = pack_data(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)
|
v2 = pack_data(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)
|
v3 = pack_data(x + 1, y , z + 1, voxel_id, 5, ao[3], flip_id)
|
||||||
|
|
||||||
if flip_id:
|
if flip_id:
|
||||||
index = add_data(vertex_data, index, v3, v1, v0, v3, v2, v1)
|
index = add_data(vertex_data, index, v3, v1, v0, v3, v2, v1)
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
#version 330 core
|
#version 330 core
|
||||||
|
|
||||||
layout (location = 0) in ivec3 in_position;
|
layout (location = 0) in uint packed_data;
|
||||||
layout (location = 1) in int voxel_id;
|
|
||||||
layout (location = 2) in int face_id;
|
int x, y, z;
|
||||||
layout (location = 3) in int ao_id;
|
int voxel_id;
|
||||||
layout (location = 4) in int flip_id;
|
int face_id;
|
||||||
|
int ao_id;
|
||||||
|
int flip_id;
|
||||||
|
|
||||||
uniform mat4 m_proj;
|
uniform mat4 m_proj;
|
||||||
uniform mat4 m_view;
|
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() {
|
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;
|
int uv_index = gl_VertexID % 6 + ((face_id & 1) + flip_id * 2) * 6;
|
||||||
|
|
||||||
uv = uv_coords[uv_indices[uv_index]];
|
uv = uv_coords[uv_indices[uv_index]];
|
||||||
voxel_color = hash31(voxel_id);
|
voxel_color = hash31(voxel_id);
|
||||||
shading = face_shading[face_id] * ao_values[ao_id];
|
shading = face_shading[face_id] * ao_values[ao_id];
|
||||||
|
|
Loading…
Reference in a new issue