FyroxEngine/Fyrox · error
Invalid Terrain height texture size
Error message
Invalid Terrain height texture size
What it means
Fyrox terrain quadtree construction logs this error when the height map (height texture) dimensions are smaller than 3x3 pixels. The quadtree AABB cannot be computed for such maps, so the default (empty) bounding box is returned instead. It is a guard against degenerate terrain height data.
Solutions
- Ensure the terrain's height map texture is at least 3x3 pixels before the scene is built or aabb/debug_draw/select is called.
- Check that the height map resource path is correct and loads successfully (no fallback to a default small texture).
- Regenerate or replace the height map if it was saved corrupted.
- Inspect Log output upstream for resource-load failures that may have produced a degenerate height map.
Example fix
// before let heightmap = TextureResource::from_bytes(&ctx, TextureKind::Rectangle(2, 2), ...)?; terrain.height_map = heightmap; // after let heightmap = TextureResource::from_bytes(&ctx, TextureKind::Rectangle(64, 64), ...)?; terrain.height_map = heightmap;
Defensive patterns
Strategy: validation
Validate before calling
let size = terrain.height_map_ref().data_size(); // or known texture dimensions assert!(size.x >= 3 && size.y >= 3, "height map must be at least 3x3 pixels");
Prevention
- Always assign height map textures >= 3x3 pixels to terrain.
- Log texture dimensions when building terrain programmatically.
- Watch the Fyrox log during scene load for earlier resource errors.
When it happens
Trigger: Calling Terrain::aabb (directly or indirectly via debug_draw or select) when the terrain's height map texture is smaller than 3 pixels in x or y.
Common situations: Loading a scene saved with a corrupted or placeholder height map; programmatically assigning a 1x1 or 2x2 texture as a terrain heightmap; a resource failing to load and falling back to a default minimal texture.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- Missing hole mask texture
- Invalid Terrain quad tree node position
- Graphics context is uninitialized!
- only rectangle textures can be used as render target!
- Graph pool must be empty on load!
AI-assisted analysis of FyroxEngine/Fyrox@76c91aad8e (2026-09-10).
Data as JSON: /api/errors/e847a347bdfed9ce.
Report an issue: GitHub.
Appendix: source
Thrown at fyrox-impl/src/scene/terrain/quadtree.rs:239
/// Construct an AABB for the node.
/// * transform: Transformation matrix to apply to the AABB just before it is returned.
/// * height_map_size: The overall size of the whole of the height map data that this node is a part of.
/// * physical_size: The size of the whole of the height map data in world units.
/// Note that the sizes of these arguments are only for the chunk of this [QuadTree].
/// Other chunks are not included since they have entirely separate height data.
pub fn aabb(
&self,
transform: &Matrix4<f32>,
height_map_size: Vector2<u32>,
physical_size: Vector2<f32>,
) -> AxisAlignedBoundingBox {
if self.size.x < 1 || self.size.y < 1 {
Log::err("Invalid Terrain quad tree node size");
return Default::default();
}
if height_map_size.x < 3 || height_map_size.y < 3 {
Log::err("Invalid Terrain height texture size");
return Default::default();
}
if self.position.x < 1 || self.position.y < 1 {
Log::err("Invalid Terrain quad tree node position");
return Default::default();
}
// Convert sizes from pixel sizes to mesh sizes.
// For calculating AABB, we do not care about the number of vertices;
// we care about the number of edges between vertices, which is one fewer.
let real_map_size = height_map_size.map(|x| x - 3);
// Nodes have no margins, but we still need to subtract one so we are measuring length, not counting vertices.
let real_node_size = self.size.map(|x| x - 1);
// Exclude the one-pixel margin when calculating the real position of this node.
let pos = self.position.map(|x| x - 1);
let min_x = (pos.x as f32 / real_map_size.x as f32) * physical_size.x;
let min_y = (pos.y as f32 / real_map_size.y as f32) * physical_size.y;
let max_x = ((pos.x + real_node_size.x) as f32 / real_map_size.x as f32) * physical_size.x;View on GitHub (pinned to 76c91aad8e)