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

Provide mip-mapping capabilities in libKTX #464

Open
thokra1 opened this issue Aug 2, 2021 · 6 comments
Open

Provide mip-mapping capabilities in libKTX #464

thokra1 opened this issue Aug 2, 2021 · 6 comments

Comments

@thokra1
Copy link

thokra1 commented Aug 2, 2021

Currently, there doesn't seem to be a way to let the BasisU encoder generate mip maps. There is a host of options one can pass to the latest BasisU CLI:

  "Mipmap generation options:\n"
  " -mipmap: Generate mipmaps for each source image\n"
  " -mip_srgb: Convert image to linear before filtering, then back to sRGB\n"
  " -mip_linear: Keep image in linear light during mipmap filtering (i.e. do not convert to/from sRGB for filtering purposes)\n"
  " -mip_scale X: Set mipmap filter kernel's scale, lower=sharper, higher=more blurry, default is 1.0\n"
  " -mip_filter X: Set mipmap filter kernel, default is kaiser, filters: box, tent, bell, blackman, catmullrom, mitchell, etc.\n"
  " -mip_renorm: Renormalize normal map to unit length vectors after filtering\n"
  " -mip_clamp: Use clamp addressing on borders, instead of wrapping\n"
  " -mip_fast: Use faster mipmap generation (resample from previous mip, not always first/largest mip level). The default (as of 1/2021)\n"
  " -mip_slow: Always resample each mipmap level starting from the largest mipmap. Higher quality, but slower. Opposite of -mip_fast. Was the prior default before 1/2021.\n"
  " -mip_smallest X: Set smallest pixel dimension for generated mipmaps, default is 1 pixel\n"

Currently, while using libKTX works well for most other encoding-related tasks, all of the above has to be implemented separately (in our case using STBI resize, which sadly lacks Kaiser window filtering, IIRC).

@MarkCallow
Copy link
Collaborator

Mipmap generation in toktx uses the same code as basisu. Use --genmipmap to invoke it. It automatically does -mip_srgb if the input images are srgb, as determined from the input image. Similarly -mip_linear is done if the input images are linear. You can override the image metadata with--{assign,convert}_oetf which will also change the mipmap generation. You can set the filter with --filter, the scale with --fscale and the clamp mode with --wmode. The only things missing are -mip_renormalize, -mip_fast and -mip_slow. I have a TODO for renormalize. toktx currently always does the same as -mip_slow. The resampling speed has never troubled me so I didn't have a TODO for fast & slow.

@MarkCallow
Copy link
Collaborator

MarkCallow commented Aug 3, 2021

Whoops! You want the mipmap generation functionality in libktx. If I add it, I'll make it work for any format not just when using the BasisU encoder. Like with toktx, mip_srgb and mip_linear will be chosen based on the texture format but it will be possible to override.

@thokra1 thokra1 changed the title Expose mip-mapping caps of the BasisU encoder Provide mip-mapping capabilities in libKTX Aug 3, 2021
@thokra1
Copy link
Author

thokra1 commented Aug 3, 2021

This would be highly appreciated. Alternatively, I could spare some time and give you a pull request, if you're interested.

@MarkCallow
Copy link
Collaborator

A PR would be great. The PR can access the resampler in the BasisU code in a similar way to how toktx does it. The genmipmap function should give KTX_INVALID_OPERATION if the texture is already in a block-compressed format or if it already has mipmaps.

@MarkCallow
Copy link
Collaborator

I was caused to re-read this report after which I have a few questions:

  1. The BasisU CLI mentioned only lets you apply the mipmap options when compressing a file and it only compresses from PNG/BMP/TGA/JPG inputs. This is exactly equivalent to what you can do with ktx create (except it does not support BMP and TGA inputs). So @thokra1 what exactly are you asking for?
  2. If, as I guessed, you want mipmap generation in libktx, how would you create the input .ktx2 files, if not with ktx create?

The BasisU tool can also unpack .basis files to "one of more .ktx/.png files". You could then read these back into the tool and use the mipmap generation. You can do exactly the same with the ktx tool suite: use ktx extract to create .png or .exr files then ktx create with mipmap generation options to create a new .ktx2 file. But I do not recommend doing this from source files that have been subject to lossy compression: .basis files or .ktx2 files with BasisU, BCn, ASTC, ETC, etc. format images because you will introduce further losses. For this reason, if we were to add mipmap generation support to libktx, we would make it a KTX_INVALID_OPERATION to generate mipmaps if the .ktx2 file has such a format.

The crux of deciding whether there is anything to proceed with here is the answer to question 2.

@donmccurdy
Copy link
Contributor

@MarkCallow one significant use case would be tools like glTF-Compressor. To my understanding it uses libktx via JS/WASM to compress PNG/JPG images in glTF files; ktx create is not available in a browser environment. As a result, glTF files generated with glTF-Compressor currently lack mipmaps:

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

No branches or pull requests

3 participants