BabylonJS/Babylon.js · error

Unsupported pixel format!

Error message

Unsupported pixel format!

What it means

ConvertPixelArrayToFloat32 converts texture pixel data into a Float32Array when converting specular/glossiness materials to metallic/roughness. It supports Uint8Array (normalized by /255) and Float32Array passthrough; any other pixel array type cannot be handled and triggers this throw.

Source

Thrown at packages/dev/serializers/src/glTF/2.0/glTFMaterialExporter.ts:163

    }

    const rawTexture = RawTexture.CreateRGBATexture(data, width, height, scene);

    return rawTexture;
}

function ConvertPixelArrayToFloat32(pixels: ArrayBufferView): Float32Array {
    if (pixels instanceof Uint8Array) {
        const length = pixels.length;
        const buffer = new Float32Array(pixels.length);
        for (let i = 0; i < length; ++i) {
            buffer[i] = pixels[i] / 255;
        }
        return buffer;
    } else if (pixels instanceof Float32Array) {
        return pixels;
    } else {
        throw new Error("Unsupported pixel format!");
    }
}

/**
 * Utility methods for working with glTF material conversion properties.
 * @internal
 */
export class GLTFMaterialExporter {
    // Mapping to store textures
    private _textureMap = new Map<number, ITextureInfo>();

    // Mapping of internal textures to images to avoid exporting duplicate images
    private _internalTextureToImage: { [uniqueId: number]: { [mimeType: string]: Promise<number> } } = {};

    constructor(private readonly _exporter: GLTFExporter) {}

    public getTextureInfo(babylonTexture: Nullable<BaseTexture>): Nullable<ITextureInfo> {
        return babylonTexture ? (this._textureMap.get(babylonTexture.uniqueId) ?? null) : null;

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Convert the pixel data to Uint8Array or Float32Array before export (e.g. new Uint8Array(pixels.buffer) if raw bytes are 8-bit, or normalize into a Float32Array)
  2. Re-encode the texture source as standard 8-bit RGBA so the loader yields Uint8Array data
  3. Avoid converting specular/glossiness materials: assign a PBRMetallicRoughness material before export
  4. Catch the error and export with the original material unconverted if the target glTF allows it

Example fix

// before
const tex = texture.readPixels(); // Uint16Array -> throws
// after
const pixels = texture.readPixels();
const floatPixels = new Float32Array(pixels.length);
for (let i = 0; i < pixels.length; i++) floatPixels[i] = pixels[i] / 65535; // normalize to Float32Array
Defensive patterns

Strategy: type-guard

Validate before calling

function pixelsAreExportable(pixels: unknown): pixels is Uint8Array | Float32Array {
    return pixels instanceof Uint8Array || pixels instanceof Float32Array;
}

Type guard

const isUint8OrFloat32 = (p: unknown): p is Uint8Array | Float32Array =>
    p instanceof Uint8Array || p instanceof Float32Array;

Try / catch

try {
    await GLTF2Export.GLTFAsync(scene, "scene");
} catch (e) {
    if (e instanceof Error && e.message === "Unsupported pixel format!") {
        // re-encode offending textures as 8-bit RGBA and retry
    } else { throw e; }
}

Prevention

When it happens

Trigger: Exporting a scene with a KHR_materials_pbrSpecularGlossiness conversion where a texture's pixel data is neither Uint8Array nor Float32Array — e.g. pixel data read back as Uint16Array, Int32Array, or a half-float typed array from a nonstandard texture source.

Common situations: Exporting scenes with HDR/16-bit textures (e.g. RGBA16F readback producing Uint16Array), textures from custom loading pipelines that return exotic typed arrays, or KTX/Basis decoded frames whose arrays are not Uint8/Float32.

Related errors


AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30). Data as JSON: /api/errors/385f0380e0e35688. Report an issue: GitHub.