google / model-viewer

Easily display interactive 3D models on the web and in AR!
https://modelviewer.dev
Apache License 2.0
6.92k stars 816 forks source link

Support draco encoded glTFs #72

Closed jsantell closed 4 years ago

jsantell commented 5 years ago

In the future.

cdata commented 5 years ago

This issue should probably tie back into #35 , which is our best proxy for general GLTF support.

donmccurdy commented 5 years ago

For a rough overview of the work required:

GLTFLoader can be configured with a DRACOLoader instance:

var loader = new THREE.GLTFLoader();
THREE.DRACOLoader.setDecoderPath( '/examples/js/libs/draco' );
loader.setDRACOLoader( new THREE.DRACOLoader() );

DRACOLoader is small, and can be included in the bundle. If the model uses Draco compression, GLTFLoader will automatically defer to DRACOLoader, which in turn loads either (1) the JS decoder, or (2) the WASM decoder based on browser support. Including both decoders in the bundle is probably impractical, so I think end-users may have to host the decoder libs alongside their model. Here are the libs: https://github.com/mrdoob/three.js/tree/dev/examples/js/libs/draco/gltf.

Will likely need at least one attribute, e.g. draco-decoder-path="path/to/decoders", added.

donmccurdy commented 5 years ago

Hm I don't know the status of magic leap support here.

johnpallett commented 5 years ago

@rcabanier do you know whether magic leap supports Draco decoding?

rcabanier commented 5 years ago

Can you provide a pointer to draco? Is it a new format or a preprocessor?

donmccurdy commented 5 years ago

@rcabanier Draco is a compression library. It can be used as a standalone format (.drc) but more often it is used as a compression scheme within a glTF model, through the KHR_draco_mesh_compression extension. It's that glTF extension we're interested in here. Typically this reduces the size of the geometry (not textures or animation) in the model by 85–95%. glTF files using Draco can be decoded in a preprocess step, or during the normal loading process using the provided decoders.

Glad to provide more technical details and example models if that would be helpful. :)

rcabanier commented 5 years ago

I asked the team. They looked into it but it’s not on the roadmap yet.

If we can convert it as a JavaScript preprocessing step, we can easily add it to prismatic.

rcabanier commented 5 years ago

@donmccurdy is there a way to convert from a Draco compressed gltf to a regular one?

rcabanier commented 5 years ago

Also, do you have data on how common these types of gltf are?

donmccurdy commented 5 years ago

Hi @rcabanier β€” you can convert both ways (compressed <--> uncompressed), the compression is lossy but otherwise reversible.

One popular tool that implements this is glTF-Pipeline. This tool is useful for authoring and testing, but relies on node.js and the Cesium engine so you wouldn't want to ship it in Prismatic I imagine.

Re-implementing that decompression in Prismatic should be straightforward enough, but does require that you use the Draco WASM, JS, or native decoding library.

Draco compression is a popular optimization for glTF users, particularly on web for bandwidth considerations, but typically that compression is added manually β€” asset libraries like Sketchfab, Poly, and TurboSquid do not distribute glTF files that are already compressed. Most authoring tools (e.g. Blender, Substance Painter) also output uncompressed files, the only exception I know of is Adobe Dimension 2.0, which outputs compressed files with the Draco extension.

jbrettle commented 5 years ago

@rcabanier @donmccurdy We're seeing Draco adoption quite a bit in applications like ecommerce, mapping, and assets captured through photogrammetry. As Don mention, much of compression is done outside the major asset libraries, although we're starting to see more authoring tools have plug-ins for Draco-gltf export currently or the near future (Maya, blender)

rcabanier commented 5 years ago

Thanks for all the information. I will look into getting support for this compression scheme for LuminOS.

webprofusion-chrisc commented 5 years ago

Hi folks, sorry to be effectively leaving a +1 but Draco support is basically essential for remotely realistic 3D models and I don't know how you're managing without it (all your models are low poly?). The benefits are absolutely enormous (unlike the file sizes). As Don mentioned Three already has good working Draco decompression available in conjunction with GLTFLoader.

Assuming a target audience for the model viewer is things like online shopping etc, this probably needs some attention again. Facebook have the same problem with 3d posts not supporting draco either, combined with capped file sizes, hobbling the usefulness of the feature.

To give some perspective, in my own use case draco cuts model sizes (and therefore user wait times) from 14mb to 2mb (for example). Big models are common when starting from CAD model sources rather than designing them to be low poly from the start.

cdata commented 5 years ago

@webprofusion-chrisc good news! If you check our project board, you'll see that DRACO support is on deck for this sprint.

sorry to be effectively leaving a +1

No apologies needed, we love getting feedback πŸ™Œ

I don't know how you're managing without it

Basic glTF support was, of course, the first order of business. There is a lot of free content available in non-compressed glTF, so basic support has been suitable as we have ramped up the project.

It's also worth noting that DRACO support will add significant byte size and some complexity to the <model-viewer> payload.

donmccurdy commented 5 years ago

@cdata it may be worth looking at this PR, rather than the checked-in version of DRACOLoader: https://github.com/mrdoob/three.js/pull/15249. In particular using workers will prevent <model-viewer/> from hanging the rest of the page, and will parallelize decoding when multiple viewers are present.

cdata commented 5 years ago

Thanks for the heads up @donmccurdy . I had mistakenly assumed that the DRACO loader was already usable from a worker.

What outstanding work is remaining to get that PR merged?

donmccurdy commented 5 years ago

The GLTFDRACOLoader class in that PR is compatible with the GLTFLoader already, because it has the same API as the older class and can be provided similarly:

gltfLoader.setDRACOLoader( dracoLoader );

So it doesn't strictly have to be merged, but I would eventually liked to get it submitted, and the remaining items are listed here: https://github.com/mrdoob/three.js/pull/15249#issuecomment-439102607. (1) and (2) only affect merging it into three.js, but (3) may affect performance and is relevant here.