Guide technique · WebGL · React
Premiers pas en WebGL : afficher une scène 3D dans React
Comprendre le rôle du canvas, initialiser un contexte WebGL et construire une première scène 3D animée dans une application React.
WebGL permet d’exploiter le processeur graphique directement depuis un navigateur, sans installer de module complémentaire. Pour un développeur React, cette technologie ouvre la voie à des interfaces plus immersives : configurateur produit, visualisation de données, portfolio interactif ou arrière-plan animé. La difficulté ne consiste pas seulement à dessiner un objet, mais à organiser proprement le cycle de rendu dans le modèle déclaratif de React.
WebGL et React : deux responsabilités distinctes
React gère l’interface, l’état et le cycle de vie des composants. WebGL, de son côté, dessine des pixels dans un élément <canvas> en exécutant une suite d’instructions sur le GPU. Le bon réflexe consiste donc à laisser React créer le canvas, puis à confier le contexte graphique à une logique impérative isolée.
Un composant minimal utilise une référence pour accéder au canvas après son insertion dans le DOM. L’initialisation doit être placée dans useEffect afin de ne pas exécuter d’appel WebGL pendant le rendu serveur ou avant que l’élément existe.
import { useEffect, useRef } from "react";
export default function Scene3D() {
const canvasRef = useRef(null);
useEffect(() => {
const canvas = canvasRef.current;
const gl = canvas.getContext("webgl");
if (!gl) {
console.error("WebGL n'est pas disponible.");
return;
}
gl.clearColor(0.06, 0.09, 0.16, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
}, []);
return <canvas ref={canvasRef} width="800" height="500" />;
}
À ce stade, le navigateur efface le canvas avec une couleur bleu nuit. Ce premier test est essentiel : il valide la disponibilité de WebGL avant d’ajouter shaders, géométrie et textures. En production, prévoyez aussi un message de repli pour les appareils anciens ou les contextes graphiques désactivés.
Préparer le canvas pour tous les écrans
La taille logique d’un canvas et sa taille visuelle sont deux notions différentes. Une image étirée devient rapidement floue sur un écran haute densité. Il faut donc synchroniser sa résolution avec sa taille CSS et le ratio de pixels de l’appareil.
function resizeCanvas(canvas, gl) {
const ratio = window.devicePixelRatio || 1;
const width = Math.floor(canvas.clientWidth * ratio);
const height = Math.floor(canvas.clientHeight * ratio);
if (canvas.width !== width || canvas.height !== height) {
canvas.width = width;
canvas.height = height;
gl.viewport(0, 0, width, height);
}
}
Appelez cette fonction au début de chaque image ou lors d’un redimensionnement. Dans une scène complexe, une vérification par frame évite d’empiler des écouteurs inutiles. Le canvas peut ensuite recevoir une règle CSS simple : width: 100%, height: 420px et display: block.
Du triangle à l’objet 3D
WebGL ne connaît pas directement les cubes, les sphères ou les matériaux. Il manipule des sommets, des buffers et des programmes shader. Un premier objet 3D est généralement défini par trois éléments :
- un buffer contenant les positions des sommets ;
- un vertex shader qui transforme chaque sommet ;
- un fragment shader qui détermine la couleur des pixels.
Pour un cube, les coordonnées sont transformées par des matrices de modèle, de vue et de projection. La matrice de modèle applique la rotation, la caméra définit le point d’observation et la projection simule la perspective. Même si cette algèbre paraît abstraite, elle devient prévisible dès qu’elle est regroupée dans une petite couche dédiée.
Cette séparation rappelle une règle utile dans d’autres projets de conception : comme pour une charpente apparente, il faut distinguer ce qui porte la structure de ce qui relève de la finition. Dunezia Intérieurs aborde justement le choix entre conserver, intégrer ou relooker une charpente sans fragiliser l’existant, une logique de diagnostic qui trouve son équivalent dans l’organisation d’une scène 3D.
Créer une boucle d’animation propre
Une scène interactive doit être redessinée à chaque image avec requestAnimationFrame. La boucle met à jour la rotation, efface le framebuffer, puis dessine les buffers. Il faut conserver l’identifiant de la frame et l’annuler au démontage du composant, faute de quoi une page quittée peut continuer à consommer des ressources.
useEffect(() => {
let frameId;
let rotation = 0;
const render = (time) => {
rotation += 0.01;
// mettre à jour les matrices et dessiner la scène
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.drawElements(gl.TRIANGLES, indexCount, gl.UNSIGNED_SHORT, 0);
frameId = requestAnimationFrame(render);
};
frameId = requestAnimationFrame(render);
return () => cancelAnimationFrame(frameId);
}, []);
Pour une animation régulière, utilisez le paramètre temporel fourni par le navigateur plutôt qu’une valeur fixe. Vous obtiendrez une vitesse cohérente sur un écran 60 Hz comme sur un écran 144 Hz. Activez également le test de profondeur avec gl.enable(gl.DEPTH_TEST) pour que les faces proches masquent correctement les faces éloignées.
Quand choisir une bibliothèque 3D ?
Écrire tout le pipeline à la main est formateur, mais rarement nécessaire pour une fonctionnalité produit. Three.js simplifie les caméras, les lumières, les matériaux et le chargement de modèles. React Three Fiber ajoute une couche déclarative adaptée à React, tandis que des solutions comme Svelte ou Vue peuvent être intégrées à une architecture similaire.
Pour un projet d’équipe, l’enjeu est de choisir le niveau d’abstraction approprié. Un shader personnalisé peut rester natif, alors que la gestion d’une scène complète gagne à s’appuyer sur un moteur éprouvé. GraphHub facilite cette frontière entre design et code en centralisant les composants, les exemples SDK et la diffusion d’assets 3D via un CDN dédié.
Optimiser avant la mise en ligne
Une scène spectaculaire ne doit pas dégrader l’expérience utilisateur. Mesurez le temps d’affichage, le nombre de triangles et la mémoire consommée par les textures. Compressez les modèles, réduisez la résolution des images sur mobile et chargez les assets après le contenu critique. Un arrêt temporaire de l’animation lorsque l’onglet est masqué permet aussi de limiter la consommation énergétique.
- prévoir une version légère pour les petits écrans ;
- limiter les changements d’état React pendant le rendu ;
- utiliser des formats d’assets adaptés et un CDN ;
- tester sur un ordinateur portable et un smartphone réel ;
- ajouter une alternative accessible lorsque la 3D n’est pas disponible.
Une première scène WebGL réussie repose donc moins sur la quantité d’effets que sur une architecture claire : React orchestre l’interface, le moteur graphique dessine la scène et les ressources sont chargées avec discernement. Pour poursuivre avec des exemples de rendu temps réel et d’intégration front-end, découvrez les outils présentés sur notre page d’accueil.