RobotLocomotion / drake

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

Contact vectors cast shadows in meshcat #21109

Open SeanCurtis-TRI opened 8 months ago

SeanCurtis-TRI commented 8 months ago

What happened?

Now that it's easier to enable shadows in meshcat, it turns out that the vector arrows for contact visualization cast shadows. Generally, we should make sure that any visualized element that doesn't represent a physical object probably shouldn't cast shadows. This includes contact vectors, hydroelastic contact meshes, frame triads, etc.

In principle, this is easily addressed. If we add a cylinder with path "/drake/foo/rod" we can prevent it from casting shadows by calling: meshcat.SetProperty("/drake/foo/rod/<object>", "castShadow", false);.

This might be slightly misleading, however. It may not be that direct for all objects that meshcat manages. For example, when glTF files get parsed, they get parsed into a subtree of three.js nodes. The call toSetProperty() above only directly sets the property on the root node of the subtree. However, the property castShadow isn't inherited. It is set uniquely on a node-by-node basis. So, depending on why kind of user-experience we want, we may need to add an additional alias to meshcat's aliased property lists (akin to what is done to opacity), where setting the opacity on the root of a sub-tree affects the whole sub-tree. But this can be deferred. Simply disabling shadow casting on the artifacts that Drake code creates as we go is sufficient to declutter the shadows.

Things that should not cast shadows:

Version

No response

What operating system are you using?

No response

What installation option are you using?

No response

Relevant log output

No response

SeanCurtis-TRI commented 8 months ago

If you want to see the current shadow behavior, you can do something like:

  1. Run bazel run examples/hydroelastic/python_nonconvex_mesh:drop_pepper_py.
  2. Set the following values (shown in the image below):
    • /Lights/PointLightNegativeX, visible, false.
    • /Lights/PointLightPositiveX/<object>, castShadow, true.
    • /drake/illustration/bowl, visible, false
    • /drake/illustration/yellow_bell_pepper_no_stem, visible, false.
  3. Observe the shadows cast onto the semi-transparent table.

image

jwnimmer-tri commented 8 months ago

As I understand it, the castShadow property is a standard https://threejs.org/docs/#api/en/loaders/ObjectLoader property (along with many others like receiveShadow or frustumCulled), that is obeyed by Meshcat when loading the object (modulo any defects in Meshcat) -- see here.

Of course we can always do a SetProperty after the fact, but maybe it's worth considering allowing the user to specify those properties up front when calling Meshcat::SetObject, for convenience. If we think most every call site needs should acutely consider whether the object should have shadows, putting that front and center in the API design might help encourage it.