BabylonJS/Babylon.js · error
Texture layers are not supported in Babylon Native
Error message
Texture layers are not supported in Babylon Native
What it means
This createRawTexture-family entry point in ThinNativeEngine rejects any request with a layers count greater than 0, because Babylon Native's bgfx backend does not support texture arrays/layers here. Layered textures must be avoided in this engine.
Source
Thrown at packages/dev/core/src/Engines/thinNativeEngine.pure.ts:2387
if (type === Constants.TEXTURETYPE_FLOAT && !this._caps.textureFloatLinearFiltering) {
// if floating point linear (gl.FLOAT) then force to NEAREST_SAMPLINGMODE
samplingMode = Constants.TEXTURE_NEAREST_SAMPLINGMODE;
} else if (type === Constants.TEXTURETYPE_HALF_FLOAT && !this._caps.textureHalfFloatLinearFiltering) {
// if floating point linear (HALF_FLOAT) then force to NEAREST_SAMPLINGMODE
samplingMode = Constants.TEXTURE_NEAREST_SAMPLINGMODE;
}
if (type === Constants.TEXTURETYPE_FLOAT && !this._caps.textureFloat) {
type = Constants.TEXTURETYPE_UNSIGNED_BYTE;
Logger.Warn("Float textures are not supported. Type forced to TEXTURETYPE_UNSIGNED_BYTE");
}
const texture = new InternalTexture(this, source);
const width = (<{ width: number; height: number; layers?: number }>size).width ?? <number>size;
const height = (<{ width: number; height: number; layers?: number }>size).height ?? <number>size;
const layers = (<{ width: number; height: number; layers?: number }>size).layers || 0;
if (layers !== 0) {
throw new Error("Texture layers are not supported in Babylon Native");
}
const nativeTexture = texture._hardwareTexture!.underlyingResource;
const nativeTextureFormat = getNativeTextureFormat(format, type);
// TODO(bgfx-msaa-mips): stopgap workaround for a bgfx bug -- D3D11/D3D12/Vulkan backends share one
// texture descriptor between the MSAA render target and the non-MSAA resolve target, so requesting
// both mips > 1 and samples > 1 makes the API (D3D11 E_INVALIDARG, Vulkan VUID-02257, ...) reject the
// MSAA texture creation. Force hasMips = false here to keep the combo from reaching bgfx. The fix
// belongs in bgfx (separate descs per target, like OpenGL/WebGL do with a non-mipped renderbuffer);
// this guard should be removed once a fixed bgfx ships in a stable BabylonNative npm release. Tracked
// in BabylonNative#1714. Cost: MSAA RTs on Native lose post-resolve auto-mipgen and diverge from
// WebGL/WebGPU semantics -- texture.generateMipMaps stays true on the InternalTexture but the
// underlying bgfx resource has 1 mip.
const hasMips = samples > 1 ? false : generateMipMaps;
// REVIEW: We are always setting the renderTarget flag as we don't know whether the texture will be used as a render target.
this._engine.initializeTexture(nativeTexture, width, height, hasMips, nativeTextureFormat, true, useSRGBBuffer, samples);
this._setTextureSampling(nativeTexture, getNativeSamplingMode(samplingMode));
View on GitHub (pinned to 0592b347b8)
Solutions
- Flatten the texture array into an atlas and adjust UVs.
- Create one raw texture per layer and index them in the shader.
- Use a 3D texture alternative only if the engine's native path supports it; otherwise restructure the material.
Example fix
// before
engine.createRawTexture(data, { width: 256, height: 256, layers: 4 }, format, ...);
// after
for (let i = 0; i < 4; i++)
engine.createRawTexture(layerData[i], 256, 256, format, ...); Defensive patterns
Strategy: validation
Validate before calling
const layers = (typeof size === "object" ? size.layers : 0) ?? 0;
if (layers !== 0) throw new Error("Babylon Native: flatten or split texture arrays before createRawTexture."); Type guard
const isNonLayeredSize = (size: number | { width: number; height: number; layers?: number }): boolean =>
typeof size === "number" || !size.layers; Try / catch
try {
tex = engine.createRawTexture(data, size, format, sampling);
} catch (e) {
if (e.message.includes("Texture layers are not supported")) {
tex = createAtlasFromLayers(data, size); // fallback: atlas or per-layer textures
} else throw e;
} Prevention
- Avoid .ktx2/.dds texture arrays in Native-targeted assets; use atlases.
- Assert layers === 0 in your texture factory before calling the engine.
- Document that texture arrays are unsupported on Babylon Native for the whole team.
When it happens
Trigger: Calling createRawTexture (or similar size-object API) with size = { width, height, layers: N } where N !== 0, or passing the layer count through a scene loader that emits array textures.
Common situations: Assets authored as 2D texture arrays (e.g. .ktx arrays) or terrain/splatting systems using layer textures being run under Babylon Native.
Related errors
- updateWrappedNativeTexture: wrapped texture is part of a mul
- updateWrappedNativeTexture: wrapped texture's render-target
- updateWrappedWebGLTexture: wrapped texture is part of a mult
- Loading textures from IInternalTextureLoader not yet impleme
- Could not load a native texture.
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/f9cea9530c95d21b.
Report an issue: GitHub.