Posted at Sat Aug 21 2021
Hello, today I would like to share how to make 3D Web app using @react-three/fiber and lastly, how to import your Blender model to Web.
I used
Next.js
in my recent 3D projects, but it's not required. You can use any React
boilerplate/starter you want (Next, CRA, etc).
You need
Blender
software if you want to use CAD for creating your 3D model.
You can install required dependencies using:
npm i three @react-three/fiber
Let's do simple "hello world" by rendering simple Box in our scene:
import ReactDOM from "react-dom";
import { Canvas } from "@react-three/fiber";
function Box(props) {
return (
<mesh {...props}>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color="orange" />
</mesh>
);
}
ReactDOM.render(
<Canvas>
<pointLight position={[-2, 2, 10]} />
<Box position={[2, -2, 0]} scale={1} />
</Canvas>,
document.getElementById("root")
);
Alongside the box, we also render a
light
so that we can see our object on scene. You can set the position for
the Box with
Vector3
(3 item array: x, y, z). You'll use Vector3 a lot since it's the most
basic unit in 3D, it'll be used for object position, scale, rotation,
etc.
Three.js offers basic geometries that you can use direcly such as Box,
Sphere, and so on. They're good for procedural rendering which don't
have model loading cost. For instance, you want to render simple chess
tiles, or simple plane, you might not need to import Model at all.
In most cases, you'll create your model in CAD software and import
them to another medium (Web, Unity, etc). Three.js allows you to
import model from CAD software (Blender, Maya, etc) by using glTF
extension, it's one of standard format for 3D scenes and model.
From Blender UI, you can export by click menu File > Export > glTF 2.0
You can save as "hello.gltf" for now.
We'll use another helper package for handling glTF loading. Let's
install:
npm i @react-three/drei
We need to convert our glTF into React Three Fiber format, we can use
https://gltf.pmnd.rs/
for that. Go to the site, drag and drop your glTF, and you can copy paste your
Model component from there. The site also previews your model and
you'll get something like:
// Auto-generated by: https://github.com/pmndrs/gltfjsx
import React, { useRef } from 'react'
import { useGLTF } from '@react-three/drei'
export default function Model(props) {
const group = useRef()
const { nodes, materials } = useGLTF('/hello.gltf')
return ( ...
Next, copy your glTF file into your public
folder, it should be
accessible from your server host. (e.g. http://localhost/hello.gltf)
Finally, you can import your model into your scene:
import Model from './Model'
...
<Canvas>
<Suspense fallback={null}>
<Model position={[0.2, -1.3, 0.5]} />
</Suspense>
<pointLight position={[-2, 2, 10]} />
</Canvas>
Congrats! Your model finally shows up on your Web! One more thing, you
might notice that we use React Suspense
to handle potential asset
loading state from our Model.
As a bonus, you can use drei Stage for fast Scene prototyping like
Camera, Light setup, etc. Example:
import React, { Suspense, useRef } from "react";
import { Canvas } from "@react-three/fiber";
import { OrbitControls, Stage } from "@react-three/drei";
import Model from "./Model";
...
const ref = useRef();
...
<Canvas>
<Suspense fallback={null}>
<Stage
controls={ref}
preset="rembrandt"
intensity={1}
environment="city"
>
<Model />
</Stage>
</Suspense>
<OrbitControls ref={ref} autoRotate />
</Canvas>
You can also fork my Codesandbox here for complete code
Antony Budianto
Software Engineering, Web, and some random life thoughts.