State of the art for viewing USDZ on web

Hi!

I’m curious what is the state of the art for vieweing usdz files on the web today?
There is the autodesk for with the renderdelegate that is used by three.js’s USDZLoader which works well for basics but limited, eg. proper scene transform hierarchy is missing.
Also this autodesk fork is very undocumented and looks abandoned?

There is tinyusdz which seems more maintained but also not complete at all.

Or maybe it’s futile to try to render usdz files on the web and it’s always better to convert to gltf offline first? In that case what would you say is the most complete converter for that?

Thanks!

I think it really depends on your specific constraints (as with anything on the web)

We’ve just started a Web Interest group in the AOUSD, so I’d definitely recommend joining there to discuss further.

  1. The Autodesk WASM fork isn’t abandoned, but we are looking into paths to move it along now into something more integrated into the primary repo. It is also quite large as a deliverable on the web, but would give you the entirety of USD.
  2. TinyUSDZ is an option but isn’t feature complete so you’ll lose out on various features, but that might not be an issue depending on your assets.
  3. Converting to glTF is probably the easiest right now but it’s lossy. However, it’s easiest to get integrated into a lot of viewers. The best conversion tool right now is probably building the Adobe file format plugins with USD.

Alternatively, if your needs are more limited to displaying models, the W3C Model Element is progressing along nicely and might be an option.

2 Likes

Thank you, that’s super useful!

  1. I’m using that and I’m seeing very limited list of methods compared to what I find in the usdz api documentation.
    What I’m using is similar to the three.js implementations like this:
    usd-viewer/usd-wasm/src/hydra/ThreeJsRenderDelegate.js at main · needle-tools/usd-viewer · GitHub

and I’m finding it difficult to reconstruct the transform hierarchy within a usdz file. Most web renderers like the code above create a flat list of nodes using the render delegates, something like:

const driver = new module.HdWebSyncDriver(delegate, fileName);
driver.Draw();

When I tried instead to traverse the xform objects I had to do things like this:

const stage = driver.GetStage();
const rootLayer = stage.GetRootLayer();
const xformPaths: string[] = [];
rootLayer.Traverse("/", path => {
	const prim = stage.GetPrimAtPath(path);
	if (getType(prim) === "Xform")
	{
		xformPaths.push(path);
	}
})

orderPathsByDepthAsc(xformPaths);

for (const path of paths)
{
	const prim = stage.GetPrimAtPath(path);
	// This errors out:
	prim.GetAttribute("xformOp:transform").Get();
}

Here I got weird wasm error when trying to get the local transform and simply a lot of missing functions compared to what I’m supposed to be seeing according to the official documentation.
It’s possible that the wasm binary I’m using is outdated but it’s the latest I found and it’s pretty difficult to build this manually.

My goal is to load and export to usdz files in my hobby editor gltfeditor.com which is mostly working but there are subtle things missing, like animation, hierarchy, binary usdz export support.

I would just like to follow up a bit on @dhruvgovil 's response above. As they mentioned, we are actively working on getting WASM support into the main OpenUSD repository. It is a pretty large change with a number of moving pieces but progress is moving along steadily. We are hoping to land the first part of this change soon. As you note, it can be a bit tricky to get the fork building, so we are working to have the process as smooth as possible using build_usd.py once official support lands.

The Autodesk fork currently exposes only a small subset of the USD API to JavaScript. Unfortunately many functions you see in the official documentation are not present. We are currently looking at what the javascript portion of the WASM effort is going to look like. Wrapping everything as we do with python would be a herculean undertaking, so we are exploring a number of avenues to ease this burden.

Seeing your use case spelled out here provides a great datapoint in getting an idea of what people are looking for in the API and we are happy to hear any suggestions from the community on the best path forward in this regard. For now, it should possible to expose missing portions of the USD API that you need by modifying the JS wrap files present in the fork. I understand that may not be the most ideal, but it may unblock you.

Hi Matthew, thanks, that’s also very useful to know I can modify the JS wrap files.
I wonder if some automated LLM solutions could be used for wrapping as that seems to be a straightforward step (?)

I guess in my case I can also manually reconstruct the tree by splitting the prim’s path by “/” but the bigger issue I have is this wasm error when I Try to get the local transform an XForm node:

const prim = stage.GetPrimAtPath(path);
prim.GetAttribute("xformOp:transform").Get();

This is giving me:

emHdBindings.js:4469 Uncaught (in promise) BindingError: _emval_take_value has unknown type N32pxrInternal_v0_24__pxrReserved__10GfMatrix4dE
    at throwBindingError (emHdBindings.js:4469:13)
    at requireRegisteredType (emHdBindings.js:6238:9)
    at __emval_take_value (emHdBindings.js:7073:14)
    at emHdBindings.wasm:0xe29bc

I wonder if that’s a bug or I’m calling it in an incorrect way? My goal is to get the local transform of a node as the current three.js based solutions take the world transform which is useful for a flat list instead of a proper hierarchy.

Thank you!

My Best guess at that error is that there is no conversion for the Matrix4d class that GetAttribute is returning back to JavaScript. In the Autodesk fork there is some plumbing to wrap some gf classes. If you look in vec3d.h you will see an emscripten helper include and at the top and a registration at the bottom. This does not seem to be present for the matrix classes which it seems like your error is eluding to.

I am not 100% sure, but it is possible that adapting the approach taken there for the matrix classes and rebuilding might fix your error and allow you to access the transform data in this case.