{"record":{"id":"ddc64f890ed01ee4","repo":"BabylonJS/Babylon.js","slug":"sog-texture-contains-splattexelcount-texels-bu","errorCode":null,"errorMessage":"SOG texture contains ${splatTexelCount} texels, but metadata references ${splatCount} splats.","messagePattern":"SOG texture contains (.+?) texels, but metadata references (.+?) splats\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"packages/dev/loaders/src/SPLAT/sog.pure.ts","lineNumber":602,"sourceCode":"        gpuTextures = gpu;\r\n        meansL = CreateSogTextureFromImage(scene, images[0]);\r\n        meansU = CreateSogTextureFromImage(scene, images[1]);\r\n        meansWidth = images[0].width;\r\n        meansHeight = images[0].height;\r\n    } else {\r\n        const [meansTex, gpu] = await Promise.all([Promise.all(data.means.files.map(loadGpuTextureAsync)), Promise.all(gpuFiles.map(loadGpuTextureAsync))]);\r\n        gpuTextures = gpu;\r\n        meansL = meansTex[0];\r\n        meansU = meansTex[1];\r\n        const size = (meansL as Texture).getSize();\r\n        meansWidth = size.width;\r\n        meansHeight = size.height;\r\n    }\r\n\r\n    const splatCount = data.count ?? data.means.shape[0];\r\n    const splatTexelCount = meansWidth * meansHeight;\r\n    if (splatTexelCount < splatCount) {\r\n        throw new Error(`SOG texture contains ${splatTexelCount} texels, but metadata references ${splatCount} splats.`);\r\n    }\r\n\r\n    const scales = gpuTextures[0];\r\n    const quats = gpuTextures[1];\r\n    const sh0 = gpuTextures[2];\r\n\r\n    let shCentroids: RawTexture | undefined;\r\n    let shLabels: RawTexture | undefined;\r\n    let shCoeffCount = 0;\r\n    let shDegree = 0;\r\n\r\n    if (data.shN && gpuTextures.length >= 5) {\r\n        shCentroids = gpuTextures[3];\r\n        shLabels = gpuTextures[4];\r\n\r\n        shCoeffCount = data.shN.bands ? (data.shN.bands + 1) ** 2 - 1 : data.shN.shape[1] / 3;\r\n        shDegree = data.shN.bands ?? Math.round(Math.sqrt(shCoeffCount + 1) - 1);\r\n    }\r","sourceCodeStart":584,"sourceCodeEnd":620,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/loaders/src/SPLAT/sog.pure.ts#L584-L620","documentation":"ParseSogMetaAsTextures validates that the decoded means texture has at least as many texels (width * height) as the splat count declared in metadata (data.count or means.shape[0]). This error means the means_l webp image is too small for the declared splat count, so splats beyond the texel capacity would read undefined data. The message includes both numbers to aid diagnosis.","triggerScenarios":"Loading a SOG bundle where meta.json's count/means.shape[0] exceeds meansWidth*meansHeight — typically a meta.json from a different asset paired with mismatched means webp images, an encoder that wrote a wrong shape/count, or the means image being replaced/downscaled by an image pipeline.","commonSituations":"Mixing files from two SOG assets during manual re-bundling; CDN/asset optimization re-encoding or resizing the webp images; hand-edited meta.json with an incorrect count; partial uploads pairing an old meta.json with new images.","solutions":["Ensure all SOG files come from the same export: re-download/re-extract the complete bundle so meta.json matches the means images.","Fix data.count (or means.shape[0]) in meta.json so it is <= meansWidth * meansHeight of the actual means_l image.","Re-export the asset with the SOG encoder so means image dimensions match the splat count.","Verify the asset pipeline does not re-encode/resize the webp data images."],"exampleFix":"// before (meta.json references 250000 splats but image is 512x256 = 131072 texels)\n\"count\": 250000\n// after (match count to the actual means texture capacity, or re-export)\n\"count\": 131072","handlingStrategy":"validation","validationCode":"function validateSplatCapacity(meta, meansImage) {\n  const splatCount = meta.count ?? meta.means.shape[0];\n  const texels = meansImage.width * meansImage.height;\n  if (texels < splatCount) {\n    throw new Error(`means texture has ${texels} texels but meta declares ${splatCount} splats`);\n  }\n}","typeGuard":"function hasSufficientMeansCapacity(meta, meansImage) {\n  const splatCount = meta.count ?? meta.means.shape[0];\n  return meansImage.width * meansImage.height >= splatCount;\n}","tryCatchPattern":"try {\n  return await ParseSogMetaAsTextures(metaOrFiles, rootUrl, scene);\n} catch (e) {\n  if (e.message.startsWith('SOG texture contains')) {\n    // meta.json and means image are from different assets or the image was resized:\n    // re-download the complete bundle or fix count/shape in meta.json\n  }\n  throw e;\n}","preventionTips":["Never serve SOG webp data images through re-encoding/resizing image CDNs — they are raw data.","Verify splatCount (count ?? means.shape[0]) fits within the means image dimensions during asset QA.","Keep meta.json and images from one export together via a manifest/hash; never mix bundles.","Log image dimensions alongside splat count when SOG loading fails for easier diagnosis."],"tags":["sog","gaussian-splatting","metadata","dimension-mismatch","asset-validation"],"backgroundTag":"texture-size-mismatch","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-30T18:17:15.746Z"}