Skip to content

Commit df780ad

Browse files
jameskane05James Kane
andauthored
Add support for KTX2 texture compression to gltf-model (#5101)
* Initial commit, feature support for ktx2 textures in gltf-model * Code cleanup * Doc cleanup * Doc cleanup * Re-adding mysteriously wiped code for gltf-loader system * WIP example * KTX2 seem to be working, verifying... * Style correction * Extending example * Correcting link to transcoder files * basisTranscoderPath is the correct term, since it's the path to basis .wasm and .js files Co-authored-by: James Kane <jkane@paradowski.com>
1 parent 52abba0 commit df780ad

File tree

5 files changed

+34
-2
lines changed

5 files changed

+34
-2
lines changed

‎docs/components/gltf-model.md‎

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,10 +132,11 @@ You'll also need to load a decoder library by configuring scene properties as ex
132132
[draco-decoders]: https://github.com/mrdoob/three.js/tree/master/examples/js/libs/draco/gltf
133133
[meshopt-decoder]: https://github.com/zeux/meshoptimizer/tree/master/js
134134

135-
When using glTF models compressed with Draco or Meshopt, you must configure the path to the necessary decoders:
135+
When using glTF models compressed with Draco, KTX2 or Meshopt, you must configure the path to the necessary decoders:
136136

137137
```html
138138
<a-scene gltf-model="dracoDecoderPath: path/to/decoder/;
139+
basisTranscoderPath: path/to/transcoder/;
139140
meshoptDecoderPath: path/to/meshopt_decoder.js;">
140141
<a-entity gltf-model="url(pony.glb)"></a-entity>
141142
</a-scene>
@@ -144,6 +145,7 @@ When using glTF models compressed with Draco or Meshopt, you must configure the
144145
| Property | Description | Default Value |
145146
|------------------|--------------------------------------|----|
146147
| dracoDecoderPath | Path to the Draco decoder libraries. | '' |
148+
| basisTranscoderPath | Path to the basis/KTX2 transcoder libraries. | '' |
147149
| meshoptDecoderPath | Path to the Meshopt decoder. | '' |
148150

149151
`dracoDecoderPath` path must be a folder containing three files:
@@ -157,6 +159,14 @@ These files are available from the three.js repository, under
157159
automatically choose whether to use a WASM or JavaScript decoder, so both should
158160
be included. A Google-hosted version of the Draco decoder libraries saves you from needing to include these libraries in your own project: set `https://www.gstatic.com/draco/v1/decoders/` as the value for `dracoDecoderPath`.
159161

162+
`basisTranscoderPath` path must be a folder containing two files:
163+
164+
basis_transcoder.js — JavaScript wrapper for the WebAssembly transcoder.
165+
basis_transcoder.wasm — WebAssembly transcoder.
166+
167+
These files are available from the three.js repository in [`/examples/js/libs/basis`](https://github.com/mrdoob/three.js/tree/master/examples/js/libs/basis).
168+
169+
160170
`meshoptDecoderPath` path should be the complete file path (including filename) for a Meshopt decoder, typically named `meshopt_decoder.js`. Meshopt requires WebAssembly support. A CDN-hosted, versioned decoder is available at `https://unpkg.com/meshoptimizer@0.16.0/meshopt_decoder.js`, or you may download copies from the [meshoptimizer GitHub repository][meshopt-decoder].
161171

162172
## More Resources

‎examples/test/model/index.html‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,21 @@
77
<script src="../../../dist/aframe-master.js"></script>
88
</head>
99
<body>
10-
<a-scene background="color: #FAFAFA" renderer="colorManagement: true;" stats>
10+
<a-scene gltf-model="basisTranscoderPath:https://cdn.jsdelivr.net/npm/super-three@0.141.0/examples/js/libs/basis/;" background="color: #FAFAFA" renderer="colorManagement: true;" stats>
1111
<a-assets>
1212
<a-asset-item id="crate-obj" src="../../assets/models/crate/crate.obj"></a-asset-item>
1313
<a-asset-item id="crate-mtl" src="../../assets/models/crate/crate.mtl"></a-asset-item>
1414
<a-asset-item id="brainstem" src="https://cdn.aframe.io/test-models/models/glTF-2.0/brainstem/BrainStem.gltf"></a-asset-item>
15+
<a-asset-item id="putter-grip" src="https://cdn.glitch.global/f43e6264-95fc-43e8-8049-dc53b985b1e3/grip-compressed.glb?v=1661368839319"></a-asset-item>
1516
</a-assets>
1617

1718
<a-entity position="0 0 -12">
1819
<a-entity gltf-model="#brainstem" position="-2 -1 5" scale="3 3 3"></a-entity>
1920
<a-text value="glTF" color="#000000" position="-2 -2 6" scale="1.5 1.5 1.5"></a-text>
2021

22+
<a-entity gltf-model="#putter-grip" position="2.5 1.65 5" scale="2.75 3 3" rotation="0 90 0"></a-entity>
23+
<a-text value="glTF\nw/ KTX2 texture" color="#000000" position=".75 1.25 5" scale="1.5 1.5 1.5"></a-text>
24+
2125
<a-entity obj-model="obj: #crate-obj; mtl: #crate-mtl" position="5 0 5"></a-entity>
2226
<a-entity obj-model="obj: #crate-obj; mtl: #crate-mtl" position="5 2 5"></a-entity>
2327
<a-text value="OBJ" color="#000000" position="4.75 -2 6" scale="1.5 1.5 1.5"></a-text>

‎src/components/gltf-model.js‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ module.exports.Component = registerComponent('gltf-model', {
1313
var self = this;
1414
var dracoLoader = this.system.getDRACOLoader();
1515
var meshoptDecoder = this.system.getMeshoptDecoder();
16+
var ktxLoader = this.system.getKTX2Loader();
1617
this.model = null;
1718
this.loader = new THREE.GLTFLoader();
1819
if (dracoLoader) {
@@ -25,6 +26,9 @@ module.exports.Component = registerComponent('gltf-model', {
2526
} else {
2627
this.ready = Promise.resolve();
2728
}
29+
if (ktxLoader) {
30+
this.loader.setKTX2Loader(ktxLoader);
31+
}
2832
},
2933

3034
update: function () {

‎src/lib/three.js‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,16 @@ if (THREE.Cache) {
2222
require('../../vendor/DeviceOrientationControls'); // THREE.DeviceOrientationControls
2323
require('super-three/examples/js/loaders/DRACOLoader'); // THREE.DRACOLoader
2424
require('super-three/examples/js/loaders/GLTFLoader'); // THREE.GLTFLoader
25+
require('super-three/examples/js/loaders/KTX2Loader'); // THREE.KTX2Loader
2526
require('super-three/examples/js/loaders/OBJLoader'); // THREE.OBJLoader
2627
require('super-three/examples/js/loaders/MTLLoader'); // THREE.MTLLoader
2728
require('super-three/examples/js/utils/BufferGeometryUtils'); // THREE.BufferGeometryUtils
2829
require('super-three/examples/js/lights/LightProbeGenerator'); // THREE.LightProbeGenerator
30+
require('super-three/examples/js/utils/WorkerPool'); // WorkerPool used by KTX2Loader
2931

3032
THREE.DRACOLoader.prototype.crossOrigin = 'anonymous';
3133
THREE.GLTFLoader.prototype.crossOrigin = 'anonymous';
34+
THREE.KTX2Loader.prototype.crossOrigin = 'anonymous';
3235
THREE.MTLLoader.prototype.crossOrigin = 'anonymous';
3336
THREE.OBJLoader.prototype.crossOrigin = 'anonymous';
3437

‎src/systems/gltf-model.js‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@ function fetchScript (src) {
1919
* provided externally.
2020
*
2121
* @param {string} dracoDecoderPath - Base path from which to load Draco decoder library.
22+
* @param {string} basisTranscoderPath - Base path from which to load Basis transcoder library.
2223
* @param {string} meshoptDecoderPath - Full path from which to load Meshopt decoder.
2324
*/
2425
module.exports.System = registerSystem('gltf-model', {
2526
schema: {
2627
dracoDecoderPath: {default: ''},
28+
basisTranscoderPath: {default: ''},
2729
meshoptDecoderPath: {default: ''}
2830
},
2931

@@ -33,11 +35,16 @@ module.exports.System = registerSystem('gltf-model', {
3335

3436
update: function () {
3537
var dracoDecoderPath = this.data.dracoDecoderPath;
38+
var basisTranscoderPath = this.data.basisTranscoderPath;
3639
var meshoptDecoderPath = this.data.meshoptDecoderPath;
3740
if (!this.dracoLoader && dracoDecoderPath) {
3841
this.dracoLoader = new THREE.DRACOLoader();
3942
this.dracoLoader.setDecoderPath(dracoDecoderPath);
4043
}
44+
if (!this.ktx2Loader && basisTranscoderPath) {
45+
this.ktx2Loader = new THREE.KTX2Loader();
46+
this.ktx2Loader.setTranscoderPath(basisTranscoderPath).detectSupport(this.el.renderer);
47+
}
4148
if (!this.meshoptDecoder && meshoptDecoderPath) {
4249
this.meshoptDecoder = fetchScript(meshoptDecoderPath)
4350
.then(function () { return window.MeshoptDecoder.ready; })
@@ -49,6 +56,10 @@ module.exports.System = registerSystem('gltf-model', {
4956
return this.dracoLoader;
5057
},
5158

59+
getKTX2Loader: function () {
60+
return this.ktx2Loader;
61+
},
62+
5263
getMeshoptDecoder: function () {
5364
return this.meshoptDecoder;
5465
}

0 commit comments

Comments
 (0)