BabylonJS/Babylon.js · error · Error

Unsupported pixelType ${decoder.type} for ${header.compressi

Error message

Unsupported pixelType ${decoder.type} for ${header.compression}

What it means

The decoder only supports EXR pixel types 1 (half, UINT16) and 2 (float, FLOAT32). If decoder.type ends up as 0 (UINT) or any other value, it throws because no getter can be selected for integer pixels.

Source

Thrown at packages/dev/core/src/Materials/Textures/Loaders/EXR/exrLoader.decoder.ts:228

            case EXROutputType.HalfFloat:
                decoder.getter = ParseUint16;
                decoder.inputSize = INT16_SIZE;
                break;
        }
    } else if (decoder.type === 2) {
        // float
        switch (outputType) {
            case EXROutputType.Float:
                decoder.getter = ParseFloat32;
                decoder.inputSize = FLOAT32_SIZE;
                break;

            case EXROutputType.HalfFloat:
                decoder.getter = DecodeFloat32;
                decoder.inputSize = FLOAT32_SIZE;
        }
    } else {
        throw new Error("Unsupported pixelType " + decoder.type + " for " + header.compression);
    }

    decoder.blockCount = decoder.height / decoder.scanlineBlockSize;

    for (let i = 0; i < decoder.blockCount; i++) {
        ParseInt64(dataView, offset); // scanlineOffset
    }

    // we should be passed the scanline offset table, ready to start reading pixel data.
    const size = decoder.width * decoder.height * decoder.outputChannels;

    switch (outputType) {
        case EXROutputType.Float:
            decoder.byteArray = new Float32Array(size);
            decoder.textureType = Constants.TEXTURETYPE_FLOAT;

            // Fill initially with 1s for the alpha value if the texture is not RGBA, RGB values will be overwritten
            if (fillAlpha) {

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Re-export the EXR with half (UINT16) or float (FLOAT32) pixel type instead of UINT
  2. Convert with oiiotool: `oiiotool in.exr -type half -o out.exr`
  3. Check exporter settings — disable 'integer/ID pass' output for textures meant as color data
  4. Inspect the file with exrheader to confirm channel pixel types

Example fix

// before: integer EXR (pixelType 0)
// oiiotool id.exr -o id_uint.exr
// after: convert to half float
// oiiotool id.exr -type half -o id.exr
Defensive patterns

Strategy: validation

Validate before calling

// EXR channels declare pixelType in the header; ensure exports use HALF(1)/FLOAT(2), not UINT(0)
// pipeline check: reject assets whose pixelType is 0
if (assetMeta.pixelType === 0) throw new Error("integer EXR not supported; re-export as half/float");

Type guard

function isSupportedExrPixelType(pixelType: number): boolean {
  return pixelType === 1 || pixelType === 2; // half or float, not UINT
}

Try / catch

try {
  await loader.loadAsync(file);
} catch (e) {
  if (/Unsupported pixelType/.test(String(e))) {
    return loadHalfConverted(url); // re-converted to half float
  }
  throw e;
}

Prevention

When it happens

Trigger: Raised in CreateDecoderAsync when the recognized R/G/B/A/Y channel has pixelType !== 1 and !== 2 — i.e. an EXR whose image channels are stored as 32-bit unsigned integers (pixelType 0), possibly combined with any compression code.

Common situations: ID/object-index passes and cryptomatte-style integer EXRs exported from renderers; misconfigured exporters that write UINT instead of HALF/FLOAT.

Related errors


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