I’m hitting GPU Memory problems with my current workflow of using glTFs with jpg and png images on mobile. Sadly I can’t find a good setup to avoid that.
I guess the next step is to either use GPU compressed texture formats like basis or to reduce the texture resolution. Sadly I haven’t figured out a good workflow for rcreating and linking optimized assets.
My questions are:
Is the basis texture format already a feasible format for all platforms?
Is it possible to link basis textures in glTF files?
What tools do you use to create optimized textures (with Mipmaps / Texture Atlases)?
Is there a possibility to check the available GPU memory to load low res textures for mobile devices?
Is there an ETA for including basis textures in glTFs?
Right now, we’re using Blender to export the glTF files, which only supports exporting jpegs and pngs.
I would love to hear from your workflows to optimize the textures and models for the web!
We tested basis textures and are really satisfied with the reduction in filesize. So far I encountered some problems with 8k textures on mobile (rendering just black), but Im unsure what the cause is.
To answer some of your questions:
I converted the blender output texture from png to basis using the supplied tool and replaced the texture slot in the gltf manually (editing code in the model file).
The officially supplied converter from basis universal team. Creating mipmaps for the textures increases conversion time and filesize by a noticeable amount, but I couldnt see a difference in Performance or visual representation.
To throw in some Numbers: In one case the filesize on 4k textures went from 13.9 MB JPG to 7.0 MB basis, and in another from 7.4 MB to 0.53 MB without mipmaps and very little loss of detail.
Your images-part looks correct. Make sure to include the necessary lib files and that they are loaded which are required by basis.
I imported your files into my project and without modifying anything this is the result:
The front box is the one I uploaded here, which has the basis texture seemingly in the map property, but is not rendering it. The cube in the back is generated and the texture is set for the material manually, this one works as expected.
Edit: i would have to Check the source Control to actually verify my Statements, they are Just coming from my memory
Additionally I have compressed and converted my gltf-basis Models using DRACO, but this doesnt affect your Cube.
Im not using Extensions, These lines are Missing in my Models - do you mind Sharing some information about this?
Ah, I stumbled over that post a while ago. As far as I can tell, it’s only about loading the textures themselves (as in the BasisTexture Loader example I integrated in the reproduction, which actually works). I guess my question then is: How did you connect the BasisTextureLoader with your GLTFLoader?
I wanted to use the extension “GOOGLE_texture_basis”, which they also use in their example. It will most likely be replaced, but from what I can tell, this might be the standard right now. My idea was that the extesion can signal which textureloader should be used. The problem is, I can’t tell which step does not work, since at least the basis texture is loaded and some texture is in the map channel of the material, but it does not show in the renderer.
The link to enable basis textures happens via the loading Manager. I guess this part of code should be doing the job, but its just an extract from my project for the sake of simplicity.
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { BasisTextureLoader } from "three/examples/jsm/loaders/BasisTextureLoader.js";
[...]
const basisLoader = new BasisTextureLoader(loadingManager);
basisLoader.setTranscoderPath('libs/basis/');
basisLoader.detectSupport(renderer);
loadingManager.addHandler(/\.basis$/i, basisLoader);
const gltfLoader = new GLTFLoader(loadingManager);
Then proceed to load your model and add it to the scene.
It will definitely be replaced. I made it up to get a functional demo, but it’s not an official standard at all sorry! The real extensions are in progress.
Hm, I actually do that as well. I tried using the default loading manager like so:
var basisLoader = new BasisTextureLoader();
basisLoader.setTranscoderPath( 'js/libs/basis/' );
basisLoader.detectSupport( renderer );
THREE.DefaultLoadingManager.addHandler( /\.basis$/, basisLoader );
// model
var loader = new GLTFLoader().setPath( 'models/gltf/BasisBlock/glTF-basis/' );
I also tried creating an own loading manager:
var loadingManager = new THREE.LoadingManager();
var basisLoader = new BasisTextureLoader(loadingManager);
basisLoader.setTranscoderPath( 'js/libs/basis/' );
basisLoader.detectSupport( renderer );
loadingManager.addHandler( /\.basis$/, basisLoader );
// model
var loader = new GLTFLoader(loadingManager).setPath( 'models/gltf/BasisBlock/glTF-basis/' );
I also tried using the default GLTFLoader without the extension support, since that is what you seem to do. I can’t put my finger on what I’m missing here…
Those settings should probably be in the glTF file itself, as a sampler for the texture, but without an official extension it’s pretty DIY at the moment.
Aha! Thanks so much for the info. I somehow missed that in all the threads I read. Perfect, the example now works for me, finally I can join the basis party
@WenBin_Liang it’s probably a bit too early to start using .ktx2 files. If you want to use Basis, for now, I would create .basis files and load them separately from your models.
It will be possible to embed .ktx2 files in .gltf and .glb files before too long, but not yet. The three.js part of that is being developed in https://github.com/mrdoob/three.js/pull/18490, along with various tasks in the glTF and KTX-Software repositories.
Hi,
thanks for this very helpful thread. I learned a lot along the way. I’m working on adding .basis textures into a gltf. (I’m adding them manually) and then load the gltf according to the code snippets above. It seems to work generally, meaning the model is loaded and the textures seem to be loaded as well. However, I’m getting the following error:
WebGL: drawElements: texture bound to texture unit 1 is not renderable. It maybe non-power-of-2 and have incompatible texture filtering or is not ‘texture complete’, or it is a float/half-float type with linear filtering and without the relevant float/half-float linear extension enabled.
Now the texture is definitely a power-of-2. I also see these errors
[Warning] THREE.WebGLRenderer: WEBGL_compressed_texture_astc extension not supported.
[Warning] THREE.WebGLRenderer: EXT_texture_compression_bptc extension not supported.
[Warning] THREE.WebGLRenderer: WEBGL_compressed_texture_etc1 extension not supported.
[Warning] THREE.WebGLRenderer: WEBGL_compressed_texture_pvrtc extension not supported.
[Warning] THREE.WebGLRenderer: WEBKIT_WEBGL_compressed_texture_pvrtc extension not supported.
That is for Chrome 81.0 and Safari 13.1.
My goal is to use compressed textures inside glTF on desktop and mobile eventually.
The basis textures I created with the command line tool basisu tex.png
Some of the info here was great to get gLTF + basis loading correctly. It works fine if there is just one texture. When I attempt a model that has 3 different textures/images for 3 different meshes inside the gLTF, it seems to only be applying the first to all the meshes. I tried changing the name and order in the Images array and position or index in a lot of other places. Nothing seems to change which texture is applied to which mesh. Any ideas ?
There will be a new workflow available with three.js r119. It’s still experimental (the Basis extension for glTF is not complete yet, and things may change) but it’s likely to be more useable than the older workflows described earlier in this thread. Please try:
Compress with gltf-transform etc1s ... or gltf-transform uastc ... using glTF-Transform CLI.
Note that the --zstd option for Basis UASTC is not yet supported in my viewer, and I’m not sure if that support will make it into r119 or not. The PR is https://github.com/mrdoob/three.js/pull/19932. Once r119 is released I will update https://gltf-viewer.donmccurdy.com/ as well (and the experimental version above may stop working).