Huggingface.js documentation

@huggingface/usd-web-viewer

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

@huggingface/usd-web-viewer

OpenUSD in the browser: USD composition in WebAssembly, built on openusd (pure Rust), rendered with three.js. Reads .usd, .usda, .usdc and .usdz; loads run in a Web Worker.

npm install @huggingface/usd-web-viewer three

Usage

A ready-made viewer (renderer, lighting, orbit controls):

import { createViewer } from '@huggingface/usd-web-viewer';

const viewer = createViewer(document.getElementById('viewer')); // a container element
const { info } = await viewer.load(
  'https://huggingface.co/datasets/Robotiq-Official/simready-assets/resolve/main/Robotiq_2F_85/simready_usd/Robotiq_2F_85.usda',
);

Or into your own three.js scene:

import { loadUsd } from '@huggingface/usd-web-viewer';

const { root, complete, dispose } = await loadUsd(url);
scene.add(root); // a THREE.Group, Y-up, in meters
await complete; // textures stream in after the geometry

Options

loadUsd(url, options) and viewer.load(url, options) take:

OptionDefault
textures'preview''none', 'preview' (base color, small data maps, no normal maps) or 'full'
maxTextureSize1024Long side of decoded textures, in pixels
signalAn AbortSignal; the load rejects with a UsdLoadError of code aborted
onProgressCalled with the stage and an overall fraction from 0 to 1
filesLoad dropped or picked files instead of the network (see below)
wasmUrl, workerUrlnext to the packageWhere the WASM binary and the worker script are served from
maxConcurrentFetches16Requests in flight at once
maxLayerBytes, maxLayers768 MiB, 1024Layer download limits
maxTextureBytes512 MiBTexture download limit
maxTriangles, maxInstances20M, 100,000What is drawn at most

createViewer(container, options) takes background (default transparent), onContextLost and onContextRestored (called with a reload of the last model shown).

Failures are UsdLoadErrors with a code (aborted, fetch, compose, worker, webgl); anything that could not be shown faithfully is listed in info.warnings. Every option, error and warning is typed.

Loading untrusted files

  • Requests are sent like <model-viewer>’s: cookies only to the page’s own origin (credentials: 'same-origin'), no custom headers, no referrer.
  • Layers and textures are fetched over http(s) only.
  • Parsing runs in Rust compiled to WebAssembly, in a Web Worker.
  • Each load is capped: maxLayerBytes (768 MiB), maxLayers (1024), maxTextureBytes (512 MiB), maxTriangles (20M) and maxInstances (100,000); images up to 16384 px a side and 8192 x 8192 px in area; prims nested up to 256 levels deep; .usdz entries up to 512 MiB each and 1 GiB in all, stored uncompressed.
  • Malformed files fail the load with a UsdLoadError.

Local files

To show files dropped on the page or picked with <input type="file" webkitdirectory>, pass them as files, keyed by their path in the package, and load the root layer’s key. Relative paths in the files resolve against each other; nothing is fetched for them.

const files = new Map([...input.files].map((file) => [file.webkitRelativePath || file.name, file]));
await viewer.load('chair/simready_usd/sm_chair.usd', { files });

Bundlers

The worker and the WASM binary are found with new URL(..., import.meta.url), which Vite, webpack and other bundlers resolve and emit. With the Vite dev server, exclude the package from dependency pre-bundling:

// vite.config.js
export default { optimizeDeps: { exclude: ['@huggingface/usd-web-viewer'] } };

MIT licensed. The licenses of the Rust crates compiled into the WASM binary are in THIRD_PARTY_LICENSES.

Update on GitHub