Skip to content
13 changes: 12 additions & 1 deletion docs/components/gltf-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,11 @@ You'll also need to load a decoder library by configuring scene properties as ex
[draco-decoders]: https://github.com/mrdoob/three.js/tree/master/examples/js/libs/draco/gltf
[meshopt-decoder]: https://github.com/zeux/meshoptimizer/tree/master/js

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

```html
<a-scene gltf-model="dracoDecoderPath: path/to/decoder/;
ktx2TranscoderPath: path/to/transcoder/;
meshoptDecoderPath: path/to/meshopt_decoder.js;">
<a-entity gltf-model="url(pony.glb)"></a-entity>
</a-scene>
Expand All @@ -144,6 +145,7 @@ When using glTF models compressed with Draco or Meshopt, you must configure the
| Property | Description | Default Value |
|------------------|--------------------------------------|----|
| dracoDecoderPath | Path to the Draco decoder libraries. | '' |
| ktx2TranscoderPath | Path to the KTX2 transcoder libraries. | '' |
| meshoptDecoderPath | Path to the Meshopt decoder. | '' |

`dracoDecoderPath` path must be a folder containing three files:
Expand All @@ -157,6 +159,15 @@ These files are available from the three.js repository, under
automatically choose whether to use a WASM or JavaScript decoder, so both should
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`.

`ktx2TranscoderPath` path must be a folder containing two files:

basis_transcoder.js — JavaScript wrapper for the WebAssembly transcoder.
basis_transcoder.wasm — WebAssembly transcoder.

These files are available from the three.js repository, under
[examples/js/libs/basis][basis].
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't see [basis] defined in the document, similar to [blender]. I guess you want to include something like
[basis]: https://github.com/mrdoob/three.js/tree/dev/examples/js/libs/basis

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call, bad syntax. Corrected w/ link to that file folder.



`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].

## More Resources
Expand Down
6 changes: 5 additions & 1 deletion examples/test/model/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,21 @@
<script src="../../../dist/aframe-master.js"></script>
</head>
<body>
<a-scene background="color: #FAFAFA" renderer="colorManagement: true;" stats>
<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>
<a-assets>
<a-asset-item id="crate-obj" src="../../assets/models/crate/crate.obj"></a-asset-item>
<a-asset-item id="crate-mtl" src="../../assets/models/crate/crate.mtl"></a-asset-item>
<a-asset-item id="brainstem" src="https://cdn.aframe.io/test-models/models/glTF-2.0/brainstem/BrainStem.gltf"></a-asset-item>
<a-asset-item id="putter-grip" src="https://cdn.glitch.global/f43e6264-95fc-43e8-8049-dc53b985b1e3/grip-compressed.glb?v=1661368839319"></a-asset-item>
</a-assets>

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

<a-entity gltf-model="#putter-grip" position="2.5 1.65 5" scale="2.75 3 3" rotation="0 90 0"></a-entity>
<a-text value="glTF\nw/ KTX2 texture" color="#000000" position=".75 1.25 5" scale="1.5 1.5 1.5"></a-text>

<a-entity obj-model="obj: #crate-obj; mtl: #crate-mtl" position="5 0 5"></a-entity>
<a-entity obj-model="obj: #crate-obj; mtl: #crate-mtl" position="5 2 5"></a-entity>
<a-text value="OBJ" color="#000000" position="4.75 -2 6" scale="1.5 1.5 1.5"></a-text>
Expand Down
4 changes: 4 additions & 0 deletions src/components/gltf-model.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ module.exports.Component = registerComponent('gltf-model', {
var self = this;
var dracoLoader = this.system.getDRACOLoader();
var meshoptDecoder = this.system.getMeshoptDecoder();
var ktxLoader = this.system.getKTX2Loader();
this.model = null;
this.loader = new THREE.GLTFLoader();
if (dracoLoader) {
Expand All @@ -25,6 +26,9 @@ module.exports.Component = registerComponent('gltf-model', {
} else {
this.ready = Promise.resolve();
}
if (ktxLoader) {
this.loader.setKTX2Loader(ktxLoader);
}
},

update: function () {
Expand Down
3 changes: 3 additions & 0 deletions src/lib/three.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,16 @@ if (THREE.Cache) {
require('../../vendor/DeviceOrientationControls'); // THREE.DeviceOrientationControls
require('super-three/examples/js/loaders/DRACOLoader'); // THREE.DRACOLoader
require('super-three/examples/js/loaders/GLTFLoader'); // THREE.GLTFLoader
require('super-three/examples/js/loaders/KTX2Loader'); // THREE.KTX2Loader
require('super-three/examples/js/loaders/OBJLoader'); // THREE.OBJLoader
require('super-three/examples/js/loaders/MTLLoader'); // THREE.MTLLoader
require('super-three/examples/js/utils/BufferGeometryUtils'); // THREE.BufferGeometryUtils
require('super-three/examples/js/lights/LightProbeGenerator'); // THREE.LightProbeGenerator
require('super-three/examples/js/utils/WorkerPool'); // WorkerPool used by KTX2Loader

THREE.DRACOLoader.prototype.crossOrigin = 'anonymous';
THREE.GLTFLoader.prototype.crossOrigin = 'anonymous';
THREE.KTX2Loader.prototype.crossOrigin = 'anonymous';
THREE.MTLLoader.prototype.crossOrigin = 'anonymous';
THREE.OBJLoader.prototype.crossOrigin = 'anonymous';

Expand Down
11 changes: 11 additions & 0 deletions src/systems/gltf-model.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@ function fetchScript (src) {
* provided externally.
*
* @param {string} dracoDecoderPath - Base path from which to load Draco decoder library.
* @param {string} basisTranscoderPath - Base path from which to load Basis transcoder library.
* @param {string} meshoptDecoderPath - Full path from which to load Meshopt decoder.
*/
module.exports.System = registerSystem('gltf-model', {
schema: {
dracoDecoderPath: {default: ''},
basisTranscoderPath: {default: ''},
meshoptDecoderPath: {default: ''}
},

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

update: function () {
var dracoDecoderPath = this.data.dracoDecoderPath;
var basisTranscoderPath = this.data.basisTranscoderPath;
var meshoptDecoderPath = this.data.meshoptDecoderPath;
if (!this.dracoLoader && dracoDecoderPath) {
this.dracoLoader = new THREE.DRACOLoader();
this.dracoLoader.setDecoderPath(dracoDecoderPath);
}
if (!this.ktx2Loader && basisTranscoderPath) {
this.ktx2Loader = new THREE.KTX2Loader();
this.ktx2Loader.setTranscoderPath(basisTranscoderPath).detectSupport(this.el.renderer);
}
if (!this.meshoptDecoder && meshoptDecoderPath) {
this.meshoptDecoder = fetchScript(meshoptDecoderPath)
.then(function () { return window.MeshoptDecoder.ready; })
Expand All @@ -49,6 +56,10 @@ module.exports.System = registerSystem('gltf-model', {
return this.dracoLoader;
},

getKTX2Loader: function () {
return this.ktx2Loader;
},

getMeshoptDecoder: function () {
return this.meshoptDecoder;
}
Expand Down