Exported glb reduces the texture resolution

Hi BabylonJS forumers. Thank you for creating such an incredible platform and community!

I am having a challenges with exporting a glb and maintaining the original texture resolution.

My glb has a texture of 12288 x 12288. When I load to glb.babylonpress.org and exporta WebP version, the texture is always downsized to 5760.

Is there any way that I can control this and keep the maximum resolution?

I look forward to hearing from someone shortly. Many thanks!!

Hello and welcome!

glb.babylonpress.org is my creation :slight_smile:

Could you share your model to check what is happening?
Do you have the same problems if transform your model at https://gltf.report/ ?

Hi Labris - thank you very much for your kind reply. It’s happening with all my glbs that have a 12288x12288 texture.

When I export from gltf.report, though, it keeps the high resolution. However, the texture isn’t converting to WebP in gltf.report - it’s staying as a jpeg texture.

I will have a look, probably there is some browser limitation for conversion.
Meahwhile you may do the same transforms in Node.js environment wiith the help of GLTF-Transform CLI which doesn’t depend on browser, may use lossless codec and shouldn’t have such limitations.
Also, be aware that such big textures may lead to crash on non-high-end machines.

I wasn’t able to reproduce this issue with PNG texture 12188x8122 resolution at https://glb.babylonpress.org/ - after optimization I have the same width and height of WEBP texture. How do you export your GLB from there - is it the main export button at the bottom menu bar or Inspector export button?

But I was able to reproduce this issue when exporting from Sandbox with the help of Inspector. In this case the texture becomes 7055x4702.
@alexchuber , what do you think about it?

Here is my test file - Babylon.js Playground
To reproduce the Sandbox issue, open the Inspector

and export GLB.
Texture will lose some resolution when you check the exported file in the Sandbox.

I am away right now, so I can’t double check this, but it might be because we use the default quality level (something like 1/2? 127/255?) when re-encoding the image. Check the parameters of ‘DumpData()’ for more info.

1 Like

Here is the small test plane mesh with 12188*12188 texture resolution - Babylon.js Sandbox - View glTF, glb, obj and babylon files

When exported from the Inspector, it reduces to 5760x5760.
Still, when exporting after conversion to WEBP at https://glb.babylonpress.org/, it has the same dimensions 12188x12188.
@Christopher_East Did you solve your issue or there are any other related questions?

Let me assign to @alexchuber if not urgent so she can have a look when she ll be back next Monday as it sounds like a potential bug. I can have a look if it is urgent.

I don’t think it is urgent since it exists at least from Babylon 5 :slight_smile:
Still it is strange behavior which a user shouldn’t experience with default settings.

1 Like

The only real one :slight_smile:

1 Like

This looks like a hardware limitation related to the offscreen canvas used in DumpData. Even though we set the canvas size to 12188×12188, the actual gl.drawingBufferWidth is being limited to 5760×5760.

From the WebGL spec:

If the requested width or height cannot be satisfied, either when the drawing buffer is first created or when the width and height attributes of the HTMLCanvasElement or OffscreenCanvas are changed, a drawing buffer with smaller dimensions shall be created. The dimensions actually used are implementation dependent and there is no guarantee that a buffer with the same aspect ratio will be created. The actual drawing buffer size can be obtained from the drawingBufferWidth and drawingBufferHeight attributes.

So when exporting via the Sandbox Inspector, the texture gets resized to fit within some hardware limits, which explains the unexpected dimensions.

Now I’m curious, though – @labris how are you converting images to WebP in your app?

Texture resizing and format conversion in https://glb.babylonpress.org/ is performed at array level (without any offscreen canvas) and based on GLTF-Transform compressTexture function.

Which, in turn, uses ndarray - npm and some of it’s functions.

1 Like

The actual underlying lib used for image r/w is ndarray-pixels, which uses sharp for node.js, and OffscreenCanvas for browsers.

ImageDecoder might worth a try since it does not define a size limit in spec.


          // Create an ImageDecoder instance.
          const decoder = new ImageDecoder({
            data: file.stream(),
            type: file.type,
          });

          // Make sure decoder tracks are ready.
          await decoder.tracks.ready;

          // Decode the first available image frame.
          const frame = (await decoder.decode()).image;

          // Set canvas dimensions based on the decoded image.
          canvas.width = frame.displayWidth;
          canvas.height = frame.displayHeight;

          // Prepare an output buffer.
          const pixelCount = frame.displayWidth * frame.displayHeight;
          // RGBA pixels: each pixel uses 4 bytes.
          const outputBuffer = new Uint8ClampedArray(pixelCount * 4);

          // Use the copyTo() method to copy the frame's pixels into our output buffer.
          // We specify the desired pixel format ("RGBA").
          await frame.copyTo(outputBuffer, { format: "RGBA" });
1 Like

Nice catch!
Anyway, the issue seems to be related to Babylon implementation only.