{"record":{"id":"f9cea9530c95d21b","repo":"BabylonJS/Babylon.js","slug":"texture-layers-are-not-supported-in-babylon-native","errorCode":null,"errorMessage":"Texture layers are not supported in Babylon Native","messagePattern":"Texture layers are not supported in Babylon Native","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/dev/core/src/Engines/thinNativeEngine.pure.ts","lineNumber":2387,"sourceCode":"        if (type === Constants.TEXTURETYPE_FLOAT && !this._caps.textureFloatLinearFiltering) {\r\n            // if floating point linear (gl.FLOAT) then force to NEAREST_SAMPLINGMODE\r\n            samplingMode = Constants.TEXTURE_NEAREST_SAMPLINGMODE;\r\n        } else if (type === Constants.TEXTURETYPE_HALF_FLOAT && !this._caps.textureHalfFloatLinearFiltering) {\r\n            // if floating point linear (HALF_FLOAT) then force to NEAREST_SAMPLINGMODE\r\n            samplingMode = Constants.TEXTURE_NEAREST_SAMPLINGMODE;\r\n        }\r\n        if (type === Constants.TEXTURETYPE_FLOAT && !this._caps.textureFloat) {\r\n            type = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n            Logger.Warn(\"Float textures are not supported. Type forced to TEXTURETYPE_UNSIGNED_BYTE\");\r\n        }\r\n\r\n        const texture = new InternalTexture(this, source);\r\n        const width = (<{ width: number; height: number; layers?: number }>size).width ?? <number>size;\r\n        const height = (<{ width: number; height: number; layers?: number }>size).height ?? <number>size;\r\n\r\n        const layers = (<{ width: number; height: number; layers?: number }>size).layers || 0;\r\n        if (layers !== 0) {\r\n            throw new Error(\"Texture layers are not supported in Babylon Native\");\r\n        }\r\n\r\n        const nativeTexture = texture._hardwareTexture!.underlyingResource;\r\n        const nativeTextureFormat = getNativeTextureFormat(format, type);\r\n        // TODO(bgfx-msaa-mips): stopgap workaround for a bgfx bug -- D3D11/D3D12/Vulkan backends share one\r\n        // texture descriptor between the MSAA render target and the non-MSAA resolve target, so requesting\r\n        // both mips > 1 and samples > 1 makes the API (D3D11 E_INVALIDARG, Vulkan VUID-02257, ...) reject the\r\n        // MSAA texture creation. Force hasMips = false here to keep the combo from reaching bgfx. The fix\r\n        // belongs in bgfx (separate descs per target, like OpenGL/WebGL do with a non-mipped renderbuffer);\r\n        // this guard should be removed once a fixed bgfx ships in a stable BabylonNative npm release. Tracked\r\n        // in BabylonNative#1714. Cost: MSAA RTs on Native lose post-resolve auto-mipgen and diverge from\r\n        // WebGL/WebGPU semantics -- texture.generateMipMaps stays true on the InternalTexture but the\r\n        // underlying bgfx resource has 1 mip.\r\n        const hasMips = samples > 1 ? false : generateMipMaps;\r\n        // REVIEW: We are always setting the renderTarget flag as we don't know whether the texture will be used as a render target.\r\n        this._engine.initializeTexture(nativeTexture, width, height, hasMips, nativeTextureFormat, true, useSRGBBuffer, samples);\r\n        this._setTextureSampling(nativeTexture, getNativeSamplingMode(samplingMode));\r\n\r","sourceCodeStart":2369,"sourceCodeEnd":2405,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/core/src/Engines/thinNativeEngine.pure.ts#L2369-L2405","documentation":"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.","triggerScenarios":"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.","commonSituations":"Assets authored as 2D texture arrays (e.g. .ktx arrays) or terrain/splatting systems using layer textures being run under Babylon Native.","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."],"exampleFix":"// before\nengine.createRawTexture(data, { width: 256, height: 256, layers: 4 }, format, ...);\n\n// after\nfor (let i = 0; i < 4; i++)\n  engine.createRawTexture(layerData[i], 256, 256, format, ...);","handlingStrategy":"validation","validationCode":"const layers = (typeof size === \"object\" ? size.layers : 0) ?? 0;\nif (layers !== 0) throw new Error(\"Babylon Native: flatten or split texture arrays before createRawTexture.\");","typeGuard":"const isNonLayeredSize = (size: number | { width: number; height: number; layers?: number }): boolean =>\n  typeof size === \"number\" || !size.layers;","tryCatchPattern":"try {\n  tex = engine.createRawTexture(data, size, format, sampling);\n} catch (e) {\n  if (e.message.includes(\"Texture layers are not supported\")) {\n    tex = createAtlasFromLayers(data, size); // fallback: atlas or per-layer textures\n  } else throw e;\n}","preventionTips":["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."],"tags":["native","texture-arrays","unsupported"],"backgroundTag":"unsupported-texture-format","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-30T18:17:15.746Z"}