Skip to content

Loading Models

Fresh

There are many types of 3D model extensions. This page focuses on loading the three most common ones: GLTF, FBX and OBJ. All of these will use the useLoader function.

This section assumes 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

GLTF is the open standard with the most support in React Three Fiber.

js
import { useLoader } from '@react-three/fiber'
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'

Create a Model component:

jsx
function Scene() {
  const gltf = useLoader(GLTFLoader, '/Poimandres.gltf')
  return <primitive object={gltf.scene} />
}

Loading GLTF Models as JSX Components

You can transform GLTF models into React components and use them like any React component.

Grab your GLTF model and use the GLTFJSX tool (gltf.pmnd.rs) to generate a component. The output will look like:

jsx
/*
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')

Now import and use the model like any React component:

jsx
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>
  )
}

Loading OBJ Models

Use the trusted useLoader hook with three.js's OBJLoader:

js
import { OBJLoader } from 'three/addons/loaders/OBJLoader.js'
import { useLoader } from '@react-three/fiber'
jsx
function Scene() {
  const obj = useLoader(OBJLoader, '/Poimandres.obj')
  return <primitive object={obj} />
}

Loading FBX Models

Use useLoader with three.js's FBXLoader:

js
import { useLoader } from '@react-three/fiber'
import { FBXLoader } from 'three/addons/loaders/FBXLoader.js'
jsx
function Scene() {
  const fbx = useLoader(FBXLoader, '/Poimandres.fbx')
  return <primitive object={fbx} />
}

Loading FBX Models with useFBX

@react-three/drei exports a convenient useFBX helper:

jsx
function Scene() {
  const fbx = useFBX('/Poimandres.fbx')
  return <primitive object={fbx} />
}

No need to import anything from three.js — it is all handled behind the scenes.

Showing a Loading Indicator

If your model is large and takes a while to load, show a loading indicator using Html and useProgress from @react-three/drei:

  • Html — place plain HTML in your canvas and render it like a normal DOM element
  • useProgress — a hook that gives you information about the loading status of your model
jsx
import { Html, useProgress } from '@react-three/drei'

function Loader() {
  const { progress } = useProgress()
  return <Html center>{progress} % loaded</Html>
}

Wrap your model in a Suspense with the Loader as fallback:

jsx
export default function App() {
  return (
    <Canvas>
      <Suspense fallback={<Loader />}>
        <Model />
      </Suspense>
    </Canvas>
  )
}

useProgress returns much more than just progress — you can access total loaded bytes, active items, errors, and more.