KTX texture problem

Hi @trevordev, thank you for the fix. It’s working on the PG. Could we have a new minor release on npm with the latests changes? There are a couple fixes since the last release the we are looking forward to include in our project :slight_smile:

Yep I will push a new NPM today or tomorrow :slight_smile:

1 Like

Hey @Vinc3r and @JCPalmer, sorry for resurrecting a long-old post, but did you ever figure out how to format this code?

When I use:

var available = [’-astc.ktx’, ‘-dxt.ktx’, ‘-pvrtc.ktx’, ‘-etc2.ktx’, ‘-etc1.ktx’];
var formatUsed = this.engine.setTextureFormatToUse(available);

The skybox still does not show up with:

skyboxMaterial.reflectionTexture = new CubeTexture(https://our-bucket.s3.amazonaws.com/skybox_textures/generic/skybox, this.scene);

despite the fact that my file directory looks like:

^ I also had skybox-dxt.ktx first named as skybox.ktx. Neither of these names worked.

This works:
https://playground.babylonjs.com/#8S4DM1

This does not work:
https://playground.babylonjs.com/#8S4DM1#1

@JCPalmer @trevordev: I think I understood what you were saying about how the ‘new CubeTexture’ function does not work with ktx (?), but was an alternative for skybox generation figured out?

It’s just because you’re not using the extensions given in your available array :slight_smile:

Here using your .ktx & .ktx2 files:

https://playground.babylonjs.com/#8S4DM1#3

[edit]

Hmm, it seems only .jpg are loaded
image
I’m not sure but maybe you should keep ktx name convention (['-astc.ktx', '-dxt.ktx', '-pvrtc.ktx', '-etc2.ktx', '-etc1.ktx'] - and keeping only available formats in this list) and rename your files?

thanks for the response. So you mean keep the cube texture separated into 6 textures but change the name of those textures instead of having one texture as a whole?

(so having skybox_nx-dtx.ktx, skybox_ny-dtx.ktx, etc. instead of just skybox-dtx.ktx?)

Yep, try with the skybox_nx-dtx.ktx convention

1 Like

I tried again with the naming convention, as seen here, but the issue still persists:

It was working in your edited version of my playground only because it reverted back to jpg, as you noted.
I removed the jpg files from S3 and it still isn’t grabbing the ktx files. I opened the ktx files in babylon sandbox and they look fine, don’t seem to be corrupted.

Is it working in a local webserver, with all your assets in it?

It is not. I am compressing the .jpg images with this command:

toktx --bcmp skybox_pz-etc1.ktx skybox_pz.jpeg

(Khronos Texture Tools: toktx)

since --bcmp uses ETC1S / BasisLZ and implies --t2, I figured adding the -etc1.ktx would make sense. I also tried using ktx2 instead of ktx, but that did not work either. I printed out the result from const formatUsed = engine.setTextureFormatToUse(available); and it is always -dtx.ktx, which makes no sense to me, as it shouldn’t be compressing using DirectX.

I tried just putting the assets in the local project directory and referencing the address to the assets folder but that resulted in the same thing.

There is a bit of confusion here. There are two different versions of KTX: 1 and 2. KTX version 1 only supported platform specific formats. KTX version 2 supports Basis Universal which can transcode into platform specific formats at runtime.

The KTX1 loader allows you to specify multiple suffixes to allow you to provide each individual platform formats. You cannot use KTX2 files with this method.

KTX2 supports cubemaps, but we don’t have support for them in Babylon yet.

TLDR: Use KTX1 for this scenario for now. You’ll need a separate KTX1 (.ktx) file for each format (astc, dxt, pvrtc, etc2, etc1) for each face of the cubemap. I’m not exactly sure how to generate these files though. I don’t believe toktx is the tool to generate KTX1 files.

1 Like

Thank you for clarifying this. It seems that PVRTexTool should work for this purpose, correct?

Since “The texture must be encoded with the Y-axis flipped”, would I toggle on InvertZ on the cube texture (seems to be the only option for CubeTexture…no InvertY) after the new CubeTexture constructor is called?

1 Like

I’m not sure about the InvertY issue. Try it out and find out? :slight_smile:

So I’m still having an issue even just getting the cubeTexture to retrieve the textures properly. I thought I resolved it, because it showed up a couple times, but turns out it wasn’t using the ktx textures like I thought it was.

I am using the PVRTexTool GUI as suggested in this babylon doc:

Using the texture encoding process here
https://docs.imgtec.com/oxy_ex-2/UtilitiesSrc/PVRTexTool/Documentation/PVRTexTool_Manual/topics/PVRTexTool%20GUI/pvrtextool_texture_encoding.html

I am using these skybox images (512p x 512p):
https://playground.babylonjs.com/textures/skybox_nz.jpg
https://playground.babylonjs.com/textures/skybox_ny.jpg
https://playground.babylonjs.com/textures/skybox_nx.jpg
https://playground.babylonjs.com/textures/skybox_pz.jpg
https://playground.babylonjs.com/textures/skybox_py.jpg
https://playground.babylonjs.com/textures/skybox_px.jpg

and this encoding type
Screen Shot 2021-06-04 at 1.45.05 PM
with ETC Encoding Mode: Fast
The Generate MIPMaps and Vertical Flip checkboxes are checked, as suggested in this babylon doc as well:

I am using the skybox_nz-etc2.ktx, skybox_ny-etc2.ktx, … naming convention for my compressed files.

I am saving the compressed jpegs outputted from the encoding tool to .ktx extension files.

Additionally, I am not sure why PVRTexTool is outputting LARGER files than the jpegs, as seen here:
Screen Shot 2021-06-04 at 1.50.41 PM
The pattern of larger outputted files was consistent across all encoding types when saved as .ktx.
The only times the encoded files were not larger when saved was when they were saved as .pvr files, but it seems that the CubeTexture function only takes ktx, correct?

And, as a side note, there doesn’t seem to be a way to utilize the CubeTexture function to create a CubeTexture out of a single cube texture file (like an image file that contains all of the skybox images in their proper unfolded positions), correct?
Any thoughts as to why?

I tried many other permutations of encoding types to no avail. Would you mind trying to reproduce this? Feel free to point the textures retrieval address to something else.

Thanks!

I’ve never heard of .pvr files. If the encoding for the KTX is some kind of block compression, it will most likely be bigger than JPG. The main benefit is how much GPU memory is used. JPG will expand to full raw resolution on the GPU.

There aren’t that many file formats that can contain a cube texture. DDS can but it’s not portable. KTX version 2 can, but we don’t support it yet. If you are using this for an environment, there is the .env format which is a single file.

I am not using the CubeTexture as the env. I am using it as the skybox. It seems that the CubeTexture function only looks for -dtx.ktx files when putting together the skybox. Why is this? I am on a macOS and it seems that this playground here:
https://playground.babylonjs.com/#1SCH7H#5

has only tested dtx on macOS, and not any other compression on macOS, which contradicts the suggestions laid out in this documentation:

which says that some formats should work on multiple platforms.

Additionally, it would help greatly if you or someone else could reproduce this issue given the outline that I provided above. If the PVRTexTool is not your recommended tool for compressing textures, then please point me in the right direction. Otherwise, it is the main one suggested in that documentation (besides encoding basis from the source repo) and thus the one I am trying to utilize for this issue. I’ve tried all the encoding types (correctly, to my knowledge) to create each file extension above. None of them work with ‘new CubeTexture()’ constructor, nor CubeTexture.createFromImages().

Based on other forum posts, it seems this is either a known issue and hasn’t been resolved or that something is busted behind the scenes.

The env format can be used as a skybox as well as IBL. This is how the sandbox does it. This format is not compressed on the GPU though.

The selection is based on the capabilities reported by the browser. The code iterates through the array passed to setTextureFormatToUse and tries them in order. I tried this on my mac and the texture loaded which is good, no?

I’m not exactly sure which issue you refer to. If you are talking about trying to load images into a cube texture, can provide a playground link of the issue?

Thanks for the timely response.
In terms of reproducing the issue, I mean encoding the compressions of babylon’s given skybox jpgs into ktx or whatnot via PVRTexTool and getting those compressed images to load in when creating a new skybox.

This is my playground:

The textures and encoding strategy I am using are shown previously in this thread.

The point of the issue:
Right now the skybox alone is seemingly causing 200MB of memory usage in our app. We want to shrink that as much as possible, so we are compressing the textures.

I tried various compression encodings in the PVRTexTool GUI, to no avail. They load without error, but they do not render in the scene.
I followed the suggestions outlined here:

and then here:

but it seems the playgrounds on those posts are dead ends.

So I’m wondering if there is a compatibility issue, if this is an issue on the Babylon side, or if I am encoding them incorrectly. Thanks!

This is good, but the texture loaded is not being utilized in a skybox, which is not the point. The compressed textures that are being imported are not working with Babylon’s cube texture functions

After debugging a bit, it looks like the KTX texture loader doesn’t support loading 6 separate files as a cubemap. The code seems to indicate there is cubemap support, but it’s not through 6 separate images. I didn’t write this code, so I’m trying to decipher what it is supposed to be. I think it wants a single KTX that has 6 faces encoded in the file. I’m not sure how to generate a file like this.

It looks like there are ways to do this with PVRTexTool (imgtec.com) (see page 21).

1 Like