Breaking down a cube in react-three-fiber
In the previous post I introduced a little bit of r3f (react-three-fiber), what it does, and why I believe it's worth looking at if you want to make performant 3D things for the web. In this post I'm going to expand on each part of the tiny example, and actually show it running.
It still doesn't do anything yet, but this only the second post.
The previous example
import React from 'react'
import ReactDOM from 'react-dom'
import { Canvas } from 'react-three-fiber'
const App = () => (
<Canvas>
<pointLight position={[5, 5, 5]} />
<mesh rotation={[45, 45, 45]}>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color="red" />
</mesh>
</Canvas>
);
ReactDOM.render(<App />, document.getElementById("root"));
It's just a tiny static cube at the moment. But we have to start somewhere, right?
What each part does
Breaking down the script we have 3 main parts. The first 3 lines are imports.
import React from 'react'
import ReactDOM from 'react-dom'
import { Canvas } from 'react-three-fiber'
These are the necessary parts to make a react app work, and then to make it work with r3f. React and ReactDOM are necessary to get a react-driven component working in the browser. They do some clever stuff that's well outside of the scope of this post, but if you're interested in reading the background head over to the React website for more details.
Canvas is the thing that drives r3f. More about that later in the post.
const App = () => (
// JSX stuff
);
ReactDOM.render(<App />, document.getElementById("root"));
The block and the last line will be familiar to anyone who's make a React app before. These set up the component that will contain our r3f content, and then ReactDOM adds it to the body of the page and sets up the necessary React code to make it do something.
This only leaves the JSX content inside of the App component. This is the r3f and Three.js bit.
<Canvas>
<pointLight position={[5, 5, 5]} />
<mesh rotation={[45, 45, 45]}>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color="red" />
</mesh>
</Canvas>
Canvas a React component that sets up a typical Three.js boilerplate, adds a canvas, fires up a WebGL context, and implements a render loop. It also creates a scene that meshes and lights can be added to. It does quite a lot.
pointLight is an instance of a THREE.PointLight. A pointlight is a light that throws out light in every direction. There are a few different types of lights in Three.JS, but this is the simplest one and handy for just the typical lights that you might use to get stated.
Finally there's the mesh. A mesh in WebGL is made up of a geometry, which is a collection of vertices and faces (and sometimes other bits), and a material that defines how it should be rendered. There is a lot of complexity in meshes and how to make them do what you want in a scene. Inside of the mesh component there's a boxGeometry, which is what the name implies eg a box, and a meshStandardMaterial that paints the box red. meshStandardMaterial is one of several different material types that Three.JS provides.
That's all there is to it. This is one of the great things about r3f - there's a ton of complexity hiding away behind those JSX tags. You don't really need to worry about it if you're making something relatively straightforward.
What are position? rotation? args?
Each of the components takes different props that the Three.JS thing it refers to is expecting.
position is a 3D position in the scene, represented by x, y, and z coordinates. Position is in 'world units', but it's easiest to think of them as metres. rotation is a 3D rotation along the x, y, and z axises in radians. Rotation in 3D apps is hard, but more on that in a later post.
args is very much dependent on the component, but they correspond to the arguments that the component constructor is expecting. boxGeometry's first three arguments correspond to the box's width, height and depth.
Modifying the cube
You can see the cube here:
(Click on "Babel" if the canvas is blank)
Click through to Codepen and play with the code there - https://codepen.io/onion2k/pen/jOrojrp. Try modifying the args to change the size of the box, or use a different color value.
The next thing to do is to make it so we can see the back of the cube, and that means moving the camera. That's coming in the next post.


