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

  1. Ensure the terrain's height map texture is at least 3x3 pixels before the scene is built or aabb/debug_draw/select is called.
  2. Check that the height map resource path is correct and loads successfully (no fallback to a default small texture).
  3. Regenerate or replace the height map if it was saved corrupted.
  4. 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

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


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)