For a few years now, one of my free-time projects has been to start answering the question "what would HTML elements with 3D powers be like?"
The project is Lume, working towards a 1.0 release. Lume provides a set of HTML elements for 3D rendering, built on three.js for rendering, with a system for defining new custom HTML elements with reactivity and templating powered by Solid.js.
Here is Lume's "hello world" example.
Paste that code into a CodePen pen, and you will have a demo that simply works (no build tools required!):
In this Disco Helmet example, remove the enable-css="false"
attribute, inspect the elements in your browser devtools, hover on a <flickering-orb>
element, and notice that the browser will natively show you the position of the 3D object in the view, and that we can change the color of a light right from the inspector:
We removed the enable-css="false"
attribute (it defaults to true) to make Lume apply CSS 3D transforms to the elements. Lume's CSS transforms are aligned with the WebGL transforms, which is what tells Chrome devtools where WebGL objects are located on the screen. This is nifty for development and debugging! We didn't have to install additional devtools like we would with React, Vue, Svelte, etc. Custom HTML elements are simply supported out of the box by browser devtools!
With CSS rendering enabled using enable-css="true"
, we get the ability to combine today's standard built-in HTML elements with Lume's 3D elements. The next demo shows the browser's built-in <button>
elements mixed with Lume's WebGL rendering. Right click and inspect the buttons!
This is powerful because it means we can use all of today's HTML/CSS abilities inside of a 3D space with additional graphical powers, gaining accessibility of 3D content.
3D content made with Lume is not only more accessible to humans, but also to robots such as
- screen readers
- search engines
- automation and design tools
- and AI
Here is Lume in the wild, in an app called Neo Fairies that gives players the ability to own characters in a fantasy-punk open world:
Besides 3D elements, Lume also provides Lume Element, a system for defining custom elements. The next demo shows a <name-card>
element that has no relation to Lume's 3D elements. It is a custom element that is composed only of today's built-in elements. None of Lume's 3D features are loaded in the next demo, only the necessary pieces for making Custom Elements are imported and downloaded:
In a following article, I'll describe additional features that Lume builds on top of Three.js, as well as more details on parts of Lume's road map which include:
- 3D elements for geospatial globe/planet rendering powered by lume/harp.gl
- AR/VR/MR/XR controls
- 3D-oriented UI component library with the ability to transition from 2D UIs into 3D XR UIs
- HTML elements for applying physics to objects
- 2D and 3D layouts
- Server-side rendering of 3D scenes for simple resumability and link sharing of 3D experiences
- Compilation of Lume's TypeScript codebase to WebAssembly and native, including Three.js and Solid.js (more on this later!)
- A no/low/full-code creative studio and IDE with AI assisted asset and code generation
- And more...
I'm excited to see where HTML 3D can go. We have some fun work ahead!
Top comments (8)
The stuff you build is amazing as always, Joe. Looking forward to lume 1.0!
Thanks Alex! Can't wait to release 1.0! :D
Looks amazing! Thanks for sharing.
love your content and love threejs
Love this Thanks
Cool! Got any inspiration from VRML from back in the days? 🤠
I have indeed checked out VRML and X3D. I also met Tony Parisi, and he gave me some kudos on the project! The VRML syntax reminds me of Qt's QML.
I'd like to add some of the lower level features of VRML/X3D to Lume, but first and foremost I am focusing on the most human-friendly higher-level set of HTML elements to make it practical to write content easily by hand. In this sense I'm borrowing ideas from Threejs's scene graph which is fairly human friendly at a high level (though it also allows access to all the low levels, array buffers, etc). Apple Safari's new
<model>
element is an example of starting with the high level for the human developers: it loads and renders 3D models, and provides a few controls for the camera positioning, but that's about it.In Lume, there isn't a way to express vertices via HTML yet, but it can load GLTF models with a
<lume-gltf-model>
element, and has basic geometries, lights, cameras, etc. It is more like A-Frame in the sense of initial simplicity for human-written scenes, whereas VRML and X3D have a lot of complexity akin to GLTF. A higher-level HTML interface will be nice for integrating assets into web apps that use React, Vue, Angular, Svelte, Solid, jQuery, etc. Lume's first backend is in Three.js, and does allow access to all the underlying Three.js objects for people who need more control (planning a Babylon backend later).Some interesting work we are now doing, that we couldn't do in the time of VRML during the early days of web, is imagining what sorts of APIs 3D elements could have if they became native elements of browsers considering all the new standards we now have. As an example, we have a pull request in progress to add Pointer Events to the 3D elements (
click
,pointerup
,pointerdown
,pointermove
, etc), and these events work the same as on the current native elements, but now we get additional 3D info like.offsetZ
,worldX/Y/Z
, etc, on the events. This makes these new 3D elements immediately compatible with all those DOM frameworks that currently rely on the standard events.Wonderful, the css is just as powerful!