The WebGPU engine uses CreateTexture2DArrayFromImageUrlsAsync and the result is “Layer 0 is normal, while layers with index > 0 are blank”.
The code is located in thinWebGPUEngine.js: The third parameter is faceIndex (which is the layer in the array texture), and it is hardcoded as 0 here.
else if (texture._source === 3 /* Raw */ || texture._source === 11 /* Raw2DArray */) {
this._textureHelper.generateMipmaps(gpuHardwareTexture, texture.mipLevelCount, 0, commandEncoder);
}
CreateTexture2DArrayFromImageUrlsAsync has the default samplingMode set to TRILINEAR, and for a 512×512 size, it results in 10 levels of mip mapping:
Layer 0: Mip 0 is the one we uploaded (the generation is triggered once after all layers are uploaded), and mip 1 to 9 have also been generated → normal
Layers 1+ : Mip 1 to 9 were never generated. When creating the WebGPU texture, the texture is initialized to zero → sampling results in all zeros, alpha = 0 → mix(baseRgb, texColor.rgb, 0) retains the base color → the entire image disappears and this explains a phenomenon that should have been obvious: When the camera is moved closer and the parking space covers the entire screen, the second image suddenly appears (at this time, the sampling falls on mip 0). If the layer index itself is incorrect, there will definitely not be this “image appears only when viewing from a certain distance” behavior.
By the way, the path taken by WebGL2 is gl.generateMipmap(TEXTURE_2D_ARRAY), which by the specification will overwrite all layers, and there is no such proble
Temporary solution
export function generateAllLayerMipmaps(scene: Scene, atlas: RawTexture2DArray): number {
const engine = scene.getEngine() as unknown as {
_textureHelper?: {
generateMipmaps(hardwareTexture: unknown, mipLevelCount: number, faceIndex: number, commandEncoder?: unknown): void
}
}
const internal = (
atlas as unknown as {
_texture?: { mipLevelCount: number; _hardwareTexture?: unknown }
}
)._texture
const helper = engine._textureHelper
const hardwareTexture = internal?._hardwareTexture
const mipLevelCount = internal?.mipLevelCount ?? 1
if (!helper || !hardwareTexture || mipLevelCount <= 1) return 0
/
for (let layer = 0; layer < atlas.depth; layer++) {
helper.generateMipmaps(hardwareTexture, mipLevelCount, layer)
}
return atlas.depth
}
use
const textureArray = await CreateTexture2DArrayFromImageUrlsAsync(scene, ['img1.png',...])
console.info(textureArray.depth)
generateAllLayerMipmaps(scene, textureArray)

