BestPractice: JPG attached to model or Load WebP to Model?

@Samuel-Morgan-Tyghe

i don’t think you need cMake if you use this…

the from node.js cmd you can run the function to convert to basis, i found it best if you first cd into the directory you want to save the basis files to and then in notepad++ you can layout a batch of images you want to process like this…

npx basisu G:/path/to/image1.png
npx basisu G:/path/to/image2.png

this will take theses images and the output them as .basis files to the directory you originally cd’d to, you can then setup yout three scene with basis image loader and decoder…

here is an example that uses .basis images

1 Like

Fantastic, I was overcomplicating things. Yes it does work.

1 Like

after installing [glTF-Transform] then said I needed to install KTX, and to install that I needed to install Cmake to build KTX to run the GLTF-Transform command to optimise the gltf/glb file.

No need to install Cmake or to build KTX-Software — it has prebuilt binaries in the releases tab here: Releases · KhronosGroup/KTX-Software · GitHub

Is This right? And is this better than BasisU?

The compression technology is the same, both use Basis Universal libraries. The difference is that .basis (output of basisu CLI) is a custom container format and can’t be embedded in a glTF file in any official way - you’d need to load your textures and models separately. Whereas .ktx2 is a more standard container format, is supported in glTF, and you can bundle the compressed textures into your glTF files.

Note that Draco affects only geometry, whereas BasisU and KTX affect only textures, so these are complementary.

2 Likes

Thanks, how do I install KTX-Software?

@donmccurdy I didn’t know this, I managed to change the gltf file so all mime types are basis and simply changed all .jpg to .basis and it loaded through the gltf loader with basis decoder, nevertheless gonna try ktx software install again was having the same problem thinking I need cmake

Thanks, how do I install KTX-Software?

From the Releases page, open the “Assets” dropdown and download the automated installer for your operating system.

2 Likes

Perfect, it worked when adding the options ‘development’ and add PATH to user.

@donmccurdy
glTF-Transform works great!
image
not that much of a reduction but still, i think i had already majorly compressed these images…

Edit:
these output files actually resulted in larger file sizes…
image
any idea why that might be?

thanks for the help with KTX install!!

I have the same,

info: gltfdesk.gltf (5.64 MB) → gt.gltf (5.93 MB)

and i havent been able to load it

TypeError: Cannot read property ‘uri’ of undefined
at GLTFParser.loadTexture (main.js:108966)

import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";

import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";

import * as THREE from "three";

import { MeshoptDecoder } from "../vendor/meshopt_decoder.module.js";

export function addModel() {

  const gltfLoader = new GLTFLoader();

  // const dracoLoader = new DRACOLoader();

  // dracoLoader.setDecoderPath("../vendor/draco/");

  // gltfLoader.setDRACOLoader(dracoLoader);

  return new Promise((resolve, reject) => {

    gltfLoader.load(

      "../dist/assets/models/output/gt.gltf",

      (data) => resolve(data),

      null,

      reject

    );


  });

}

@Samuel-Morgan-Tyghe
you should be able to load that, you now need to use basis texture loader in conjunction with basis decoder and gltf loader, not draco, unless you’ve also used draco compression on your mesh?

should look like this…

const basisLoader = new BasisTextureLoader();
basisLoader.setTranscoderPath('../../../examples/js/libs/basis/');
basisLoader.detectSupport(renderer);
1 Like

these output files actually resulted in larger file sizes…

Making smaller files is not really the purpose of Basis — sometimes it will, depending on your compression settings, but it’s not always better than JPEG for size. The main goal is to reduce GPU memory (JPG and PNG textures have to be fully decompressed in GPU memory) and to have the textures upload from JS memory to GPU memory much faster, avoiding rendering freezes while loading a new texture. See the gltf-transform etc1s -h documentation for a bit more detail here.

2 Likes

How do you use it in conjunction,
I know with draco its,

gltfLoader.setDRACOLoader(dracoLoader);

but it’s not

gltfLoader.setBasisTextureLoader(basisLoader);

like this, after this you can go on to load gltf as normal i think

import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";

import * as THREE from "three";

import {BasisTextureLoader} from 'three/examples/jsm/loaders/BasisTextureLoader'

export function addModel(renderer) {

  const gltfLoader = new GLTFLoader();

  const basisLoader = new BasisTextureLoader();

  basisLoader.setTranscoderPath( '../vendor/basis/' );

  basisLoader.detectSupport( renderer );

  // gltfLoader.setBasisTextureLoader(basisLoader);

  return new Promise((resolve, reject) => {

    gltfLoader.load(

      "../dist/assets/models/output/gt.gltf",

      

      (data) => resolve(data),

      null,

      reject

    );

  });

}

If you’re compressing with glTF-Transform, the Basis texture data will be embedded as .ktx2 files and need KTX2Loader to process. Here’s how I’d set that up:

This assumes the msc_basis_transcoder.js file is already added as a script to the page… trying to make that part automatic, until then see the three.js KTX2 example.

2 Likes

I need to read up on how to use Loading Manager, thanks for the example.

Sorry to be a pain, but I’m getting this error now.

ReferenceError: MSC_TRANSCODER is not defined

import { GLTFLoader } from “three/examples/jsm/loaders/GLTFLoader”;

import * as THREE from "three";

import {KTX2Loader} from 'three/examples/jsm/loaders/KTX2Loader'

import {DRACOLoader} from 'three/examples/jsm/loaders/DRACOLoader'

export function addModel(renderer) {

  const manager = new THREE.LoadingManager( () => {})

  const gltfLoader = new GLTFLoader(manager)

  .setCrossOrigin('anonymous')

  .setDRACOLoader( new DRACOLoader( manager ).setDecoderPath( '../vendor/draco/' ) )

  .setKTX2Loader( new KTX2Loader( manager ).detectSupport( renderer ) );

  return new Promise((resolve, reject) => {

    gltfLoader.load(

      "../dist/assets/models/output/gt.gltf",

      

      (data) => resolve(data),

      null,

      reject

    );

  });

}

@Samuel-Morgan-Tyghe

see the example three.js KTX2 example. suggested…

image

1 Like

Perfect, to summarise model Optimistation currently for 2021-01-19T00:00:00Z

  • WebP is the best for smallest file size, it will be supported for iOS 14 but currently best practice of inclusivity means stick to JPG and PNG

  • For fastest GPU and potentially the smallest file size use a Basis/.ktx2 compressor and use the Three Loaders to add to model

  • For faster GPU compress Geometries using Draco compressor then load with Draco Loader

  • Currently, one of the best things to do is use gltf-transform created by the wonderful @donmccurdy .It can input a Model(gltf) compress the Geometrys , Textures and then output as a loadable Model

alternatives are:

To compress your first Model / TLDR

npm install --global @gltf-transform/cli

from the ‘Asset’ section of here download and install

To implement follow the below trend
gltf-transform <command> <input> <output>

gltf-transform etc1s input/file/gltf.gltf /output/gt.gltf

more commands and options available here

Download and add Draco Transcoders from THREE GitHub, add to your project msc_basis_transcoder.js file

reference the

msc_basis_transcoder.js

In the html (this file might be skippable/embedded in the future, I think)

<script src="../wherever/the/path/to/the/file/in/your/project/is/msc_basis_transcoder.js"></script>

import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { KTX2Loader } from "three/examples/jsm/loaders/KTX2Loader";
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
export function addModel(renderer) {
const gltfLoader = new GLTFLoader()
.setCrossOrigin("anonymous")
.setDRACOLoader(new DRACOLoader().setDecoderPath("../where/you/saved/the/draco/decoder/folder/"))
.setKTX2Loader(new KTX2Loader().detectSupport(renderer));
gltfLoader.load(
// resource URL
'models/gltf/duck/duck.gltf',
// called when the resource is loaded
function ( gltf ) {
scene.add( gltf.scene );}    )    }
2 Likes

Yep, this all looks right to me! I’m hoping to change the installation process of msc_basis_transcoder.js in the next month to make that work more like DRACOLoader currently does, not requiring a <script/> tag on the page.

I’d add that gltfpack has some really nice features for simplification and optimization, including very fast decompression at loading time, so it’s a great alternative, too. But the optimization process does simplify the internal structure of the model in more opinionated ways than the other tools, so you do need to be careful of that part.

2 Likes