BabylonJS/Babylon.js · critical · Error

Missing codebook in SOG version 2 sh0 data.

Error message

Missing codebook in SOG version 2 sh0 data.

What it means

For SOG version 2, base colors (SH0) are stored as palette indices into data.sh0.codebook; the decoder maps each byte through the codebook before applying the SH_C0 basis. This error means meta.json declares version 2 but the sh0 entry has no codebook, so color bytes cannot be decoded. The library throws instead of rendering wrong colors.

Source

Thrown at packages/dev/loaders/src/SPLAT/sog.pure.ts:217

            throw new Error("Missing arrays in SOG scales data.");
        }

        for (let i = 0; i < splatCount; i++) {
            const index = i * 4;
            for (let j = 0; j < 3; j++) {
                const sc = scales[index + j];
                const lsc = Scalar.Lerp(data.scales.mins[j], data.scales.maxs[j], sc / 255);
                const lsce = Math.exp(lsc);
                scale[i * 8 + 3 + j] = lsce;
            }
        }
    }

    // --- Colors/SH0
    const colors = imageDataArrays[4].bits;
    if (data.version === 2) {
        if (!data.sh0.codebook) {
            throw new Error("Missing codebook in SOG version 2 sh0 data.");
        }
        for (let i = 0; i < splatCount; i++) {
            const index = i * 4;
            for (let j = 0; j < 3; j++) {
                const component = 0.5 + data.sh0.codebook[colors[index + j]] * SH_C0;
                rgba[i * 32 + 24 + j] = Math.max(0, Math.min(255, Math.round(255 * component)));
            }
            rgba[i * 32 + 24 + 3] = colors[index + 3];
        }
    } else {
        if (!Array.isArray(data.sh0.mins) || !Array.isArray(data.sh0.maxs)) {
            throw new Error("Missing arrays in SOG sh0 data.");
        }
        for (let i = 0; i < splatCount; i++) {
            const index = i * 4;
            for (let j = 0; j < 4; j++) {
                const colorsMin = data.sh0.mins[j];
                const colorsMax = data.sh0.maxs[j];

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Regenerate meta.json with a proper SOG v2 encoder so sh0.codebook (256 entries) is present.
  2. If the asset is actually v1, set version to 1/omit it so the mins/maxs path decodes sh0.
  3. Pre-validate: if version === 2, require Array.isArray(data.sh0.codebook) before parsing.

Example fix

// before
"sh0": { "shape": [100000, 4], "dtype": "uint8", "files": ["sh0.webp"] }
// after
"sh0": { "shape": [100000, 4], "dtype": "uint8", "files": ["sh0.webp"], "codebook": [-0.53, -0.51, ...] }
Defensive patterns

Strategy: validation

Validate before calling

function validateV2Sh0(meta) {
  if (meta.version === 2 && !Array.isArray(meta.sh0?.codebook)) {
    throw new Error('v2 SOG asset: meta.sh0.codebook is required');
  }
}

Type guard

function hasSh0Codebook(meta) {
  return meta.version !== 2 || Array.isArray(meta.sh0?.codebook);
}

Try / catch

try {
  await ParseSogMeta(metaOrFiles, rootUrl, scene);
} catch (e) {
  if (e.message.includes('sh0')) {
    // sh0 codebook missing: re-export asset or correct the version field
  }
  throw e;
}

Prevention

When it happens

Trigger: ParseSogMeta with meta.json where version: 2 and data.sh0 has no codebook array — e.g. meta.json generated by a v1 encoder, hand-edited, or the sh0 codebook omitted during metadata transformation.

Common situations: Version mismatch between meta.json and the asset generator; converting assets between SOG versions with a script that drops codebook fields; third-party SOG files that claim v2 but follow v1 metadata layout.

Related errors


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