angular-three-gltf gives you a CLI to that turn GLTF assets into declarative and reusable Angular Three components.
This helps with performance optimization for asset-heavy Angular Three apps. It also allows you to modify your GLTF assets as Angular components, instead of working with 3D software like Blender.
- GLTF is thrown wholesale into the scene which prevents re-use, in threejs objects can only be mounted once
- Contents can only be found by traversal which is cumbersome and slow
- Changes to queried nodes are made by mutation, which alters the source data and prevents re-use
- Re-structuring content, making nodes conditional or adding/removing is cumbersome
- Model compression is complex and not easily achieved
- Models often have unnecessary nodes that cause extra work and matrix updates
- 🧑💻 It creates a virtual graph of all objects and materials. Now you can easily alter contents and re-use.
- 🏎️ The graph gets pruned (empty groups, unnecessary transforms, ...) and will perform better.
- ⚡️ It will optionally compress your model with up to 70%-90% size reduction.
Usage $ npx angular-three-gltf@latest [Model.glb] [options] Options --output, -o Output file name/path --keepnames, -k Keep original names --keepgroups, -K Keep (empty) groups, disable pruning --meta, -m Include metadata (as userData) --shadows, -s Let meshes cast and receive shadows --printwidth, -w Prettier printWidth (default: 120) --precision, -p Number of fractional digits (default: 2) --draco, -d Draco binary path --suspense -u Make the component suspense-ready --root, -r Sets directory from which .gltf file is served --transform, -T Transform the asset for the web (draco, prune, resize) --resolution, -R Transform resolution for texture resizing (default: 1024) --simplify, -S Transform simplification (default: false) (experimental!) --weld Weld tolerance (default: 0.0001) --ratio Simplifier ratio (default: 0.75) --error Simplifier error threshold (default: 0.001) --debug, -D Debug output- NodeJS must be installed
- three (>= 148.x)
- angular-three > 2.0.0
First you run your model through angular-three-gltf. npx allows you to use npm packages without installing them.
npx angular-three-gltf@latest model.gltf --transformAdd your model to your /public folder as you would normally do. With the --transform flag it has created a compressed copy of it (in the above case model-transformed.glb). Without the flag just copy the original model.
/public model-transformed.glb The component can now be dropped into your scene.
<script>import{Canvas } from'@threlte/core'importModelfrom'./Model.svelte'</script> <Canvas> <Model /> </Canvas>You can re-use it, it will re-use geometries and materials out of the box:
<Modelposition={[0, 0, 0]} /> <Modelposition={[10, 0, -10]} />Or make the model dynamic. Change its colors for example:
<T.Meshgeometry={$gltf.nodes.robot.geometry} material={$gltf.materials.metal} material.color="green" />Or exchange materials:
<T.Meshgeometry={$gltf.nodes.robot.geometry}> <T.MeshPhysicalMaterialcolor="hotpink" /> </T.Mesh>Make contents conditional:
{#ifcondition} <T.Meshgeometry={$gltf.nodes.robot.geometry} material={$gltf.materials.metal} />}{/if}You don't need to do anything if your models are draco compressed, since useGltf defaults to a draco CDN. By adding the --draco flag you can refer to local binaries which must reside in your /public folder.
With the --transform flag it creates a binary-packed, draco-compressed, texture-resized (1024x1024), webp compressed, deduped, instanced and pruned *.glb ready to be consumed on a web site. It uses glTF-Transform. This can reduce the size of an asset by 70%-90%.
It will not alter the original but create a copy and append [modelname]-transformed.glb.
Add the --types flag and your component will be typesafe.
<!--Auto-generated by: https://github.com/pmndrs/gltfjsxCommand: npx [email protected] ./stacy.glb -t--> <scriptlang="ts">importtype*asTHREEfrom'three'import{Group } from'three'import{T, typeProps, typeEvents, typeSlots } from'@threlte/core'import{useGltf, useGltfAnimations } from'@threlte/extras'type$$Props=Props<THREE.Group>type$$Events=Events<THREE.Group>type$$Slots=Slots<THREE.Group>exportconst ref =newGroup()typeActionName='pockets'|'rope'|'swingdance'|'jump'|'react'|'shrug'|'wave'|'golf'|'idle'typeGLTFResult={ nodes:{ stacy:THREE.SkinnedMesh mixamorigHips:THREE.Bone } materials:{} }const gltf =useGltf<GLTFResult>('/stacy.glb')exportconst{actions, mixer } =useGltfAnimations<ActionName>(gltf, ref)</script>{#if$gltf} <Tis={ref}{...$$restProps}> <T.Groupname="Scene"> <T.Groupname="Stacy"rotation={[Math.PI/2, 0, 0]} scale={0.01}> <Tis={$gltf.nodes.mixamorigHips} /> <T.SkinnedMeshname="stacy"geometry={$gltf.nodes.stacy.geometry} material={$gltf.nodes.stacy.material} skeleton={$gltf.nodes.stacy.skeleton} rotation={[-Math.PI/2, 0, 0]} scale={100} /> </T.Group> </T.Group> <slot{ref} /> </T>{/if}If your GLTF contains animations it will add @threlte/extras's useGltfAnimations hook, which extracts all clips and prepares them as actions:
const gltf = useGltf('/stacy.glb') export const{actions, mixer } = useGltfAnimations(gltf, ref)If you want to play an animation you can do so at any time:
constonEvent=()=>{$actions.jump.play();};import{parse}from"@threlte/gltf";import{GLTFLoader,DRACOLoader}from"three-stdlib";constgltfLoader=newGLTFLoader();constdracoloader=newDRACOLoader();dracoloader.setDecoderPath("https://www.gstatic.com/draco/v1/decoders/");gltfLoader.setDRACOLoader(dracoloader);gltfLoader.load(url,(gltf)=>{constcomponent=parse(filename,gltf,config);});The MIT License (MIT). Please see the License File for more information.