-
-
Notifications
You must be signed in to change notification settings - Fork 152
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
Support compressing KTX2 textures without CLI #675
Comments
I've been hoping that There's also https://github.com/BinomialLLC/basis_universal, they've added a WASM encoder for KTX2 recently. I haven't looked at that closely enough yet to say whether it works in Web, Node.js, or both, and whether it's generally a good replacement. I think some more investigation would be needed here... in the meantime it unfortunately would be necessary to copy/paste the |
Makes sense! I wasn't aware of this chain of issues, thanks for clarifying. (Side note: is there a better place for reading about breaking changes than the Changelog? Just ran into classes extending |
I believe the only relevant changes here were... ... included in v2.0.0 and mentioned in the changelog for that release ... is it possible you had something pinned older than v2.1.7? I'm not sure how a 2.1.7 to 2.4.2 update would break an extension. Sorry for the trouble if so! 😕 |
@hybridherbst were you able to get the v2.4.2 update working? |
Yep, we were. We also ended up doing what you recommended and moving the toktx scripts out of the CLI package into our own, to get rid of the CLI dependency. |
@hybridherbst is this available somewhere ? |
Ups sorry I misunderstood, I thought there were a webassembly / wasm implementation of the KTX encoder that was hacked |
@hybridherbst , we are in the same pickle that you were in and glad we stumbled on this issue. Were you able to cleanly copy paste the code out of the cli dependency? Curious to know if you ran into any stumbling blocks there. We are looking it but not entirely sure how to approach this. |
The Binomial KTX2 WASM encoder can be found here: They also provide example usage: Open questions remain:
|
Additional context. The KTX-Software includes a "libktx" WASM build, but that build does not include encoders. It could likely be extended to include Basis Universal encoders, but that route sounds more difficult (for me, as a JS developer) than using the Binomial encoders. |
I have tested the Binomial encoder, and it works fine in the browser environment. However, it throws an error in Node.js, and I'm not sure why. |
It appears that libKTX builds do exist with encoders, or something like that is possible, as found in the glTF Compressor project: https://github.com/KhronosGroup/glTF-Compressor However, it doesn't yet support mipmaps (KhronosGroup/KTX-Software#464). That would be a blocker for my adding libKTX to glTF Transform, but it should still be fairly straightforward for users of glTF Transform to loop over textures and apply whichever encoder you prefer, in your own scripts. |
I recently played a bit with KTX compression, and tried out the BinomialLLC encoder. Regarding the open questions:
It appears to work on the Web, meaning that the encoder test can be run in a browser (with a small bugfix for the compilation), and it does work in Node.js.
I'm not sure what this refers to. There seems to be some pre-allocation taking place on the level where the WASM is generated. But it probably refers to the "output buffer" that the data is written to. Some suspicious magic value is used in the test. I could imagine that a value of
I don't know the exact meaning of the options, but the options that are supported can be derived from the wrappers definition. I tried this out in the context of some experiments, where I locally created a |
@javagl Hi, can you give me an example that BinomialLLC encoder works in Node.js? I have tried it but throws an error in Node.js. |
@gz65555 Stuff is throwing errors. People are fixing errors. New errors show up. Rinse and repeat. That's how it is 🤷♂️ However, this is an example, containing the encoder built from https://github.com/BinomialLLC/basis_universal/tree/ad9386a4a1cf2a248f7bbd45f543a7448db15267, with the fix from BinomialLLC/basis_universal#356 , which just writes an "empty" KTX file: BasisUniversalExample-2023-09-11.zip To be of any use, something like this should be wrapped and hidden, and preferably offered as some NPM library. (I mean, who's really up for building something with CMake and Emscripten and fiddling with some WASM modules, when the goal is actually just to have some |
I've learned that loaders.gl has implemented their KTX2 compressor using the BinomialLLC encoder as well. See source code. It looks like they have code paths defined for both Node.js and web... so that's promising as a future direction. Not sure yet about installing from loaders.gl, or using a similar approach. |
It's a pity that there is no plain, small, dependency-free, standalone A short summary (not necessary complete - only what I have on the radar right now):
If glTF-Transform goes the path of (not using one of these things as a dependency, but) doing a custom WASM/encoder integration, it would at least be close to a "small, standalone package" (with some questions about the actual API). But having a package that just offers that |
One more for the list: Appears to be meant for use on web only. Based on the BinomialLLC encoder and ktx-parse. Depends on a CDN. |
Hello everyone We got this working for a while now, but wasnt following this thread anymore I've sent here a gltf transform class that transform textures to KTX on a web environnement ( with an additional web worker support when supported ) Look at usage.js for the import and initialisation I know this is not ideal, and not clean at all, It is a quick work, but maybe this can help I can answer questions if needed |
@Samsy That file referst to the BinomialLLC encoders. Did you (also) encounter BinomialLLC/basis_universal#356 when trying to encode to UASTC? |
@donmccurdy I'm about to support Node.js soon. The browser version can also be modified to not rely on the CDN. A lot of our internal projects already rely on ktx2-encoder and glTF-Transform for texture compression. If I have time, I can submit a pull request. |
I'd be interested in trying out Node.js support when that's available! I think we'll have to compare some of these and decide what to do. I'd love to have a WASM-based solution, but am a bit worried WASM may be much slower than the (multi-threaded) CLI. |
The stuff in the
That may be true. But you're aware of the trade-offs here: Option 1:
Option 2:
Option 1 is preferable, and I could imagine that most people don't care about whether encoding a model takes 1 Minute or 5 Minutes. (And whether it takes 1 minute or 10 minutes depends on the options for the encoding to begin with, like the qualityLevel and compressionLevel) Of course, for the time-critical cases (e.g. someone who wants to batch-process 1000 large models), the option to use the real executable should still exist. But I assume that you intended to offer this option anyhow. Maybe it then boils down to
|
I don't anticipate maintaining bindings in glTF Transform for more than one KTX2 encoder, unless they're API-compatible. KTX-Software and the BinomialLLC encoder do not have compatible APIs. If we add support for a WASM encoder, it will replace the KTX Software CLI integration. If WASM is ~2x slower that's probably acceptable for the benefits; 5-10x slower would be a tough sell I think. |
The degree of compatibility is... a judgement call, in many ways. The There already are places in the API that allow some soft of "different 'bindings'", so to speak, with these options like But ... the forms of these encoders (executable vs. WASM) are so different, and require so specific infrastructures that the effort for maintaining both of them might not be justified. About the performance... yeah. There is "The Truth", and there are "Benchmarks". But I was curious about that as well, and just did a very quick test (to be taken with the appropriate grain of salt):
The output:
Looks like it's very roughly in the ~"3-5 times slower" ballpark, but high (Maybe related?) : I recently did some similar experiments, to see in how far the "noisiness" and "frequencies" that appear in the input image affect the size of the KTX output image. And I could imagine that these aspects do not only affect the size, but also the time that is required for encoding. But that's just another dimension in this multi-dimensional rabbit hole, and one can cross fingers and hope that the effect of this will be independent of the difference of EXE-vs-WASM...) EDIT: Another aside: The fact that |
I am very interested in seeing this work. My use case is GLTF optimization on the client before uploading to S3 bucket. Having a toKTX transform would help a lot. |
From a practical usage perspective, using the wasm version to compress textures in a node.js environment is unacceptable due to its extremely slow speed(as demonstrated by javagl's test results). In actual business operations, there are hundreds of textures, each with specific quality requirements. |
Hi, any ETA or idea when KTX transform will be available outside of CLI ? |
@clibequilibrium no, sorry, I've pinned this under the "blocked or over budget" milestone. From my perspective there's no path forward here, unless a non-CLI KTX2 compression library becomes available that has comparable performance (+/- 50%) to the KTX-Software CLI. It is always possible to access image data in a script, and pass it to your image optimization library of choice: const document = await io.read('path/to/scene.glb');
for (const texture of document.getRoot().listTextures()) {
const image = texture.getImage(); // Uint8Array
// ...
} Maintaining bindings for Sharp (JPG, PNG, AVIF, and WebP) and KTX-Software (KTX2) texture compression is all I am willing to support out of my own time — adding another KTX2 library to the project is too much. If other developers or companies have resources (time or funding) to dedicate to this, that's always welcome and please reach out. |
Thanks a lot for your reply, totally understandable and makes sense. |
Is your feature request related to a problem? Please describe.
I'm in the process of updating from 2.1.7 to 2.4.2 (due to the toktx command changes), but running into what looks like "incorrect but somehow working" use of the library.
In 2.1.7, we were using something like
It looks like in 2.4.2
draco
has moved into/functions
, but otherwise this still works.How can we use the simplicity of the toktx command but not depend on the CLI? Might be missing something obvious here!
The text was updated successfully, but these errors were encountered: