Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DRACOLoader: Web Worker support #15249

Merged
merged 12 commits into from
Aug 26, 2019
Merged

Conversation

donmccurdy
Copy link
Collaborator

@donmccurdy donmccurdy commented Nov 15, 2018

Possible solution to #13648 — a drop-in replacement for DRACOLoader, intended for use with GLTFLoader. A glTF file may contain multiple compressed meshes, and this loader allows each mesh to be decompressed by a configurable number of workers, without using the main thread. For simplicity, I omitted some functionality of DRACOLoader that glTF does not use, such as point clouds. The result is 150 lines shorter than DRACOLoader.

Usage:

var loader = new THREE.GLTFLoader();
var decoder = new THREE.DRACOLoader();
decoder.setDecoderPath( '/examples/js/libs/draco' );
loader.setDRACOLoader( decoder );
loadel.load( 'model.glb', (gltf) => ... );

The alternative would be #13664 (comment), which involves LoaderSupport. That's more code, but also has some additional features. I'm not sure how to weigh those tradeoffs at the moment.

@donmccurdy
Copy link
Collaborator Author

/cc @FrankGalligan @kaisalmen

@Mugen87
Copy link
Collaborator

Mugen87 commented Nov 15, 2018

The alternative would be #13664 (comment), which involves LoaderSupport. That's more code, but also has some additional features. I'm not sure how to weigh those tradeoffs at the moment.

TBH, I personally prefer this approach since it's a very clear and compact implementation.

@donmccurdy
Copy link
Collaborator Author

@sunag I notice you're using the Draco decoder directly in SEA3DLoader rather than using DRACOLoader — if you'd be interested in using something like this, instead, I'm glad to rename the file as WWDRACOLoader to not be glTF-specific.

@donmccurdy donmccurdy changed the title [WIP] Add GLTFDRACOLoader. [WIP] Add GLTFDRACOLoade + worker support. Nov 15, 2018
@donmccurdy donmccurdy changed the title [WIP] Add GLTFDRACOLoade + worker support. [WIP] Add GLTFDRACOLoader + worker support. Nov 15, 2018
@donmccurdy
Copy link
Collaborator Author

donmccurdy commented Nov 15, 2018

There are a couple open things here:

  • Create a new loader vs modifying or replacing DRACOLoader?
    • Prefer to replace it, but some features have been removed, so up for debate.
  • Use LoaderSupport, or not?
    • Prefer to have a standalone module for now.
  • This implementation currently downloads the draco decoder library to each worker.
    • Fixed

@kaisalmen
Copy link
Contributor

kaisalmen commented Nov 15, 2018

Edit: It was too late yesterday evening. I re-wrote the post to make it clearer.

Use LoaderSupport, or not?

The examples below configures WWDRACOLoader (sorry for the name clash) to use it for decoding of DRACO data by GLTFLoader. WLDRACOLoader is a wrapper for existing DRACOLoader and provides all means for WWDRACOLoader to use it transparently to the user of GLTFLoader with WorkerLoader (LoaderSupport should disappear in the future...):
https://github.com/kaisalmen/three.js/blob/WorkerLoader_OBJLoader/examples/webgl_loader_worker_gltf.html

PR for the preview versions of WorkerLoader & MeshTransfer (generic approach for transfer of mesh data with transferables in mind), WLOBJLoader2 (so, it could go-exist for now with OBJLoader2 V2.5.0), WLPCDLoader (Wrapper) and WLDRACOLoader + examples is now available.
Then, people can compare the approaches and evaluate pro & cons more easily. 😉

WorkerLoader and its toolbox are overkill for a single loader, but if multiple loaders are able to re-use these functions and help them flourish, then it'll pay off, because there is less need for redundant code.

@sunag
Copy link
Collaborator

sunag commented Nov 15, 2018

@sunag I notice you're using the Draco decoder directly in SEA3DLoader rather than using DRACOLoader — if you'd be interested in using something like this, instead, I'm glad to rename the file as WWDRACOLoader to not be glTF-specific.

Thank you @donmccurdy. Certainly this could happen in the next updates.

@kaisalmen
Copy link
Contributor

@donmccurdy nice that the new decoder code has no longer dependencies to three.js! 👍

@donmccurdy donmccurdy force-pushed the feat-gltfdracoloader branch from b820d32 to d938dac Compare June 19, 2019 04:20
@donmccurdy donmccurdy changed the title [WIP] Add GLTFDRACOLoader + worker support. [WIP] DRACOLoader web worker support Jun 20, 2019
@donmccurdy
Copy link
Collaborator Author

Ok, this PR is in better shape now. I think we can now answer a few of the questions mentioned earlier:

(1) Let's replace DRACOLoader, rather than adding a glTF-specific variant of it.
(2) Let's not use LoaderSupport yet. I'm willing to reconsider this once ES modules are source files perhaps, and there's certainly some potential code overlap between this and BasisTextureLoader.
(3) Issues loading the Draco library in web workers efficiently have been fixed.

There are several breaking changes from the original DRACOLoader:

  • Removed TriangleStripDrawMode support.
  • Removed quantization support (What was attribute.isQuantized? How do I test this?).
  • Removed setVerbosity, setDrawMode, and setSkipDequantization methods.
  • Changed static initialization methods to instance methods.

None of these affect usage in GLTFLoader, so the new and old versions are both compatible with the existing GLTFLoader. The initialization changes slightly:

// Before
var dracoLoader = new THREE.DRACOLoader();
THREE.DRACOLoader.setDecoderPath( 'js/libs/draco/gltf/' )
loader.setDRACOLoader( dracoLoader );

// After
var dracoLoader = new THREE.DRACOLoader();
dracoLoader.setDecoderPath( 'js/libs/draco/gltf/' )
loader.setDRACOLoader( dracoLoader );

@donmccurdy
Copy link
Collaborator Author

There are two advantages to this approach:

  1. Decoding does not block the main thread. This is true regardless of the model, and significant especially for WebXR applications.
  2. Decoding is parallelized across workers, and may or may not complete more quickly depending on the file and the device concurrency. For a model with a single mesh, it will be slower, but I consider that an acceptable tradeoff because of (1). For models with many meshes, and especially many large meshes, the load time improvement is significant.

Running tests on two glTF models with multiple meshes (attached below), here are the results:

  • matilda.glb (103 meshes, 6MB uncompressed geometry)
    • 3% load time decrease, averaged over 5 tests. (527ms -> 512ms)
  • lovecraftian.glb (18 meshes, 45MB uncompressed geometry)
    • 60% load time decrease, averaged over 5 tests. (3815ms -> 1509ms)

draco_perf_tests.zip

matilda lovecraftian
Screen Shot 2019-06-19 at 11 04 48 PM Screen Shot 2019-06-19 at 11 04 35 PM

@donmccurdy
Copy link
Collaborator Author

The file in this PR is named DRACOLoader2.js, but I'd like to update DRACOLoader directly if there are no objections to the breaking changes mentioned in #15249 (comment).

@mrdoob mrdoob added this to the rXX milestone Jun 23, 2019
@donmccurdy donmccurdy changed the title [WIP] DRACOLoader web worker support DRACOLoader: Web worker support Aug 23, 2019
@donmccurdy donmccurdy changed the title DRACOLoader: Web worker support DRACOLoader: Web Worker support Aug 23, 2019
@donmccurdy donmccurdy force-pushed the feat-gltfdracoloader branch from c102383 to bfb1c3d Compare August 23, 2019 19:35
@donmccurdy
Copy link
Collaborator Author

I've added the changes directly to DRACOLoader (not a new loader), and I think this is ready – here's a demo of my viewer, using the web workers:

https://gltf-viewer-experimental.donmccurdy.com/

@mrdoob mrdoob modified the milestones: rXX, r108 Aug 26, 2019
@mrdoob mrdoob merged commit fd500fd into mrdoob:dev Aug 26, 2019
@mrdoob
Copy link
Owner

mrdoob commented Aug 26, 2019

Thanks!

@donmccurdy donmccurdy deleted the feat-gltfdracoloader branch August 26, 2019 20:08
@mrdoob
Copy link
Owner

mrdoob commented Aug 27, 2019

Hmm... webgl_materials_cars broke...

Screenshot 2019-08-27 at 08 39 39

@donmccurdy
Copy link
Collaborator Author

#17365 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants