Compare commits

..

2 commits

3 changed files with 83 additions and 39 deletions

View file

@ -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):

View file

@ -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)

View file

@ -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];