hmans / three-elements

Web Components-powered custom HTML elements for building Three.js-powered games and interactive experiences. 🎉
https://three-elements.hmans.co
MIT License
397 stars 14 forks source link

Support Custom Renderers #24

Open CodyJasonBennett opened 3 years ago

CodyJasonBennett commented 3 years ago

Currently, <three-game> provides a default WebGLRenderer instance, but there are cases where users would opt to use SVGRenderer, CSS2DRenderer, CSS3DRenderer, and WebGL1Renderer.

To support these renderers, we could pick up renderer elements as children of <three-game> and conditionally revert #21 for non-WebGL instances. For instance, react-three-fiber tackles this by only using renderer.setAnimationLoop when xr is enabled.

RangerMauve commented 3 years ago

Would it make sense to enable this by defining new custom elements? Like <three-svg-game>?

CodyJasonBennett commented 3 years ago

I think so, but I like your suggestion of having modified elements for <three-game> rather than child elements that merely modify its behavior. I suppose this would depend on how we deal with custom cameras, etc.

hmans commented 3 years ago

I'm tinkering with a few ideas for this. The one that feels best so far revolves around providing the various bits and pieces that are currently hardcoded into the monolithic <three-game> element as separate elements that can be combined as the user needs them, with <three-game> being reduced to just a "starter configuration" of these.

For example, we'd have <three-ticker>, <three-webgl-renderer>, <three-css-renderer>, etc., and you'd either use them directly (if you need the configurability), or through a <three-game>, <three-css-game> etc. template.

One of the downsides of this idea is the potential for namespace collisions. If we introduce a <three-ticker> element, and a future version of Three.js itself exposes a THREE.Ticker, we'll have a collision that needs to be resolved somehow.

At the same time, we've been discussing (on Discord) to establish a separate "extras" package that, similar to react-drei for react-three-fiber, provides elements that implement specific functionality (using code from Three.js' examples), like GLTF loading, Orbit Controls and so on. It's possible that there is a synergy between this and the things discussed above.

hmans commented 3 years ago

I'm tackling this now. The goal is to allow the user to create instances of these renderers by using their corresponsing <three-*> tags, eg. <three-css-3d-renderer>, and having them automatically hook up with the <three-game> element. (There is probably no need to use the newly introduced DOM CSS selector referencing here, since there will always only ever be a single renderer -- and projects where even this does not apply for some wild reason will most likely not be static HTML projects.)

hmans commented 3 years ago

PR for the first pass on this: #43

hmans commented 3 years ago

I've merged #43, which allows customization of renderers that live in the THREE.* namespace. I'm deferring support for CSS/SVG renderers to 0.4.

hmans commented 3 years ago

In the interest of pushing out a 0.4 release soon, I'm moving this to the next milestone.