<!-- Generated by `pnpm docs:recipes`. Do not edit by hand. -->
A .glb or .gltf file loads as a ModelAsset, and a Model component instantiates it under an
entity. Load before app.start() so the mesh is part of the scene Babylon Lite registers;
a model added later still appears, a few frames after its material family is compiled
(app.renderer.warmUp pays that cost up front).
One release per load: an asset() field holds the handle but never owns its reference count.
typescript
import{Camera,Light,Model,createApp}from"@ignifx/core";importtype{AssetHandle,ModelAsset}from"@ignifx/core";const canvas=document.querySelector("canvas");if(!(canvasinstanceofHTMLCanvasElement)){thrownewError("ignifx renders into a <canvas> element.");}const app=awaitcreateApp({canvas,settings: { assets: { root: "assets" }, rendering: { features: { shadows: true } } },});// A camera is an entity with a `Camera` component: the entity's transform is the view.const eye=app.world.createEntity("Main Camera");eye.transform.localPosition.set(0,1.6,-4);eye.transform.lookAt({ x: 0, y: 0.8, z: 0 });eye.addComponent(Camera,{ fov: 55, near: 0.1, far: 100 });// Only directional and spot lights can cast shadows in this Babylon Lite version (IGX-0703).const sun=app.world.createEntity("Sun");sun.transform.localPosition.set(3,6,-2);sun.transform.lookAt({ x: 0, y: 0, z: 0 });const light=sun.addComponent(Light,{ type: "directional", intensity: 3 });light.shadows.enabled=true;light.shadows.technique="pcf";// The app is not running yet, so `loadAsync` settles as soon as the file is decoded and `handle.value`// is safe below; once `app.start()` has run, loads settle in the `PreUpdate` phase of a frame.const hero: AssetHandle<ModelAsset> =awaitapp.assets.loadAsync<ModelAsset>("models/hero.glb");const actor=app.world.createEntity("Hero");actor.addComponent(Model,{ model: hero, castShadows: true, receiveShadows: true });awaitapp.start();// glTF node names are the attachment points: parent an entity under one to carry a weapon or a hat.const model=actor.requireComponent(Model);const torch=app.world.createEntity("Torch");model.attachToNode("hand.R",torch);app.log.info("model nodes:",model.nodes.size);// Teardown. The entity's components go with it; the handle is released by whoever loaded it.window.addEventListener("pagehide",()=>{actor.destroy();hero.release();app.dispose();});