BabylonJS/Babylon.js · error · Error

Sample2DRgbaToRef: data length (${data.length}) is less than

Error message

Sample2DRgbaToRef: data length (${data.length}) is less than required (${expectedLength}).

What it means

After validating dimensions, Sample2DRgbaToRef checks that the supplied pixel buffer holds at least widthPx*heightPx*4 elements (RGBA, 4 components per pixel). A shorter array would cause out-of-bounds reads, so it throws. This indicates the data array does not match the declared LUT size.

Source

Thrown at packages/dev/addons/src/atmosphere/sampling.ts:51

 * @param normalizeFunc - The function to normalize the texel values. Default is to divide by 255. Pass null for no normalization.
 * @returns The result color.
 */
export function Sample2DRgbaToRef<T extends IColor4Like>(
    u: number,
    v: number,
    widthPx: number,
    heightPx: number,
    data: Uint8Array | Uint16Array | Float32Array,
    result: T,
    normalizeFunc: ((value: number) => number) | null = DefaultNormalize
): T {
    if (widthPx <= 0 || heightPx <= 0) {
        throw new Error("Sample2DRgbaToRef: widthPx and heightPx must be positive.");
    }

    const expectedLength = widthPx * heightPx * 4;
    if (data.length < expectedLength) {
        throw new Error(`Sample2DRgbaToRef: data length (${data.length}) is less than required (${expectedLength}).`);
    }

    // Default to clamping behavior, but could support others.
    u = Clamp(u);
    v = Clamp(v);

    // Compute 4 nearest neighbor texels.
    const fractionalTexelX = Math.max(u * widthPx - 0.5, 0);
    const fractionalTexelY = Math.max(v * heightPx - 0.5, 0);
    const xLeft = Math.floor(fractionalTexelX);
    const xRight = Math.min(xLeft + 1, widthPx - 1);
    const yBottom = Math.floor(fractionalTexelY);
    const yTop = Math.min(yBottom + 1, heightPx - 1);

    // Sample nearest neighbor texels.
    const lowerLeftColor = TexelFetch2DRgbaToRef(xLeft, yBottom, widthPx, heightPx, data, TmpColor1, normalizeFunc);
    const upperLeftColor = TexelFetch2DRgbaToRef(xLeft, yTop, widthPx, heightPx, data, TmpColor2, normalizeFunc);
    const lowerRightColor = TexelFetch2DRgbaToRef(xRight, yBottom, widthPx, heightPx, data, TmpColor3, normalizeFunc);

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Ensure the buffer is allocated as widthPx*heightPx*4 with the same component count (RGBA) as the texture format.
  2. Re-read/regenerate the LUT data after changing resolution; never reuse a stale buffer across size changes.
  3. Pre-check `data.length >= width*height*4` at the call site and reallocate if too small.

Example fix

// before
const data = new Float32Array(lut.width * lut.height * 3); // wrong: RGB
sample.Sample2DRgbaToRef(u, v, lut.width, lut.height, data, out);
// after
const data = new Float32Array(lut.width * lut.height * 4); // RGBA
sample.Sample2DRgbaToRef(u, v, lut.width, lut.height, data, out);
Defensive patterns

Strategy: validation

Validate before calling

const required = lut.width * lut.height * 4;
if (data.length < required) {
  throw new Error(`LUT buffer too small: ${data.length} < ${required}`);
}

Type guard

function isFullLutBuffer(data: ArrayBufferView, w: number, h: number): boolean {
  return data.byteLength / (data instanceof Float32Array || data instanceof Uint16Array ? (data instanceof Float32Array ? 4 : 2) : 1) >= w * h * 4;
}

Try / catch

try {
  Sample2DRgbaToRef(u, v, w, h, data, out);
} catch (e) {
  if (String(e).includes("data length")) {
    data = new Float32Array(w * h * 4); // reallocate and re-read LUT
  } else throw e;
}

Prevention

When it happens

Trigger: Calling Sample2DRgbaToRef (or the LUT helpers using it) with a Uint8Array/Uint16Array/Float32Array shorter than widthPx*heightPx*4 — e.g. reading back a partial texture buffer, wrong texture type (RGB instead of RGBA), or mismatched width/height values.

Common situations: Downloading LUT data with the wrong format (RGB instead of RGBA), reusing a buffer from a differently sized LUT after changing transmittance/multiscattering resolution, slicing a texture readback buffer.

Related errors


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