BinomialLLC / basis_universal

Basis Universal GPU Texture Codec
Apache License 2.0
2.73k stars 267 forks source link

Support KTX input files #37

Open jherico opened 5 years ago

jherico commented 5 years ago

I'd like to be able to convert existing (compressed or uncompressed) KTX files to basis files using this tool. However, it appears that the tool only accepts PNG as an input file type

oscarbg commented 5 years ago

+1

MarkCallow commented 5 years ago

Converting already compressed files will not produce good results. It is far better to start from uncompressed source images.

A way of converting uncompressed KTX files to KTX2 files with Basis compression is in progress over at https://github.com/KhronosGroup/KTX-Software/tree/ktx2. There's already a ktx2ktx2 tool but Basis support is not there yet.

jherico commented 5 years ago

@MarkCallow I appreciate that converting from compressed content isn't a good path, but I have an actual use case that involves converting a significant amount of uncompressed KTX content with pre-generated mip files.

jherico commented 5 years ago

@richgel999 I'm working on adding limited support for uncompressed KTX->basis to this code by updating the code within basis_compressor::read_source_images, since this method deals both with converting source files to raw RGBA imagery and also deals with mipmap generation. However I have a question about the latter and the implications of the KTX spec concerning mipmaps with the m_params.m_mip_gen flag.

My instinct is that existing mips in KTX input files should be considered valid, regardless of the value of m_params.m_mip_gen. This would imply that extant KTX mips should be loaded even if this flag is false. However KTX supports the idea of a file with a partial mipmap pyramid, but I'm not sure if the Basis format does. If the intent is that Basis support only complete pyramids, then that implies that if an incomplete pyramid is detected in the input file(s), then m_params.m_mip_gen should be forced on (or have the tool emit an error and exit if the flag is false). Alternatively, I could simply error out on detecting a partial mip pyramid, since my own personal use case doesn't cover it and I'm uncertain how common a case it would be in the real world.

I'm also trying to determine to what extent we honor m_params.m_mip_renormalize in the case of KTX input. Again my instinct is to never apply renormalization to mip levels loaded from a KTX file, but instead to assume they're already correct, and instead only apply renormalize_normal_map to generated mips for an incomplete pyramid, if any.

jherico commented 5 years ago

I've managed to get a working version of the tool executable that will take an input uncompressed ktx file and produce and output basis file. The initial work is in this commit but I don't want to create a PR for it because it's built on top of the existing CMake refactor work. However, I would appreciate any feedback. I've tried to make the changes to the existing code as minimal as possible.

MarkCallow commented 5 years ago

Basis Universal compression is now integrated with libktx. You can create KTX2 files with the Basis U bitstream embedded (not the .basis file format, just the bitstream.) The repo has several tools: toktx for creating files from .png or NPBM files; ktx2ktx2 for creating a KTX2 file from a KTX file, ktxsc for supercompressing the images in a KTX2 file using Basis U and ktxinfo for printing out information about KTX or KTX2 files.

You can convert an uncompressed KTX file (one that does not use any of the GPU block compressed formats) to a KTX2 file with Basis U compressed images using the following pipeline:

ktx2ktx2 -o stdout myktx.ktx | ktxsc > myktx2.ktx2

There are no binary packages yet. You will have to build it yourself.

richgel999 commented 3 years ago

"The initial work is in this commit but I don't want to create a PR for it because it's built on top of the existing CMake refactor work. However, I would appreciate any feedback. I've tried to make the changes to the existing code as minimal as possible."

It's difficult for us to accept 3rd party code in BasisU (there's an approval process), although it's Apache 2.0 which is good. I'll diff this and see if I can merge it in.