mirror of
https://github.com/horizon-rust/horizon.git
synced 2026-11-07 11:06:11 -10:00
Size LabPBR maps from the texture budget
LabPBR normal and specular maps had a fixed 64 MiB budget, so with about 1300 block layers they always loaded at 64 px, however high textureBudgetMiB was set. They now get a quarter of the current budget: the default budget keeps the old 64 MiB, and 1536 MiB gives 256 px maps. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01XnU6QPo9BpqkYWfY6y5Nwu
This commit is contained in:
1 file changed
+17
-4
@@ -144,8 +144,15 @@ pub fn set_labpbr_maps(on: bool) {
|
||||
pub fn labpbr_maps() -> bool {
|
||||
LABPBR_MAPS.load(std::sync::atomic::Ordering::Relaxed)
|
||||
}
|
||||
/// Budget for either complete normal or specular image set.
|
||||
const MAX_MAP_BYTES: u64 = DEFAULT_TEXTURE_BUDGET / 4;
|
||||
/// Budget for either complete normal or specular image set: a quarter of the block textures'
|
||||
/// budget, so raising `textureBudgetMiB` sharpens a pack's LabPBR maps along with its colours.
|
||||
fn map_bytes(texture_budget: u64) -> u64 {
|
||||
texture_budget / 4
|
||||
}
|
||||
/// [`map_bytes`] for the budget the next resource load keeps to.
|
||||
fn max_map_bytes() -> u64 {
|
||||
map_bytes(TEXTURE_BUDGET.load(std::sync::atomic::Ordering::Relaxed))
|
||||
}
|
||||
/// Fewer layers than any game has (vanilla's are about 1300): what a map is kept at while
|
||||
/// loading assumes at least these many share the array.
|
||||
const LAYERS_AT_LEAST: u64 = 1024;
|
||||
@@ -275,7 +282,7 @@ impl Sprites {
|
||||
self.specular.clear();
|
||||
let largest_map = self.pbr.iter().flatten().flatten().map(|m| m.0).max();
|
||||
self.pbr_size = largest_map.map_or(SPRITE_SIZE, |l| {
|
||||
side_within(l.min(size), layers, MAX_MAP_BYTES)
|
||||
side_within(l.min(size), layers, max_map_bytes())
|
||||
});
|
||||
if largest_map.is_some() {
|
||||
let pbr_size = self.pbr_size;
|
||||
@@ -783,7 +790,7 @@ fn pbr_map(
|
||||
return None;
|
||||
}
|
||||
let side = w.max(h);
|
||||
let output_side = side_within(side, LAYERS_AT_LEAST, MAX_MAP_BYTES).min(side);
|
||||
let output_side = side_within(side, LAYERS_AT_LEAST, max_map_bytes()).min(side);
|
||||
let frames = (0..columns * rows)
|
||||
.map(|index| {
|
||||
let (x, y) = (index % columns * w, index / columns * h);
|
||||
@@ -856,6 +863,12 @@ mod tests {
|
||||
assert_eq!(side_within(512, 1300, 1), SPRITE_SIZE);
|
||||
}
|
||||
#[test]
|
||||
fn labpbr_maps_follow_the_texture_budget() {
|
||||
// 1300 layers of 1024 px maps: 64 px at the default budget, 256 px at 1536 MiB.
|
||||
assert_eq!(side_within(1024, 1300, map_bytes(DEFAULT_TEXTURE_BUDGET)), 64);
|
||||
assert_eq!(side_within(1024, 1300, map_bytes(1536 << 20)), 256);
|
||||
}
|
||||
#[test]
|
||||
fn a_labpbr_map_selects_whole_texels_and_missing_layers_get_defaults() {
|
||||
// Selecting a texel preserves encoded channels, including categorical values.
|
||||
let frame = [
|
||||
|
||||
Reference in new issue
Block a user