Loading Models
3D Software to the web!
All the models in this page were created by Sara Vieira and are freely available to download from any of the sandboxes.
There are many types of 3D model extensions, in this page we will focus on loading the three most common ones:
GLTF
,FBX
andOBJ
. All of these will use theuseLoader
function but in slightly different ways.This whole section will assume you have placed your models in the public folder or in a place in your application where you can import them easily.
Loading GLTF models
Starting with the open standard and the one that has more support in React Three Fiber we will load a
.gltf
model.Let's start by importing the two things we need:
import { useLoader } from '@react-three/fiber' import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
With this we can create a Model component and place it in our scene like so:
function Scene() { const gltf = useLoader(GLTFLoader, '/Poimandres.gltf') return <primitive object={gltf.scene} />
You can play with the sandbox and see how it looks here after I added an HDRI background:
GLTFLoader
Loading GLTF models as JSX Components
Here comes the really fancy part, you can transform these models into React components and then use them as you would any React component.
To do this, grab your
GLTF
model and head over to https://gltf.pmnd.rs/ and drop yourGLTF
, after that you should see something like:Let's now copy the code and move it over to
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 groupRef = useRef() const { nodes, materials } = useGLTF('/Poimandres.gltf') return ( <group ref={groupRef} {...props} dispose={null}> <mesh castShadow receiveShadow geometry={nodes.Curve007_1.geometry} material={materials['Material.001']} /> < mesh castShadow receiveShadow geometry={nodes.Curve007_2.geometry} material={materials['Material.002']} /> </group> useGLTF.preload('/Poimandres.gltf')Model.js
:Now we can import our model like we would import any React component and use it in our app:
import { Suspense } from 'react' import { Canvas } from '@react-three/fiber' import { Environment } from '@react-three/drei' import Model from './Model' export default function App() { return ( <div className="App"> <Canvas> <Suspense fallback={null}> <Model /> <Environment preset="sunset" background /> </Suspense> </Canvas> </div>
You can play with the sandbox here:
gltfjsx
Loading OBJ models
In this case, we will use the trusted
useLoader
hook but in combination withthree.js
OBJLoader
.import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader' import { useLoader } from '@react-three/fiber'
With these imported let's get the mesh into our scene:
function Scene() { const obj = useLoader(OBJLoader, '/Poimandres.obj') return <primitive object={obj} />
And here we go, we have an OBJ model showing on the web! Pretty cool ah?
You can play with the sandbox here:
OBJLoader
Loading FBX models
Let's again use the trusted
useLoader
but this time with theFBXLoader
that comes fromthree.js
import { useLoader } from '@react-three/fiber' import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader'
To create our scene we can get the FBX as a return value of the useLoader by passing the
FBXloader
and the location of our file like so:function Scene() { const fbx = useLoader(FBXLoader, '/Poimandres.fbx') return <primitive object={fbx} />
You can play with the sandbox here:
FBXLoader
Loading FBX models using useFBX
@react-three/drei exports a very useful helper when it comes to loading FBX models and it's called
useFBX
, in this case there is no need to import anything fromthree.js
as it is all done behind the scenes and we can just pass the location of the file touseFBX
like so:function Scene() { const fbx = useFBX('/Poimandres.fbx') return <primitive object={fbx} />
You can play with the sandbox here:
useFBX
Showing a loader
If your model is big and takes a while to load, it's always good to show a small loader of how much is already is loaded and again @react-three/drei is here to help with
Html
anduseProgress
.Html
allows you place plain ol' HTML in your canvas and render it like you would a normal DOM element.useProgress
is a hook that gives you a bunch of information about the loading status of your model.With these two things, we can create a very bare-bones loading component like so:
import { Html, useProgress } from '@react-three/drei' function Loader() { const { progress } = useProgress() return <Html center>{progress} % loaded</Html>
We can then wrap our model in it using
Suspense
like so:export default function App() { return ( <Canvas> <Suspense fallback={<Loader />}> <Model /> </Suspense>