atteneder / KtxUnity

Load KTX and Basis Universal textures at runtime
Apache License 2.0
215 stars 42 forks source link

KTX2 uncompressed textures support #47

Closed jsorel closed 1 year ago

jsorel commented 2 years ago

Hello,

Having compression support is nice but all compressions are lossy and sometimes we need the exact values.

I noticed you skip all uncompressed texture.

                if(ktx.ktxClass==KtxClassId.ktxTexture2_c) {
                    if(ktx.needsTranscoding) {
                        texture = await Transcode(ktx,linear);
                    } else {
                        Debug.LogError("Only supercompressed KTX is supported");
                    }
                } else {
                    Debug.LogError("Only KTX 2.0 is supported");
                }

Would it be possible to support a few uncompressed format for stuff not SRGB-like who require no data-loss ?

atteneder commented 2 years ago

@jsorel Thanks for bringing it up. You're absolutely right, that would indeed be helpful.

The only reason it's not supported at the moment is that the MVP initially aimed for BasisU decompression support (only).

Truth be told, I'm quite busy on glTF work (where non-compressed KTX files are not a thing yet), so if any volunteer would offer help with support for uncompressed, I'd be very grateful.

jsorel commented 2 years ago

Thanks for the fast answer.

I understand your situation, (I made both a GLTF-1 and GLTF-2/GLB reader/writer plus conversion to a 3d API in Java).

I can't help much because I don't know anything about Unity or C# ...

BUT I've been working with KTX-Software libktx for the last two weeks and figured out how to read/write and convert them to java API so I can give you the steps with libKTX at least and the matching GL format and GL internalformat.

If you could write juste one case then I believe it would be possible for me to write the others and send a merge request.

Here are the steps in pseudo-code :

ktxtexture2 tex = libktx.ktxTexture_CreateFromNamedFile("../r_reference_u.ktx2", KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT);
int level = 0;
int layer = 0;
int faceSlice = 0;
int textureWidth = tex.baseWidth;
int textureHeight = tex.baseHeight;

int offset = libktx.ktxTexture2_GetImageOffset(level, layer, faceSlice);
int nbBytes = libktx.ktxTexture2_GetImageSize(level);
byte[] rawData = new byte[nbBytes];

Pointer dataPointer = libktx.ktxTexture_GetData();
dataPointer.get(offset, rawData, 0, nbBytes);

switch (tex.vkFormat) {
  case VK_FORMAT_R8_UNORM : 
      // I don't know how to create a unity texture, but rawData contains tightly packed UInt8
      // that would be GL format : GL_RED and internalFormat : GL_R8
  . . .
}

r_reference_u.ktx2.zip