Voxel Chunk mesh rendering #5277
-
I'm having issues with my voxel chunk meshes, it looks like parts of a chunk's mesh are being rendered in front of other parts of the chunk when the parts being rendered in front are actually behind other parts relative to the camera. I'm not sure how to fix it, and I wasn't sure if it was something with my code or with bevy. Including mesh generation code and image of what's happening. In the image, part (a) is rendering properly, the corner in front of the dirt behind it. Part (b), the dirt is being rendered in front of the corner when it should not be. The latter is far more common, so I'd like to find a fix. //inside mesh function
let scl = 0.125;
let mut vertices: Vec<([f32; 3], [f32; 3], [f32; 4])> = Vec::new();
let mut indices: Vec<u32> = Vec::new();
for (_, made_of, x, y, z) in self.voxels_with_pos() {
if !made_of.is_visible() {
continue;
}
let wx = x * scl - self.position[0];
let wy = y * scl - self.position[1];
let wz = z * scl - self.position[2];
for (face, neighbor) in world.mesh_neighbors([x, y, z]).iter() {
if neighbor.is_some() && !neighbor.unwrap().is_solid() && neighbor.unwrap() != made_of {
let l = vertices.len() as u32;
let verts = match face {
Neighbor::Left => [
([wx, wy, wz], [-1.0, 0.0, 0.0], made_of.color().as_linear_rgba_f32()),
([wx, wy, wz + scl], [-1.0, 0.0, 0.0], made_of.color().as_linear_rgba_f32()),
([wx, wy + scl, wz + scl], [-1.0, 0.0, 0.0], made_of.color().as_linear_rgba_f32()),
([wx, wy + scl, wz], [-1.0, 0.0, 0.0], made_of.color().as_linear_rgba_f32()),
],
Neighbor::Down => [
([wx, wy, wz], [0.0, -1.0, 0.0], made_of.color().as_linear_rgba_f32()),
([wx + scl, wy, wz], [0.0, -1.0, 0.0], made_of.color().as_linear_rgba_f32()),
([wx + scl, wy, wz + scl], [0.0, -1.0, 0.0], made_of.color().as_linear_rgba_f32()),
([wx, wy, wz + scl], [0.0, -1.0, 0.0], made_of.color().as_linear_rgba_f32()),
],
Neighbor::Front => [
([wx + scl, wy, wz], [0.0, 0.0, -1.0], made_of.color().as_linear_rgba_f32()),
([wx, wy, wz], [0.0, 0.0, -1.0], made_of.color().as_linear_rgba_f32()),
([wx, wy + scl, wz], [0.0, 0.0, -1.0], made_of.color().as_linear_rgba_f32()),
([wx + scl, wy + scl, wz], [0.0, 0.0, -1.0], made_of.color().as_linear_rgba_f32()),
],
Neighbor::Right => [
([wx + scl, wy + scl, wz], [1.0, 0.0, 0.0], made_of.color().as_linear_rgba_f32()),
([wx + scl, wy + scl, wz + scl], [1.0, 0.0, 0.0], made_of.color().as_linear_rgba_f32()),
([wx + scl, wy, wz + scl], [1.0, 0.0, 0.0], made_of.color().as_linear_rgba_f32()),
([wx + scl, wy, wz], [1.0, 0.0, 0.0], made_of.color().as_linear_rgba_f32()),
],
Neighbor::Up => [
([wx, wy + scl, wz + scl], [0.0, 1.0, 0.0], made_of.color().as_linear_rgba_f32()),
([wx + scl, wy + scl, wz + scl], [0.0, 1.0, 0.0], made_of.color().as_linear_rgba_f32()),
([wx + scl, wy + scl, wz], [0.0, 1.0, 0.0], made_of.color().as_linear_rgba_f32()),
([wx, wy + scl, wz], [0.0, 1.0, 0.0], made_of.color().as_linear_rgba_f32()),
],
Neighbor::Back => [
([wx + scl, wy + scl, wz + scl], [0.0, 0.0, 1.0], made_of.color().as_linear_rgba_f32()),
([wx, wy + scl, wz + scl], [0.0, 0.0, 1.0], made_of.color().as_linear_rgba_f32()),
([wx, wy, wz + scl], [0.0, 0.0, 1.0], made_of.color().as_linear_rgba_f32()),
([wx + scl, wy, wz + scl], [0.0, 0.0, 1.0], made_of.color().as_linear_rgba_f32()),
],
};
for vert in verts {
vertices.push(vert);
}
indices.push(l);
indices.push(l + 1);
indices.push(l + 2);
indices.push(l);
indices.push(l + 2);
indices.push(l + 3);
}
}
}
if vertices.is_empty() {
return None;
}
let mut mesh = Mesh::new(PrimitiveTopology::TriangleList);
mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, vertices.iter().map(|(a, _, _)| *a).collect::<Vec<[f32; 3]>>());
mesh.insert_attribute(Mesh::ATTRIBUTE_NORMAL, vertices.iter().map(|(_, a, _)| *a).collect::<Vec<[f32; 3]>>());
mesh.insert_attribute(Mesh::ATTRIBUTE_COLOR, vertices.iter().map(|(_, _, a)| *a).collect::<Vec<[f32; 4]>>());
mesh.set_indices(Some(Indices::U32(indices)));
Some(mesh) |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
Are you using |
Beta Was this translation helpful? Give feedback.
Are you using
AlphaMode::Blend
? Trying to render opaque 3D meshes and saying they are transparent will cause this kind of breakage as the only thing that defines what is on top is draw order, which will only be defined by each mesh entity’s z distance of its local origin from the camera. Basically the position of the translation component of the entity’s transform relative to the camera.