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

GLTFLoader: Add EXT_texture_avif support. #25173

Merged
merged 6 commits into from
Jan 31, 2023
Merged

GLTFLoader: Add EXT_texture_avif support. #25173

merged 6 commits into from
Jan 31, 2023

Conversation

leon
Copy link
Contributor

@leon leon commented Dec 22, 2022

Related issue: #25171

Description

Adds support for the yet to be merged EXT_texture_avif gltf extension
KhronosGroup/glTF#2235

The test to see if the browser is supported is a 1x1 px avif file created in PS and then run through squoosh to get the smallest possible size (305bytes)
and then base64 converted.
I'm not sure if we can get an even smalled image, but this was as small as I could get it.

I tested it in edge which doesn't support avif yet, and in chrome and both work as expected.

@Mugen87
Copy link
Collaborator

Mugen87 commented Dec 22, 2022

I can confirm Chrome does support avif when loaded via TextureLoader.

@leon
Copy link
Contributor Author

leon commented Dec 22, 2022

@Mugen87 I added the missing ctor and added an example for the AVIF loader.

It works on Mac Ventura with Chrome 108

https://localhost:8080/examples/#webgl_loader_gltf_avif

@Mugen87
Copy link
Collaborator

Mugen87 commented Dec 22, 2022

If you add a new example, you have to generate a E2E screenshot via npm run make-screenshot webgl_loader_gltf_avif.

examples/files.json Outdated Show resolved Hide resolved
@donmccurdy
Copy link
Collaborator

Context for reviewers —

At this stage EXT_texture_webp is a draft proposal for a multi-vendor extension. Khronos does not formally ratify EXT_ extensions, and the extension will likely be merged to the glTF repository (KhronosGroup/glTF#2235) as soon as (1) two or more vendors implement it, and (2) the specification appears to be in good order. If we have any concerns about AVIF support in glTF, or about which AVIF features to allow, this is a helpful time to voice that. By adding support in three.js we would be one of those first two vendors.


Thoughts on AVIF —

AVIF may offer better compression on disk and over the network compared to WebP, PNG, and JPEG in many cases. I haven't compared to WebP2. Users should be aware that (like PNG, JPEG, or WebP) AVIF must be fully decompressed on the GPU, which brings some performance vs. quality vs. network size tradeoffs. KTX2 / Basis Universal remains the best option for textures that remain compressed on the GPU. AVIF will likely be the best option for minimizing network size.

AVIF has some useful features that, unfortunately, we probably cannot support in WebGL at this time, including:

  • progressive loading
  • wide gamut color spaces
  • HDR color spaces
  • embedded depth maps and layers
  • animation

These would require changes to browser APIs, or shipping a JavaScript or WASM decoder with three.js, which seems out of scope for now. HDR and wide-gamut color spaces may become available later with WebGPU.

Adding AVIF feels like a good thing to me. The cost is low and there's already strong support for the format. See Using Modern Image Formats: AVIF And WebP for a deeper dive.

@Mugen87 Mugen87 added this to the r149 milestone Dec 22, 2022
@Mugen87 Mugen87 changed the title GLTFLoader EXT_texture_avif support GLTFLoader: Add EXT_texture_avif support. Dec 23, 2022
@leon
Copy link
Contributor Author

leon commented Dec 25, 2022

To be able to do proper demos without having to resort to manually copying base64 into gltf files, I went ahead and implemented AVIF support in gltf-pipeline.
https://github.com/leon/gltf-pipeline/tree/avif

I did a test where I compressed the DamagedHelmet with avif using squoosh.
To not get to hung up on all the setttings for avif, I upped the quality until i couldn't see any major differences between the original textures. and went for
40 as quality
and 6 as effort.
By doing this I was able to reduce the glb file from 3773kb down to 560kb.

I changed the example to use this model instead of my cube, since the DamagedHelmet is a good reference model.
https://localhost:8080/examples/#webgl_loader_gltf_avif

@donmccurdy
Copy link
Collaborator

Experimental implementation in glTF Transform, for testing purposes:

# install
npm install --global @gltf-transform/cli@avif

# compress textures
gltf-transform avif input.glb output.glb

Related:

@Mugen87
Copy link
Collaborator

Mugen87 commented Jan 12, 2023

@donmccurdy Are you fine when this PR gets merged?

@donmccurdy
Copy link
Collaborator

@Mugen87 maybe let's skip the demo for now, unless/until we can do something more illustrative than the DamagedHelmet scene? Otherwise yes — this looks good to me!

@mrdoob mrdoob modified the milestones: r149, r150 Jan 26, 2023
@mrdoob mrdoob merged commit 88c3d4d into mrdoob:dev Jan 31, 2023
@Mugen87
Copy link
Collaborator

Mugen87 commented Feb 1, 2023

Agreed, another demo without the helmet would be better but at least for testing/validation purposes I think it's okay for now.

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

Successfully merging this pull request may close these issues.

4 participants