@gltf-transform/render v0.1.1
@gltf-transform/render
IN DEVELOPMENT: This project is currently in development, and missing some functionality.
Syncs a glTF-Transform Document with a three.js scene graph, keeping three.js updated over time as changes are made to the Document. After changes are complete, export the exact glTF document — losslessly — with the glTF-Transform NodeIO / WebIO tools.
Motivation
While three.js can render glTF 2.0 files out of the box with THREE.GLTFLoader, and export them with THREE.GLTFLoader, this approach has an important limitation: the GLTFExporter → GLTFLoader trip is lossy, and doesn't support all features of glTF. For a small set of closely-controlled assets, this might be a good workflow. But in general, it is error-prone.
Another alternative might be to apply changes in glTF-Transform, export with WebIO, and reload with THREE.GLTFLoader. This workflow is accurate, but slow to repeat — even a simple change to a material parameter requires reloading the entire file.
@gltf-transform/render
provides a tighter integration between a glTF
Document and a three.js scene graph, so that changes to the Document
(e.g. Material
settings) are shown instantly in the rendered result. In addition, any
features that three.js doesn't support won't be lost — they just aren't
rendered in the preview.
Basic workflow:
- Load a glTF Document with glTF-Transform's WebIO
- Construct three.js scene with
DocumentRenderer
- Begin ~60 FPS render loop
- Apply changes to Document; update
DocumentRenderer
state
The cost of this fast edit/refresh loop is a somewhat slower first-time load and additional memory overhead, so the project is not meant to replace THREE.GLTFLoader for most users.
Quickstart
Install:
npm install --save @gltf-transform/render
API
import { Scene, WebGLRenderer, PerspectiveCamera } from 'three';
import { DocumentRenderer } from '@gltf-transform/render';
import { WebIO } from '@gltf-transform/core';
import { KHRONOS_EXTENSIONS } from '@gltf-transform/extensions';
// Set up three.js scene.
const scene = new Scene();
const camera = new PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 10);
const renderer = new WebGLRenderer();
// ...
// Load glTF Document.
const io = new WebIO().registerExtensions(KHRONOS_EXTENSIONS);
const document = await io.read('./input.glb');
const documentRenderer = new DocumentRenderer(document);
// Add the DocumentRenderer's output to the scene (just once).
const group = documentRenderer.toObject3D();
scene.add(group);
// When glTF Document is edited, trigger change detection.
documentRenderer.updateAll(); // (a) full update
documentRenderer.update(mesh); // (b) partial update
// Render.
function animate () {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
Bindings
binding | status | comments |
---|---|---|
Scene | ✅ | Complete |
Node | ✅ | Complete |
Material | ✅ | Complete |
Texture | 🚧 | Static |
Mesh | 🚧 | Static |
Primitive | 🚧 | Static |
Animation | ❌ | No bindings |
Camera | ❌ | No bindings |
Light | ❌ | No bindings |
Legend:
- ✅ Renders and updates
- 🚧 Static render, no updates
- ❌ Not rendered
Bugs / Limitations / To Do
P0:
- Correct tangent space normal maps
- Dispose of resources removed from PropertyGraph
- Granular update process (e.g. vertex data flag)
- Fails to render reused meshes
- Rename DocumentRenderer → GLTFRenderer (?)
- Unit tests
Extensions Supported
Complete:
- KHR_draco_mesh_compression
- KHR_mesh_quantization
- KHR_materials_clearcoat
- KHR_materials_ior
- KHR_materials_transmission
- KHR_materials_unlit
- EXT_texture_webp
P0:
- KHR_materials_volume
- KHR_texture_transform
- KHR_texture_basisu
P2:
- KHR_lights_punctual
- KHR_materials_pbrSpecularGlossiness
- KHR_materials_sheen
- KHR_materials_specular
- KHR_materials_variants
- EXT_mesh_gpu_instancing
- EXT_meshopt_compression
Contributing
# Install dependencies.
yarn
# Build source, watch for changes.
yarn watch
# Build source, watch for changes, and run examples.
yarn dev
# Run tests.
yarn test