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:
Claude committed 2026-11-04 23:55:03 +00:00
1 parent 83ad384f48
commit ce86945277
1 file changed
+17 -4
+17 -4
View File
@@ -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 = [