minedmap/tile_renderer: avoid calling block_color() more often than necessary

Collect all biome indices/weights for a chunk and deduplicate using a
hash map.
This commit is contained in:
Matthias Schiffer 2023-08-03 23:02:49 +02:00
parent fb712cd2f5
commit deb33814ee
Signed by: neocturne
GPG key ID: 16EF3F64CB201D9C
3 changed files with 29 additions and 9 deletions

7
Cargo.lock generated
View file

@ -401,6 +401,7 @@ dependencies = [
"indexmap", "indexmap",
"itertools", "itertools",
"num-integer", "num-integer",
"rustc-hash",
"serde", "serde",
"serde_json", "serde_json",
"zstd", "zstd",
@ -489,6 +490,12 @@ dependencies = [
"proc-macro2", "proc-macro2",
] ]
[[package]]
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]] [[package]]
name = "rustix" name = "rustix"
version = "0.38.4" version = "0.38.4"

View file

@ -20,6 +20,7 @@ image = { version = "0.24.5", default-features = false, features = ["png"] }
indexmap = { version = "2.0.0", features = ["serde"] } indexmap = { version = "2.0.0", features = ["serde"] }
itertools = "0.11.0" itertools = "0.11.0"
num-integer = "0.1.45" num-integer = "0.1.45"
rustc-hash = "1.1.0"
serde = "1.0.152" serde = "1.0.152"
serde_json = "1.0.99" serde_json = "1.0.99"
zstd = "0.12.3" zstd = "0.12.3"

View file

@ -9,7 +9,7 @@ use num_integer::div_mod_floor;
use minedmap::{ use minedmap::{
io::{fs, storage}, io::{fs, storage},
resource::{block_color, needs_biome, Biome}, resource::{block_color, needs_biome},
types::*, types::*,
}; };
@ -44,7 +44,7 @@ fn biome_at(
block: LayerBlockCoords, block: LayerBlockCoords,
dx: i32, dx: i32,
dz: i32, dz: i32,
) -> Option<&Biome> { ) -> Option<(i8, i8, u16)> {
let (region_x, chunk_x, block_x) = coord_offset(chunk.x, block.x, dx); let (region_x, chunk_x, block_x) = coord_offset(chunk.x, block.x, dx);
let (region_z, chunk_z, block_z) = coord_offset(chunk.z, block.z, dz); let (region_z, chunk_z, block_z) = coord_offset(chunk.z, block.z, dz);
let chunk = ChunkCoords { let chunk = ChunkCoords {
@ -56,8 +56,11 @@ fn biome_at(
z: block_z, z: block_z,
}; };
let region = region_group.get(region_x, region_z)?; let region = region_group.get(region_x, region_z)?;
let index = region.chunks[chunk].as_ref()?.biomes[block]?.get() - 1; Some((
region.biome_list.get_index(index.into()) region_x,
region_z,
region.chunks[chunk].as_ref()?.biomes[block]?.get() - 1,
))
} }
pub struct TileRenderer<'a> { pub struct TileRenderer<'a> {
@ -96,8 +99,7 @@ impl<'a> TileRenderer<'a> {
return Some(block_color(block, None, depth.0 as f32)); return Some(block_color(block, None, depth.0 as f32));
} }
let mut total = 0.0; let mut weights = rustc_hash::FxHashMap::<(i8, i8, u16), f32>::default();
let mut color = Vec3::ZERO;
for dz in -Z..=Z { for dz in -Z..=Z {
for dx in -X..=X { for dx in -X..=X {
let w = SMOOTH[dz.unsigned_abs()][dx.unsigned_abs()]; let w = SMOOTH[dz.unsigned_abs()][dx.unsigned_abs()];
@ -109,15 +111,25 @@ impl<'a> TileRenderer<'a> {
continue; continue;
}; };
total += w; *weights.entry(biome).or_default() += w;
color += w * block_color(block, Some(biome), depth.0 as f32);
} }
} }
if total == 0.0 { if weights.is_empty() {
return None; return None;
} }
let mut color = Vec3::ZERO;
let mut total = 0.0;
for ((region_x, region_z, index), w) in weights {
let region = region_group.get(region_x, region_z)?;
let biome = region.biome_list.get_index(index.into())?;
total += w;
color += w * block_color(block, Some(biome), depth.0 as f32);
}
Some(color / total) Some(color / total)
} }