When i create a 100 x 100 chunk of cubes in bevy it is only able to maintain like 10 fps.
Even if i replace the cubes with something more simple like planes i dont get any better performance out of it.
I benchmarked it with mangohud and it says, that my cpu and gpu are only sitting at about 20% usage.
Here is the code I use to generate a 32 x 32 chunk with OpenSimplex noise
commands: &mut Commands, mut meshes: ResMut<Assets<Mesh>>, mut materials: ResMut<Assets<StandardMaterial>>, asset_server: Res<AssetServer>, seed: Res<Seed>, ) { let noise = OpenSimplex::new(); commands .spawn(PbrBundle { mesh: meshes.add(Mesh::from(shape::Plane{ size: 1.0 })), material: materials.add(Color::rgb(0.5, 0.5, 1.0).into()), transform: Transform::from_translation(Vec3::new(0.0, 0.0, 0.0)), ..Default::default() }) .with(Chunk) .with_children(|parent| { let texture_handle = asset_server.load("textures/dirt.png"); for x in -32 .. 32 { for z in -32 .. 32 { let y = (noise.get([ ( x as f32 / 20. ) as f64, ( z as f32 / 20. ) as f64, seed.value, ]) * 15. + 16.0) as u32; parent .spawn(PbrBundle { mesh: meshes.add(Mesh::from(shape::Cube{ size: 1.0 })), material: materials.add(StandardMaterial { albedo: Color::rgba(1.0, 1.0, 1.0, 1.0), albedo_texture: Some(texture_handle.clone()), ..Default::default() }), transform: Transform::from_translation(Vec3::new(x as f32, y as f32, z as f32)), ..Default::default() }) .with(Cube); } } }); } But 32 x 32 is the absolute maximum for a playable experience. What do I have to do, to be able to draw multiple chunks at the same time?
System specs:
cpu: Intel Core i7-6820HQ CPU @ 2.70GHz
igpu:Intel HD Graphics 530
dgpu: Nvidia Quadro M2000M
But when offloading to the more powerfull dgpu I dont get any better performance.
12 Answers
Some optimizations that are immediately visible:
- Convert your nested
for-loopalgorithm into a singlefor-loop.- It's more cache friendly.
- Use math to split the now-single index into x/y/z values to determine position.
- Hidden surface removal.
- During mesh creation, instead of creating a whole new cube to add to the mesh (6 faces, 12 triangles, 24 verts) only add the faces (2 triangles) to the mesh that are actually visible. I.e. those that do not have a neighboring opaque (not air) block in that direction.
- Use Indexed drawing instead of Vertex-based
- Use a TextureAtlas.
- Use one big texture for every every cube instead of a single texture per cube.
It is actually the engines fault, but it will improve with the 0.5.0 release.
1