Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 38

Chargement Asynchrone GLTF/GLB avec useGLTF

Recommended resources

Bonjour !

Dans la leçon précédente, nous avons ouvert la porte de l'écosystème @react-three/drei en intégrant des contrôles de caméra avec <OrbitControls /> et un moniteur de performance avec <Stats />. Nos scènes sont devenues interactives et mesurables, mais elles sont encore peuplées de formes géométriques simples.

Aujourd'hui, nous allons passer à la vitesse supérieure. L'objectif est de quitter le monde des cubes et des sphères pour intégrer des modèles 3D complexes et détaillés, créés par des artistes professionnels. C'est la clé pour construire des expériences visuellement riches comme des configurateurs de produits ou des galeries virtuelles.

À la fin de cette leçon, vous saurez charger un modèle 3D au format GLTF/GLB de manière asynchrone en utilisant le hook useGLTF.

3D F1 Car Model in a Web Application
Exemple de ce qu'il est possible de réaliser : un modèle 3D de haute qualité (ici une voiture de F1) chargé et affiché dans une application web interactive. C'est vers ce type de résultat que nous nous dirigeons.

1. GLTF : Le "JPEG" de la 3D

Avant de plonger dans le code, parlons du format de fichier que nous allons utiliser. Le GLTF (GL Transmission Format) est un standard ouvert créé par le Khronos Group (les mêmes qui gèrent WebGL). On le surnomme souvent le "JPEG de la 3D" car il est conçu pour être un format de livraison efficace, compact et rapide à charger pour les applications web.

Vous rencontrerez deux extensions de fichier :

  • .gltf : Un fichier JSON qui décrit la structure de la scène, accompagné de fichiers externes pour la géométrie (.bin) et les textures (.png, .jpg).
  • .glb : Une version binaire qui empaquette tout (JSON, géométrie, textures) dans un seul et unique fichier. C'est le format que nous privilégierons pour sa simplicité.

2. Charger un modèle : la méthode useGLTF

Dans l'écosystème React Three Fiber, l'outil de prédilection pour charger des modèles GLTF/GLB est le hook useGLTF de la librairie @react-three/drei. Il simplifie grandement le processus de chargement.

Voici les principes clés :

  1. Chargement asynchrone : Le chargement d'un modèle 3D peut prendre du temps. useGLTF gère cela en arrière-plan.
  2. Suspense de React : Puisque le chargement est asynchrone, nous devons dire à React quoi afficher pendant que le modèle charge. Pour cela, nous enveloppons notre composant 3D dans un composant <Suspense>. Il prend une prop fallback qui peut être null ou un composant JSX (par exemple, un indicateur de chargement).
  3. Affichage avec <primitive> : Une fois chargé, useGLTF nous retourne un objet contenant la scène du modèle. Pour afficher cet objet "brut" de Three.js, nous utilisons un composant spécial de R3F : <primitive>.

Pour commencer, regardez cette courte vidéo qui explique les deux approches principales pour charger un modèle. Concentrez-vous sur la seconde méthode, qui utilise useGLTF.

React Three Fiber Crash Course for Beginners

Cette vidéo de Wael Yasmina présente de manière très concise les deux façons de charger un modèle. La deuxième méthode est celle qui nous intéresse aujourd'hui.

Regardez la section intitulée "The second is almost the same" de 0:25:47 à 0:26:22. Notez la simplicité du hook useGLTF comparé à la méthode précédente (useLoader).

Maintenant, voyons cela en pratique dans un projet réel. La vidéo suivante montre la mise en place d'un configurateur de produit. Le développeur y charge un modèle de chaise.

React Three Fiber tutorial - 3D Product Configurator

Dans cet extrait du tutoriel de Wawa Sensei, vous verrez exactement comment utiliser useGLTF pour charger un fichier .gltf et l'importance du composant <Suspense>.

Regardez la section de 0:10:44 à 0:13:35. Observez bien le processus : Le modèle est placé dans le dossier public. Le hook useGLTF est appelé avec le chemin du modèle. Une erreur se produit, car le composant qui charge le modèle n'est pas enveloppé dans <Suspense>. L'ajout de <Suspense> résout le problème et le modèle s'affiche.

Pour résumer le code que vous venez de voir :

import { Suspense } from 'react';
import { Canvas } from '@react-three/fiber';
import { useGLTF, OrbitControls } from '@react-three/drei';

function ChairModel() {
  // useGLTF prend le chemin du modèle dans le dossier /public
  const gltf = useGLTF('/models/chair.gltf');
  
  // On passe la scène chargée à l'objet de la primitive
  return <primitive object={gltf.scene} scale={2} />;
}

export default function App() {
  return (
    <Canvas>
      <ambientLight intensity={0.5} />
      <directionalLight position={[10, 10, 5]} />
      
      {/* Suspense est obligatoire pour gérer le temps de chargement */}
      <Suspense fallback={null}>
        <ChairModel />
      </Suspense>
      
      <OrbitControls />
    </Canvas>
  );
}

L'objet retourné par useGLTF contient plus que la scène. Il contient aussi des listes de nodes (les maillages) et de materials. La documentation de drei est une excellente ressource pour explorer cela.

Gltf / useGLTF - Drei

La documentation officielle de drei détaille la structure de l'objet retourné par useGLTF. C'est utile pour comprendre ce que l'on manipule.

Trouvez la section "useGLTF hook". Regardez la définition des types GLTF et surtout ObjectMap. Vous y verrez les propriétés nodes et materials que nous allons bientôt utiliser.


3. Le problème de la "boîte noire" et la solution gltfjsx

La méthode avec <primitive> est simple et efficace, mais elle a un inconvénient majeur : elle traite le modèle comme une "boîte noire". Nous chargeons la scène et l'affichons en bloc. Mais que faire si nous voulons changer la couleur d'une partie spécifique du modèle, comme le coussin de la chaise, ou cacher une de ses pattes ? C'est très compliqué avec cette approche.

C'est là qu'intervient gltfjsx. C'est un outil en ligne de commande (fourni avec drei) qui va transformer votre fichier .glb ou .gltf en un composant React réutilisable.

Ce composant généré est beaucoup plus puissant :

  • Il utilise useGLTF en interne, mais expose chaque partie du modèle (nodes) et chaque matériau (materials) sous forme de props JSX.
  • Il est déclaratif : vous pouvez manipuler les différentes parties du modèle directement dans votre code JSX.
  • Il est optimisé et mémoïsé pour éviter de recharger le modèle inutilement.

La vidéo que nous avons regardée précédemment enchaîne parfaitement sur ce point.

React Three Fiber tutorial - 3D Product Configurator

Regardez maintenant comment le développeur utilise gltfjsx pour convertir le modèle de chaise en un composant React, ce qui lui donne un contrôle total sur ses différentes parties.

Regardez la section de 0:13:35 à 0:16:09. Suivez ces étapes clés : L'outil est lancé dans le terminal avec npx gltfjsx public/models/chair.gltf. Un fichier Chair.js est généré. Observez la structure du fichier généré : il contient des balises <mesh> pour chaque partie (le siège, le coussin, les pieds). Le développeur remplace l'ancien composant par ce nouveau, et peut maintenant cacher une partie du modèle simplement en ajoutant une prop visible={false}.

Après avoir utilisé gltfjsx, notre code devient beaucoup plus lisible et puissant. Au lieu de :

<primitive object={gltf.scene} />

Nous avons maintenant un composant sémantique :

<ChairModel props... />

Et à l'intérieur de ChairModel.js :

// ... imports ...

export function ChairModel(props) {
  const { nodes, materials } = useGLTF('/models/chair.gltf');
  return (
    <group {...props} dispose={null}>
      {/* On peut maintenant cibler chaque mesh individuellement ! */}
      <mesh geometry={nodes.cushion.geometry} material={materials.fabric} />
      <mesh geometry={nodes.chair_body.geometry} material={materials.wood} />
      <mesh 
        geometry={nodes.leg_1.geometry} 
        material={materials.metal} 
        visible={true} // On peut contrôler la visibilité ici !
      />
      {/* ... autres parties ... */}
    </group>
  );
}

useGLTF.preload('/models/chair.gltf'); // Pré-chargement pour la performance

Cette approche est fondamentale pour créer des applications interactives, comme un configurateur où l'utilisateur peut changer les matériaux, les couleurs ou les pièces d'un produit.


4. Atelier : Chargez votre premier modèle

Il est temps de mettre cela en pratique.

  1. Trouvez un modèle : Allez sur un site comme Sketchfab ou Poly Pizza. Cherchez un modèle simple (par ex. "chair", "table", "car"). Important : dans les filtres de recherche ou sur la page du modèle, assurez-vous qu'il est téléchargeable au format GLB ou GLTF.
  2. Préparez votre projet :
    • Utilisez le projet de la leçon précédente ou créez-en un nouveau (npm create vite@latest).
    • Installez les dépendances : npm install three @react-three/fiber @react-three/drei.
    • Créez un dossier public/models et placez votre fichier .glb à l'intérieur.
  3. Générez le composant :
    • Ouvrez votre terminal à la racine du projet.
    • Lancez la commande npx gltfjsx public/models/votre_modele.glb.
    • Un fichier VotreModele.jsx sera créé. Déplacez-le dans votre dossier src/components.
  4. Affichez le modèle :
    • Dans votre fichier App.jsx, créez une scène de base.
    • Importez votre composant VotreModele nouvellement généré.
    • Affichez-le à l'intérieur du <Canvas> et d'un <Suspense>.
    • N'oubliez pas d'ajouter des lumières et <OrbitControls /> pour bien le voir !

Votre fichier App.jsx devrait ressembler à ceci :

import { Suspense } from 'react';
import { Canvas } from '@react-three/fiber';
import { OrbitControls, Stage } from '@react-three/drei';

// Importez le composant que vous avez généré
import { VotreModele } from './components/VotreModele';

export default function App() {
  return (
    <Canvas camera={{ position: [0, 2, 5], fov: 60 }}>
      {/* Stage est un helper de drei qui centre et éclaire bien le modèle par défaut */}
      <Stage environment="city" intensity={0.6}>
        <Suspense fallback={null}>
          <VotreModele />
        </Suspense>
      </Stage>
      
      <OrbitControls autoRotate />
    </Canvas>
  );
}

Lancez votre application et admirez votre modèle 3D ! Essayez de modifier le composant généré, par exemple en changeant la couleur d'un meshStandardMaterial ou en cachant une partie avec visible={false}.


Conclusion

Félicitations ! Vous venez de franchir une étape majeure. Vous n'êtes plus limité aux formes primitives et pouvez désormais intégrer n'importe quel modèle 3D dans vos applications React.

Points clés à retenir :

  • GLTF/GLB est le format standard pour la 3D sur le web.
  • Le hook useGLTF de @react-three/drei est la méthode standard pour charger ces modèles de manière asynchrone.
  • Le chargement asynchrone requiert l'utilisation du composant <Suspense> de React pour gérer l'état de chargement.
  • Pour un contrôle total et une approche déclarative, l'outil gltfjsx est indispensable. Il transforme un fichier modèle en un composant React entièrement personnalisable.

Aperçu de la prochaine leçon :
Maintenant que nous avons un modèle de qualité, comment le faire briller ? Un bon éclairage est essentiel. Dans la prochaine leçon, nous apprendrons à mettre en place un éclairage réaliste et des reflets en quelques lignes de code seulement grâce au composant <Environment> de drei. Cela transformera radicalement l'apparence de vos scènes.