Skip to content

Three.js LDraw Viewer

Sixteen LDraw brick models rendered by Three.js and its LDrawLoader, with an Adwaita sidebar that picks the model and walks it through its building instructions one step at a time.

This is the showcase where the scene arrives from disk rather than from code. LDrawLoader fetches a packed .mpd file, reads it through Response.body, and turns roughly 250 KB of LDraw commands into 62 meshes and 124 line objects before the first frame. If your app loads its data at runtime instead of bundling it, this is the one to read.

Ported from the upstream webgl_loader_ldraw example.

This showcase declares all four runtimes, so pick the one you already have:

Terminal
gjsify showcase three-loader-ldraw --runtime gjs
gjsify showcase three-loader-ldraw --runtime node
gjsify showcase three-loader-ldraw --runtime bun
gjsify showcase three-loader-ldraw --runtime deno

A GTK 4 window opens with an Adwaita sidebar next to the canvas. Drag to orbit, scroll to zoom. Same window and same models on all four.

  • Model picks one of the sixteen models, from a car to a UCS AT-ST.
  • Rendering toggles Flat Colors, Merge Model and Smooth Normals.
  • Display steps through Building Step, and toggles the two edge layers LDrawLoader builds alongside the geometry: Display Lines and Conditional Lines.

Under gjs this runs the --app gjs bundle against GJS’s native gi://. Under node, bun and deno it runs one shared --app node bundle, where gi:// goes through the node-gi bridge. Choose the runtime covers what the CLI does when you leave the flag off.

TypeScript
import { mount } from '@gjsify/example-dom-three-loader-ldraw/browser';
const handle = mount(document.getElementById('app')!, {
assetBase: '/demos/ldraw/', // where the .mpd models are served from
});
handle.pause();
handle.resume();

The models ship with the package under ./assets/*, so point assetBase at wherever you copied them.

PackageWhat Three.js needs it for
@gjsify/fetchfetch over file://, Request, Headers, AbortSignal.any, and a Response.body the loader can re-wrap
@gjsify/web-streamsReadableStream, so the loader can report download progress
@gjsify/dom-eventsProgressEvent, dispatched per chunk while a model downloads
@gjsify/webglThe full WebGL 2.0 surface, including drawElementsInstanced and sized internal formats
@gjsify/dom-elementsHTMLCanvasElement and requestAnimationFrame
@gjsify/adwaita-webThe sidebar in the browser build
LibadwaitaAdw.ComboRow, Adw.SwitchRow and Adw.SpinRow in the GTK build

showcases/dom/three-loader-ldraw/

  • src/three-demo.ts is the scene plus the LDraw loading, with no platform imports.
  • src/models.ts is the model catalog, exported so both shells build the same dropdown.
  • src/gjs/gjs.ts, ldraw-window.ts and ldraw-window.blp are the Adw.Application, the window class and its Blueprint UI.
  • src/browser/browser.ts exports mount(); browser-main.ts runs it full-page.
  • src/assets/models/ldraw/officialLibrary/ holds the packed models, from the LDraw Parts Library under CC BY 2.0.