RobotLocomotion / drake

Model-based design and verification for robotics.
https://drake.mit.edu
Other
3.26k stars 1.26k forks source link

Better caching of meshes in Meshcat #19598

Closed jwnimmer-tri closed 2 months ago

jwnimmer-tri commented 1 year ago

There are probably some low-hanging fruit speed ups that would improve the boot-up time when repeatedly re-running the same or similar simulations.

(1) Don't send the mesh file contents inside the websocket set object message and instead only send a URL for the mesh contents. The meshcat.cc will serve the mesh contents over http when requested.

(1b) It's a small tweak to meshcat.html or meshcat.js (can't remember which) to fetch mesh contents over http. It's the same hook as we use for loading mtl files currently, just in the opposite direction.

(2) Be smart about the http url design so that browser caching kicks in. Use a content-addressable scheme (i.e., use the sha256 as the URL, not the filename) so that the browser will cache the file indefinitely. This cuts the cost of transmitting the mesh data to near-zero (on average). All that remains is parsing in the browser.

(3) The code already has "uuid"s as discussed in the code here. Get that working (so that duplicated objects are shared), and try to ensure that the same mesh (content-addressable) has the same uuid so that reloading the scene preserves the gpu vertex buffers.

pathammer commented 1 year ago

I suspect once caching is implemented parsing will be the new bottleneck. It would be good to confirm meshcat is parsing meshes with the OBJLoader2Parallel using web workers.

jwnimmer-tri commented 8 months ago

The discussion at https://github.com/meshcat-dev/meshcat-python/pull/112#issuecomment-1149588793 covers some ideas on the JS side.

jwnimmer-tri commented 7 months ago

The work on speedups is moving along in earnest.

Loading glTF objects is about 2x faster now with #20877, and I have another 2x waiting in the wings (using KTX2 for textures). Those are speed-ups just in cold boot time, with no special caching.

We do expect to our efforts on speed moving forward to focus on glTFs more than OBJs. The glTF format is much better designed for efficiently transferring and re-using data, and will scale better as we aim for large and more complex scenes. Users who really care about large-scene speed should consider a transition plan away from OBJ to glTF instead. (The texture/material support vocabulary is hugely better in glTF, also.) We aspire to have Drake's render engines continue to improve their support of glTF as well.

For OBJs my current thought is to re-wire the PNG texture loading to be more efficient, but probably not to try to improve the OBJ geometry load/parse time itself.

The new code does use http content-addressable caching, so for users that operate over a non-localhost connection between their browser and Drake's Meshcat might see some small improvements in case network latency was part of their problem.

I haven't yet really dug in to find warm-start kinds of caching on the JS side. So far, there's enough fruit making the cold-boot faster that I plan to focus my efforts there until it's tapped out.

jwnimmer-tri commented 7 months ago

With improvements like #20877 finished and #20935 on the way, the cold-boot times are improving. Even though I've talked about some of the cold-boot topics in this issue, I'm going to re-focus this issue to be only about speed-ups due to mesh caching.

In particular, probably the most valuable use case to speed up with caching would be loading N copies of the same robot arm into one scene, e.g., to animate several different possible trajectories, or to show some expected postures along one trajectory. Or in short, the typical case of having 1 copy of some geometry and instancing it multiple times in the scene. It would be equally relevant to e.g. having a pile of 5 identical mugs in the sink.

jwnimmer-tri commented 2 months ago

For the moment, we've sufficiently solved our performance problems by content-pinning the glTF assets.

Trying to optimize 5 instances of the same mesh is more technically challenging (dealing with texture refcounting on the JS side), so I don't plan to attempt that anytime soon.