Using with three.js
Being a framework based on three.js, A-Frame provides full access to the three.js API. We’ll go over how to access the underlying three.js scene, objects, and API that lay underneath A-Frame.
Table of Contents
- Relationship Between A-Frame and three.js Scene Graphs
- Accessing the three.js API
- Working With three.js Objects
<a-scene>maps one-to-one with a three.js scene.
<a-entity>maps to one or more three.js objects.
- three.js’s objects have a reference to their A-Frame entity via
.el, which is set by A-Frame.
When A-Frame entities are nested in parent-child relationships, so are their three.js objects. For example, take this A-Frame scene:
The three.js scene graph will correspond and look like:
three.js is available as a global object on the window:
A-Frame is an abstraction on top of three.js, but we still operate with three.js underneath. A-Frame’s elements have doors that lead to three.js’s scene graph.
The three.js scene is accessible from the
<a-scene> element as
And every A-Frame entity also has a reference to
From a component, we access the scene through its entity (i.e.,
Every A-Frame entity (e.g.,
<a-entity>) has its own
THREE.Object3D, more specifically a
THREE.Group that contains different types of
Object3Ds. The root
THREE.Group of an entity is accessed via
Entities can be composed of multiple types of
Object3Ds. For example, an entity can be both a
THREE.Mesh and a
THREE.Light by having both a geometry component and light component:
Components add the mesh and light under the entity’s root
THREE.Group. References to the mesh and light are stored as different types of three.js objects in the entity’s
But we can access them through the entity’s
Now let’s see how these three.js objects were set in the first place.
Object3D on an entity adds the
Object3D to the entity’s
Group, which makes the newly set
Object3D part of the three.js scene. We set the
Object3D with the entity’s
.setObject3D(name) method where the name denotes the
For example, to set a point light from within a component:
We set the light with the name
light. To later access it, we can use the entity’s
.getObject3D(name) method as described before:
And when we set a three.js object on an A-Frame entity, A-Frame will set a reference to the A-Frame entity from the three.js object via
There’s also a
.getOrCreateObject3D(name, constructor) method for creating and setting an
Object3D if one has not been set with the name. This is commonly used in the case of
THREE.Mesh when both the geometry and material components need to get or create a mesh. Whichever component gets initialized first creates the mesh, then the other component gets the mesh.
To remove an
Object3D from an entity, and consequently the three.js scene, we can use the entity’s
.removeObject3D(name) method. Going back to our example with the point light, we remove the light when the component is detached: