Skip to content

WASM and JavaScript module

Syoyo Fujita edited this page Aug 26, 2025 · 8 revisions

Project folder

Located in web folder

https://github.com/lighttransport/tinyusdz/tree/release/web

Use Emscripten to build WASM/JS module.

SharedArrayBuffer feature is not required.

WASM module is being built with no thread support by default, so works without SharedArrayBuffer feature. (e.g. static-site hosting service like Github Pages, where Cross-Origin isolation headers cannot be appended)

We have a plan to make TinyUSDZ multithreaded, and provide WASM build with SharedArrayBuffer feature.

FetchAssetResolver & EMAssetResolver

Since it is impossible or quite difficult to call JS fetch(or other async function) to do async file read from C++(synchronous), we provide JavaScript/WASM specific FetchAssetResolver(JavaScript) and EMAssetResolver(C++).

How asset resolve in USD composition works

  • First list up asset paths for each composition op(subLayer, references, payload)
  • fetch asset(URI) and store it to memory
  • Set asset binary to EMAssetResolver(C++).
  • Use EMAssetResolver for AssetResolver in USD progressive composition(in C++).
    • EMAssetResolver returns corresponding binary for given asset name.

Limitation

  • File(asset) must be read into memory a priori. So it may fail to load larger USD file.

JS library

  • TinyUSDZLoader.js : USD loader, extends Three.js Loader class. Internally it imports WASM module.
  • TinyUSDZLoaderUtils.js : Material setup(also requires Three.js), etc.
  • TinyUSDZComposer.js : USD composition utils. Depends 'TinyUSDZLoader.js'

memory64

You can use memory64 build of tinyusdz JS/WASM module.

  function checkMemory64Support() {
      try {
          // Try creating a 64-bit memory
          const memory = new WebAssembly.Memory({
              initial: 1,
              maximum: 65536,
              index: 'i64'  // This specifies 64-bit indexing
          });
          return true;
      } catch (e) {
          return false;
      }
  }

  const loader = new TinyUSDZLoader();
  const memory64 = checkMemory64Support();
  await loader.init({useMemory64: memory64});

Max memory size is set to 8GB in 64bit build.

Memory limit feature on USD load.

JS/WASM supports memory limit feature to load USD(USDA or USDC). Assets(e.g. textures) are excluded in this limitation feature.

  // limits up to 100MB(during USD data is parsed)
  loader.setMaxMemoryLimitMB(100);

Currently, heap buffer consumes 10x ~ 20x of input USD file. (USD file data(or DataURI) itself, Parsed USD data, USD data in memory, Geom data for rasterizer, etc).

For example, 180 MB of suzanne-subd-lv6.usdc file,

https://github.com/lighttransport/tinyusdz-assets

JS engine(V8) consumes roughly 5 GB of heap buffer at max.

Three.js

Currently we only support Three.js for demo .

UsdPreviewSurface

UsdPreviewSurface parameters are directly mapped to Three.js's MeshPhysicalMaterial material.

UsdPreviewSurface Parameter three.js MeshPhysicalMaterial Property Notes
diffuseColor color Both define the base color/albedo.
emissiveColor emissive For self-illumination.
roughness roughness Controls surface roughness.
metallic metalness Controls metallic appearance.
clearcoat clearcoat MeshPhysicalMaterial supports clearcoat.
clearcoatRoughness clearcoatRoughness MeshPhysicalMaterial supports clearcoatRoughness.
opacity opacity Set transparent = true if opacity < 1.
ior (indexOfRefraction) ior Supported by MeshPhysicalMaterial (three.js r125+).
normal normalMap For normal mapping.
occlusion aoMap Ambient occlusion. Texture only
displacement displacementMap/ displacementScale Displacement mapping. Texture only

Note on displacement mapping

Mesh subdivision is not supported well. To make displacement mapping work nicely, Meshes must be tessellated finely before creating USD, or tesselate in JavaScript layer.

TODO

  • Support specularWorkflow
  • Support refraction(refractive transmission)

MaterialX

TODO

WASM binary size

as of 2025/Jun.

  • 1.9 MB with -Oz
    • 400 kb with zstd compression
  • 6~7 MB with -Oz + ASYNCIFY
    • ASYNCIFY is not enabled since we made TinyUSDZ WASM module async-free

npm release(Developer only)

Need to manually invoke Github Actions for npm publish.

https://github.com/lighttransport/tinyusdz/actions/workflows/wasmPublish.yml

image

Edit version and run workflow.

CLI

example

$ curl -X POST \
  -H "Authorization: token $GITHUB_TOKEN" \
  -H "Accept: application/vnd.github.v3+json" \
  https://api.github.com/repos/OWNER/REPO/actions/workflows/build-wasm.yml/dispatches \
  -d '{"ref":"main","inputs":{"release_version":"v1.2.0"}}'
Clone this wiki locally