google / model-viewer

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

Consider using Custom Elements inside a ShadowRoot for the "3DOM" #4396

Closed trusktr closed 1 year ago

trusktr commented 1 year ago

To align with standards, and to really prototype what a future 3D spec of builtin 3D element could be like, consider using Custom Elements inside the ShadowRoot of .

By having a plain JS "3DOM" that isn't actually DOM, and isn't related to HTML, then it will not be compatible with all DOM tools (React, Vue, Svelte, etc) in the future.

For example, suppose that <model-viewer>'s ShadowRoot has something like this:

<mode-viewer ...>
  <#shadow-root>
    <!-- ... other stuff -->
      <scene-3d>
        <point-light position="..." color="..." ...></point-light>
        <!-- Take note of this! -->
        <slot name="camera">
          <orbit-camera ...></orbit-camera>
        </slot>
        <gltf-model position="..."></gltf-model>
        <!-- ... etc ... -->
      </scene-3d>
    <!-- ... other stuff -->
  </#shadow-root>
</mode-viewer>

This would open up huge doors for the HTML future, including automatically compatibility with any DOM frameworks. For example, someone in React, Vue, Solid.js, etc, could write this to replace the camera with their own:

return <model-viewer ...>
  {/* User overrides the camera to view the scene any way they want. */}
  <perspective-camera slot="camera" position={thePosition}></perspective-camera>
</model-viewer>

Note in the sample that the user of some components system overrode the camera and in this sample used JSX templating to pass the desired position using a variable called thePosition.

The current "3DOM" is entirely separate from real DOM, and therefore not compatible with all the DOM tools we've spent a long time making. Users will have to break out of their systems and go into vanilla JavaScript in order to manipulate that separate 3DOM.

Instead, if we use actual DOM, users will be able to even use jQuery if they really want, etc.

I'm thinking about this over at https://lume.io (currently rendered with Three.js), and would like to get those elements to be as standards aligned as possible, to ideate what a really adoptable "3DOM" could be like. One thing I'm merging next is Pointer Events, where it works just like you'd expect with today's non-3D DOM, but the events have additional properties like offsetZ, worldX, etc. If we build with more DOM standards in mind (making the "scene graph" DOM aligned too), I think we could more quickly get to a state where we have native 3D HTML elements.

We might even be able to sway Safari's <model> element to be more DOM aligned. It is currently also making a separate non-DOM JavaScript API al la 3DOM with no HTML in mind, which means no compatibility (as far as manipulating the scene graph goes) with the huge ecosystem of declarative-reactive web frameworks.

GLTF is a standard that isn't so human friendly, but really great at containing all the features graphics tend to describe for machine transmission, but what we may be able to do take a subset of GLTF features and spec out the simplest APIs that HTML users would want to write by hand, using a top-down approach starting with the simplest high level APIs.

Alternatives to Lume include A-Frame and three-elements.