Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] Compressed Textures fail in 9.1 #2316

Open
ibgreen opened this issue Jan 13, 2025 · 2 comments · May be fixed by #2333
Open

[Bug] Compressed Textures fail in 9.1 #2316

ibgreen opened this issue Jan 13, 2025 · 2 comments · May be fixed by #2333
Labels
Milestone

Comments

@ibgreen
Copy link
Collaborator

ibgreen commented Jan 13, 2025

Module and/or Feature

@luma.gl/webgl

Description

Compressed textures fail to load
visgl/deck.gl#9341

Expected Behavior

No response

Steps to Reproduce

visgl/deck.gl#9341

Environment

  • Framework version: 9.1
  • Browser:
  • Node:
  • OS:

Logs

No response

@ibgreen ibgreen added the bug label Jan 13, 2025
@ibgreen ibgreen changed the title [Bug] [Bug] Compressed Textures fail Jan 13, 2025
@ibgreen ibgreen added this to the v9.1 milestone Jan 13, 2025
@ibgreen ibgreen changed the title [Bug] Compressed Textures fail [Bug] Compressed Textures fail in 9.1 Jan 13, 2025
@donmccurdy
Copy link
Collaborator

A few findings:

  • In the loaders.gl textured example, calls to device.createTexture include format only in the mipmaps/images array, but not a top-level props.format value. The example has access to the GL format (integer) but may need a way to convert that to a WebGPU format (string), I think there were utilities for that in luma 9.0 but I'm not sure about 9.1.
  • In luma.gl's texture.ts we may need some adjustment to upload mipmaps:
    • /** Initialize texture with supplied props */
      // eslint-disable-next-line max-statements
      _initializeData(data: TextureProps['data']): void {
      // Store opts for accessors
      if (this.device.isExternalImage(data)) {
      this.copyExternalImage({
      image: data,
      width: this.width,
      height: this.height,
      depth: this.depth,
      mipLevel: 0,
      x: 0,
      y: 0,
      z: 0,
      aspect: 'all',
      colorSpace: 'srgb',
      premultipliedAlpha: false,
      flipY: false
      });
      } else if (data) {
      this.copyImageData({
      data,
      // width: this.width,
      // height: this.height,
      // depth: this.depth,
      mipLevel: 0,
      x: 0,
      y: 0,
      z: 0,
      aspect: 'all'
      });
      }
      }
  • In luma.gl's webgl-texture-table.ts it looks like getTextureFormatWebGL is returning the format corresponding to uncompressed data, whereas we need values like ext.COMPRESSED_RGBA_ASTC_4x4_KHR for calls to compressedTexSubImage2D(...).
    • export function getTextureFormatWebGL(format: TextureFormat): {
      internalFormat: GL;
      format: GLTexelDataFormat;
      type: GLPixelType;
      compressed: boolean;
      } {
      const formatData = WEBGL_TEXTURE_FORMATS[format];
      const webglFormat = convertTextureFormatToGL(format);
      const decoded = getTextureFormatInfo(format);
      return {
      internalFormat: webglFormat,
      format:
      formatData?.dataFormat ||
      getWebGLPixelDataFormat(decoded.channels, decoded.integer, decoded.normalized, webglFormat),
      // depth formats don't have a type
      type: decoded.dataType
      ? getGLFromVertexType(decoded.dataType)
      : formatData?.types?.[0] || GL.UNSIGNED_BYTE,
      compressed: decoded.compressed || false
      };
      }

These might be helpful as samples/tests:

2d_ktx2_samples.zip

They're various transcodings of a red Basis Universal texture, re-encoded as:

  • astc
  • etc1
  • etc2
  • bc1
  • bc3
  • bc5
  • rgba8

None of them (except the source ETC1S file) require Basis transcoding, ZSTD decompression, or WASM or Worker dependencies. So they should be mostly trivial to load in a unit test, parse with ktx-parse, and then pass the mipmap data directly into device.createTexture(...). I'm hoping to try a PR for that, but I may still be missing one or two missing pieces to get compressed textures rendering.

@ibgreen
Copy link
Collaborator Author

ibgreen commented Feb 13, 2025

Agreed.

  • Test cases will be important to keep this from breaking.
  • Also There is an example in loaders.gl that shows various format textures. It might be good to also have that example in luma.gl: https://loaders.gl/examples/textures

The example has access to the GL format (integer) but may need a way to convert that to a WebGPU format (string)

  • In the spirit of luma.gl we should standardize on WebGPU strings
  • (a small problem being that not all the compressed format have been assigned such strings yet).
  • loaders.gl should ideally be updated to return webgpu strings rather than GL constants.
  • Ideally the mapping should be in the webgl module and only included when using the webgl backend, but perhaps we need this mapping in core to be able to accept textures from sources that use GL constants.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants