Don't skip generation of some chunks

This commit is contained in:
Jarrod Doyle 2023-05-06 12:42:47 +01:00
parent ed46752c92
commit 95dd469f7a
Signed by: Jayrude
GPG Key ID: 38B57B16E7C0ADF7
1 changed files with 86 additions and 90 deletions

View File

@ -161,102 +161,98 @@ impl BrickmapManager {
let chunk_y = data[i * 4 + 1]; let chunk_y = data[i * 4 + 1];
let chunk_z = data[i * 4 + 2]; let chunk_z = data[i * 4 + 2];
// Generate full data
let mut chunk = [(false, 0u32); 512];
for z in 0..8 {
for y in 0..8 {
for x in 0..8 {
let idx = (x + y * 8 + z * 8 * 8) as usize;
// Just checks if the point is in the sphere
let pos = glam::vec3(x as f32, y as f32, z as f32);
if (pos - sphere_center).length_squared() <= sphere_r2 {
// Pack the local position as a colour
let mut albedo = 0u32;
albedo += ((x + 1) * 32 - 1) << 24;
albedo += ((y + 1) * 32 - 1) << 16;
albedo += ((z + 1) * 32 - 1) << 8;
albedo += 255;
chunk[idx] = (true, albedo);
}
}
}
}
// Cull interior voxels
let mut bitmask_data = [0xFFFFFFFF as u32; 16];
let mut albedo_data = Vec::<u32>::new();
for z in 0..8 {
// Each z level contains two bitmask segments of voxels
let mut entry = 0u64;
for y in 0..8 {
for x in 0..8 {
// Ignore non-solids
let idx = x + y * 8 + z * 8 * 8;
if !chunk[idx].0 {
continue;
}
// A voxel is on the surface if at least one of it's
// cardinal neighbours is non-solid. Also for simplicity if
// it's on the edge of the chunk
let surface_voxel: bool;
if x == 0 || x == 7 || y == 0 || y == 7 || z == 0 || z == 7 {
surface_voxel = true;
} else {
surface_voxel = !(chunk[idx + 1].0
&& chunk[idx - 1].0
&& chunk[idx + 8].0
&& chunk[idx - 8].0
&& chunk[idx + 64].0
&& chunk[idx - 64].0);
}
// Set the appropriate bit in the z entry and add the shading
// data
if surface_voxel {
entry += 1 << (x + y * 8);
albedo_data.push(chunk[idx].1);
}
}
}
let offset = 2 * z as usize;
bitmask_data[offset] = (entry & 0xFFFFFFFF).try_into().unwrap();
bitmask_data[offset + 1] = ((entry >> 32) & 0xFFFFFFFF).try_into().unwrap();
}
let chunk_idx = (chunk_x let chunk_idx = (chunk_x
+ chunk_y * world_dims[0] + chunk_y * world_dims[0]
+ chunk_z * world_dims[0] * world_dims[1]) as usize; + chunk_z * world_dims[0] * world_dims[1]) as usize;
if chunk_idx % 3 == 0 || chunk_idx % 5 == 0 || chunk_idx % 7 == 0 {
self.update_brickgrid_element(context, chunk_idx, 0)
} else {
// Generate full data
let mut chunk = [(false, 0u32); 512];
for z in 0..8 {
for y in 0..8 {
for x in 0..8 {
let idx = (x + y * 8 + z * 8 * 8) as usize;
// Just checks if the point is in the sphere // Update the brickgrid index
let pos = glam::vec3(x as f32, y as f32, z as f32); let brickgrid_element = ((self.brickmap_cache_idx as u32) << 8) + 4;
if (pos - sphere_center).length_squared() <= sphere_r2 { self.update_brickgrid_element(context, chunk_idx, brickgrid_element);
// Pack the local position as a colour
let mut albedo = 0u32;
albedo += ((x + 1) * 32 - 1) << 24;
albedo += ((y + 1) * 32 - 1) << 16;
albedo += ((z + 1) * 32 - 1) << 8;
albedo += 255;
chunk[idx] = (true, albedo);
}
}
}
}
// Cull interior voxels // Update the shading table
let mut bitmask_data = [0xFFFFFFFF as u32; 16]; let shading_idx = self
let mut albedo_data = Vec::<u32>::new(); .shading_table_allocator
for z in 0..8 { .try_alloc(albedo_data.len() as u32)
// Each z level contains two bitmask segments of voxels .unwrap() as usize;
let mut entry = 0u64; context.queue.write_buffer(
for y in 0..8 { &self.shading_table_buffer,
for x in 0..8 { (shading_idx * 4) as u64,
// Ignore non-solids bytemuck::cast_slice(&albedo_data),
let idx = x + y * 8 + z * 8 * 8; );
if !chunk[idx].0 {
continue;
}
// A voxel is on the surface if at least one of it's // Update the brickmap
// cardinal neighbours is non-solid. Also for simplicity if self.brickmap_cache[self.brickmap_cache_idx].bitmask = bitmask_data;
// it's on the edge of the chunk self.brickmap_cache[self.brickmap_cache_idx].shading_table_offset = shading_idx as u32;
let surface_voxel: bool; context.queue.write_buffer(
if x == 0 || x == 7 || y == 0 || y == 7 || z == 0 || z == 7 { &self.brickmap_buffer,
surface_voxel = true; (72 * self.brickmap_cache_idx) as u64,
} else { bytemuck::cast_slice(&[self.brickmap_cache[self.brickmap_cache_idx]]),
surface_voxel = !(chunk[idx + 1].0 );
&& chunk[idx - 1].0 self.brickmap_cache_idx += 1;
&& chunk[idx + 8].0
&& chunk[idx - 8].0
&& chunk[idx + 64].0
&& chunk[idx - 64].0);
}
// Set the appropriate bit in the z entry and add the shading
// data
if surface_voxel {
entry += 1 << (x + y * 8);
albedo_data.push(chunk[idx].1);
}
}
}
let offset = 2 * z as usize;
bitmask_data[offset] = (entry & 0xFFFFFFFF).try_into().unwrap();
bitmask_data[offset + 1] = ((entry >> 32) & 0xFFFFFFFF).try_into().unwrap();
}
// Update the brickgrid index
let brickgrid_element = ((self.brickmap_cache_idx as u32) << 8) + 4;
self.update_brickgrid_element(context, chunk_idx, brickgrid_element);
// Update the shading table
let shading_idx = self
.shading_table_allocator
.try_alloc(albedo_data.len() as u32)
.unwrap() as usize;
context.queue.write_buffer(
&self.shading_table_buffer,
(shading_idx * 4) as u64,
bytemuck::cast_slice(&albedo_data),
);
// Update the brickmap
self.brickmap_cache[self.brickmap_cache_idx].bitmask = bitmask_data;
self.brickmap_cache[self.brickmap_cache_idx].shading_table_offset =
shading_idx as u32;
context.queue.write_buffer(
&self.brickmap_buffer,
(72 * self.brickmap_cache_idx) as u64,
bytemuck::cast_slice(&[self.brickmap_cache[self.brickmap_cache_idx]]),
);
self.brickmap_cache_idx += 1;
}
} }
// Reset the request count on the gpu buffer // Reset the request count on the gpu buffer