Three.js de A à Z
Sans plugin, sans installation, sans carte graphique de compétition : comment une bibliothèque JavaScript née en 2010 a mis la 3D temps réel dans un simple onglet, ce qu'on en fait de sérieux, et ce qu'on en fait de complètement décalé.
1. C'est quoi Three.js ? La big picture pour démarrer
Définition simple
Three.js est une bibliothèque JavaScript open source (licence MIT) qui permet d'afficher et d'animer de la 3D en temps réel dans une page web. Elle s'appuie sur les interfaces graphiques du navigateur, WebGL hier et WebGPU aujourd'hui, et vous évite d'avoir à leur parler directement : là où l'API brute demande une centaine de lignes pour afficher un triangle, Three.js affiche un cube qui tourne en une quinzaine.
Le résultat tient dans un lien. Pas d'application à installer, pas de store, pas de plugin : la même scène tourne sur un PC, un téléphone, une tablette ou un casque de réalité virtuelle, à partir du même code.
Trois objets, et tout le reste en découle
Un conteneur d'objets, de lumières et de caméras, organisé en arbre.
Position, orientation, angle de vue. Perspective ou orthographique.
Transforme scène + caméra en pixels, sur un
<canvas>.Chaque objet visible est un Mesh : une géométrie (la forme, faite de triangles) habillée d'un matériau (la façon dont la surface réagit à la lumière). Le reste de la bibliothèque, chargeurs de modèles, contrôles de caméra, animation, réalité virtuelle, n'est que de l'outillage autour de ce noyau.
Les chiffres du projet Vérifiés le 8 septembre 2026
Le rythme de publication est soutenu : une version toutes les six à dix semaines ces derniers mois, chacune identifiée par un numéro précédé d'un r (pour release). Sur npm, r186 s'appelle 0.186.0. Ce n'est pas du versionnage sémantique : n'importe quelle version peut changer une API, d'où l'importance d'épingler la version que vous utilisez (voir la section 5).
Ce que Three.js n'est pas
- Pas un moteur de jeu complet. Pas de physique intégrée, pas d'éditeur de niveaux, pas de gestion de sauvegardes ni de réseau. Three.js dessine ; le reste se choisit à côté (section 10).
- Pas un logiciel de modélisation. Les modèles se fabriquent dans Blender ou équivalent, puis s'importent (au format glTF de préférence).
- Pas de la magie. Une page 3D consomme du processeur graphique et de la batterie. Savoir ce qui coûte cher est la moitié du métier (section 9).
2. Petite histoire de la 3D dans le navigateur De la demoscene au WebGPU
2009-2010 Un moteur Flash devient JavaScript
Ricardo Cabello, connu sous le pseudonyme Mr.doob, développeur espagnol issu de la demoscene, porte son moteur 3D écrit en ActionScript (Flash) vers JavaScript. Première publication sur GitHub le 24 avril 2010. À l'époque, WebGL n'existe pas encore dans les navigateurs : Three.js dessine en Canvas 2D et en SVG.
2011 WebGL 1.0 et le premier film interactif
En mars, WebGL 1.0 arrive dans Firefox 4 et Chrome ; Paul Brunt ajoute un moteur de rendu WebGL à Three.js. En mai, Google publie « 3 Dreams of Black », film interactif de Chris Milk pour le groupe ROME : trois mondes oniriques construits avec Three.js, code source ouvert. La preuve que la 3D dans le navigateur peut être un objet artistique.
2012 HexGL : un jeu de course par un seul étudiant
Thibaut Despoulain, étudiant français en informatique, publie HexGL, un jeu de course futuriste dans la lignée de Wipeout et F-Zero, jouable dans un onglet. Il est encore en ligne, et son code est sous licence MIT.
2017 WebGL 2.0
Chrome 56 et Firefox 51 apportent WebGL 2.0, basé sur OpenGL ES 3.0 : plus de types de textures, rendu multi-cible, instancing natif. Three.js en fait son mode par défaut à partir de la version r118. Safari suivra en 2021 avec la version 15.
2019 Le portfolio que l'on conduit
Bruno Simon, développeur créatif français, met en ligne un portfolio où l'on conduit une petite voiture pour renverser les titres de ses projets, avec une physique gérée par Cannon.js. Le site devient la référence d'une génération de créatifs, et son auteur lance ensuite le cours Three.js Journey.
2023 WebGPU dans Chrome 113
Le successeur de WebGL, conçu pour les GPU modernes (Vulkan, Metal, Direct3D 12), s'active par défaut dans Chrome et Edge 113 en mai. Il apporte notamment les compute shaders, c'est-à-dire du calcul général sur GPU, hors rendu.
2025 Safari et Firefox rejoignent WebGPU
Firefox 141 l'active en juillet, sur Windows uniquement ; Safari 26 et iOS 26 le livrent en septembre. Three.js, qui préparait son WebGPURenderer depuis des années, bascule l'essentiel de son effort de développement dessus.
2026 r186, TSL et un portfolio réécrit
La version r186 sort le 8 septembre 2026. Le langage de shaders maison, TSL, permet d'écrire un même matériau pour WebGL et WebGPU. Bruno Simon republie son portfolio entièrement refait avec cette technologie, code source sous licence MIT. La boucle est bouclée : ce qui demandait une équipe de Google en 2011 est devenu un projet personnel documenté sur YouTube.
3. Sous le capot : la science du pixel Triangles, shaders, matrices et 16 millisecondes
Tout est triangle
Un processeur graphique ne sait dessiner que trois choses : des points, des lignes et des triangles. Une sphère « lisse » à l'écran est en réalité une mosaïque de quelques centaines à quelques milliers de triangles, dont les arêtes sont gommées par le calcul de l'éclairage. Plus il y a de triangles, plus la forme est fidèle, et plus la carte graphique travaille. Activez le mode filaire dans la démo ci-dessous pour les voir.
Chaque triangle est défini par trois sommets (vertices), et chaque sommet porte des données : sa position dans l'espace, sa normale (la direction vers laquelle la surface « regarde », indispensable pour calculer la lumière) et ses coordonnées UV (où piocher dans l'image plaquée dessus).
Le pipeline de rendu, étape par étape
(matrices)
(lumière, texture)
(z-buffer)
- Le vertex shader reçoit chaque sommet et le projette sur l'écran. Mathématiquement, c'est une multiplication par trois matrices 4×4 : la matrice modèle (où est l'objet dans le monde), la matrice vue (où est la caméra) et la matrice projection (la perspective, qui rapetisse ce qui est loin). Three.js les calcule pour vous à chaque image.
- La rastérisation découpe chaque triangle projeté en pixels candidats, appelés fragments.
- Le fragment shader calcule la couleur de chaque fragment : lumière reçue, couleur du matériau, texture, ombres. C'est ici que se joue le réalisme, et le coût.
- Le test de profondeur compare la distance de chaque fragment à celle déjà stockée pour ce pixel, et ne garde que le plus proche. C'est ce qui fait qu'un objet en cache un autre sans que personne n'ait à trier quoi que ce soit.
Le budget : 16,7 millisecondes
Un écran à 60 Hz se rafraîchit toutes les 16,7 ms ; à 120 Hz, toutes les 8,3 ms. Tout doit tenir dans ce budget : votre JavaScript (mise à jour des positions, logique), la préparation des ordres de dessin par le processeur, puis leur exécution par le GPU. Dépassez, et l'image suivante est sautée : c'est la saccade. Toute la discipline de performance (section 9) consiste à rester sous cette barre sur la machine la plus faible que vous visez, pas sur la vôtre.
La caméra perspective a quatre paramètres : l'angle de vue (fov, en degrés), le ratio largeur/hauteur, et deux distances, near et far, entre lesquelles les objets sont visibles. Ces quatre valeurs définissent une pyramide tronquée, le frustum. Ce qui est en dehors n'est tout simplement pas envoyé au GPU : c'est le frustum culling, automatique dans Three.js.
Démo 1 : le cube fondateur Interactif
Le premier programme de tout développeur Three.js, celui du README officiel : une forme, un matériau, une caméra, une boucle. Faites tourner l'objet à la souris ou au doigt, passez en filaire pour voir les triangles, cliquez sur l'objet pour le bousculer, changez de forme et regardez le compteur de triangles.
Le code qui produit cette scène (les valeurs suivent vos réglages)
import * as THREE from 'three'; const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(45, largeur / hauteur, 0.1, 100); camera.position.z = 4; const geometry = new THREE.BoxGeometry(1.4, 1.4, 1.4); const material = new THREE.MeshNormalMaterial({ wireframe: false }); const mesh = new THREE.Mesh(geometry, material); scene.add(mesh); const renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(largeur, hauteur); renderer.setAnimationLoop((time) => { // appelé à chaque rafraîchissement de l'écran mesh.rotation.x = time / 2000; mesh.rotation.y = time / 1000; renderer.render(scene, camera); });
4. Le vocabulaire, sans jargon inutile Vingt mots pour lire n'importe quel exemple
| Terme | Ce que c'est | À retenir |
|---|---|---|
| Mesh | Un objet visible : géométrie + matériau, avec une position, une rotation et une échelle. | L'unité de base de tout ce qui s'affiche. |
| Geometry | La forme, sous forme de tableaux de sommets et de triangles (BufferGeometry). | Partageable entre plusieurs meshes. |
| Material | Comment la surface réagit à la lumière : couleur, rugosité, métallicité, transparence. | MeshStandardMaterial pour 90 % des cas. |
| Texture | Une image plaquée sur une surface, via les coordonnées UV. | Souvent le premier poste de mémoire vidéo. |
| UV | Coordonnées (u, v) entre 0 et 1 qui disent, pour chaque sommet, quel point de l'image lui correspond. | Un dépliage de la forme à plat. |
| Normale | Vecteur perpendiculaire à la surface en un point. | Sans normales, pas d'éclairage. |
| Shader | Petit programme exécuté sur le GPU, pour chaque sommet ou chaque pixel. | GLSL, WGSL, ou TSL avec Three.js. |
| Draw call | Un ordre de dessin envoyé au GPU. Un mesh = au moins un appel. | Le coût caché n°1. |
| Instancing | Dessiner N copies d'une même géométrie en un seul appel, avec des transformations différentes. | InstancedMesh. Démo en section 9. |
| Frustum culling | Ne pas envoyer au GPU ce qui est hors du champ de la caméra. | Automatique, par objet. |
| LOD | Level of detail : plusieurs versions d'un modèle, la moins détaillée servant de loin. | Indispensable sur les grandes scènes. |
| Raycasting | Lancer un rayon depuis la caméra à travers le curseur pour savoir quel objet il touche. | C'est ainsi que l'on « clique » en 3D. |
| glTF / GLB | Format standard d'échange de scènes 3D (Khronos Group). GLB en est la version binaire en un seul fichier. | « Le JPEG de la 3D ». Exportez depuis Blender. |
| PBR | Physically based rendering : matériaux décrits par des propriétés physiques (rugosité, métallicité). | Section 6. |
| Environment map | Une image panoramique du monde autour de la scène, utilisée pour les reflets et l'éclairage indirect. | Ce qui rend un métal crédible. |
| Post-processing | Effets appliqués à l'image finie : flou de profondeur, bloom, grain, correction colorimétrique. | Chaque passe coûte un rendu plein écran. |
| WebXR | API du navigateur pour la réalité virtuelle et augmentée. Three.js la prend en charge nativement. | renderer.xr.enabled = true. |
| Import map | Bloc JSON dans la page qui dit au navigateur où trouver 'three' quand un script l'importe. | Three.js sans outil de build. |
| Compute shader | Programme GPU qui calcule sans dessiner : particules, simulations, IA. | WebGPU seulement. |
| TSL | Three Shading Language : écrire ses shaders en JavaScript composable, compilés en GLSL ou WGSL selon le moteur. | Le futur des matériaux Three.js. |
5. Anatomie d'un programme Three.js Installer, écrire, faire tourner
Trois façons d'installer Fondamental
1. Sans outil de build : une import map et un CDN
C'est la méthode de ce guide. Le navigateur lit un bloc JSON qui associe le nom three à une URL, puis vos scripts l'importent comme un module normal. Épinglez toujours la version.
<script type="importmap"> { "imports": { "three": "https://cdn.jsdelivr.net/npm/three@0.186.0/build/three.module.js", "three/addons/": "https://cdn.jsdelivr.net/npm/three@0.186.0/examples/jsm/" } } </script> <script type="module"> import * as THREE from 'three'; import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; // ... votre scène </script>
2. Avec npm et un bundler (Vite)
npm install three # installe la version courante, épinglée dans package.json npm create vite@latest # un projet moderne en une commande
Même code ensuite, avec en prime l'auto-complétion de l'éditeur, le tree-shaking (seul le code réellement importé part en production) et le rechargement à chaud.
3. Via un framework
React Three Fiber, Threlte ou TresJS (section 10) enveloppent Three.js dans la syntaxe de React, Svelte ou Vue. Utile si votre application est déjà écrite avec l'un d'eux ; inutile pour apprendre.
Le programme minimal, ligne par ligne
import * as THREE from 'three'; // 1. Une caméra : angle de vue 70°, ratio de l'écran, visible entre 0,01 et 10 unités const camera = new THREE.PerspectiveCamera(70, innerWidth / innerHeight, 0.01, 10); camera.position.z = 1; // 2. Une scène, et un cube dedans const scene = new THREE.Scene(); const geometry = new THREE.BoxGeometry(0.2, 0.2, 0.2); const material = new THREE.MeshNormalMaterial(); const mesh = new THREE.Mesh(geometry, material); scene.add(mesh); // 3. Un moteur de rendu, qui crée son propre <canvas> const renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(innerWidth, innerHeight); document.body.appendChild(renderer.domElement); // 4. La boucle : le navigateur rappelle cette fonction avant chaque rafraîchissement renderer.setAnimationLoop((time) => { mesh.rotation.x = time / 2000; // time est en millisecondes mesh.rotation.y = time / 1000; renderer.render(scene, camera); });
- Les unités sont arbitraires. Un cube de 0,2 est petit parce que la caméra est à 1 unité. Convention courante : 1 unité = 1 mètre, ce qui simplifie l'import de modèles et la physique.
- Les angles sont en radians partout, sauf le
fovde la caméra, en degrés. Un tour complet vaut2 * Math.PI. - Le repère est droitier : X vers la droite, Y vers le haut, Z vers vous (hors de l'écran). La caméra regarde vers les Z négatifs.
setAnimationLoops'appuie surrequestAnimationFrame: la boucle se cale sur l'écran et se met en pause quand l'onglet est caché. Elle est aussi obligatoire pour la réalité virtuelle, où c'est le casque qui impose la cadence.- Utilisez
timeplutôt qu'un compteur incrémenté à chaque image : à 120 Hz, votre cube tournerait deux fois plus vite qu'à 60 Hz.
Les briques que vous ajouterez ensuite
| Besoin | Module | Import |
|---|---|---|
| Tourner autour de la scène à la souris | OrbitControls | three/addons/controls/OrbitControls.js |
| Charger un modèle Blender | GLTFLoader | three/addons/loaders/GLTFLoader.js |
| Décompresser des géométries Draco | DRACOLoader | three/addons/loaders/DRACOLoader.js |
| Textures compressées GPU | KTX2Loader | three/addons/loaders/KTX2Loader.js |
| Un éclairage d'ambiance sans image HDR | RoomEnvironment | three/addons/environments/RoomEnvironment.js |
| Fusionner des géométries | BufferGeometryUtils | three/addons/utils/BufferGeometryUtils.js |
| Réalité virtuelle en un bouton | VRButton | three/addons/webxr/VRButton.js |
Tout ce qui vit sous three/addons/ vient du dossier examples/jsm du dépôt : maintenu par le projet, mais hors du cœur, ce qui garde ce dernier léger.
6. Lumière, matière et vérité physique Le rendu physiquement réaliste (PBR) expliqué
Pourquoi le rendu « physique » a gagné
Jusqu'au début des années 2010, un matériau 3D se décrivait par des paramètres esthétiques : une couleur diffuse, une couleur spéculaire, une « brillance ». Ça marchait sous une lumière, et c'était faux sous une autre. Le rendu physiquement réaliste (PBR) remplace ces réglages par des propriétés mesurables sur de vrais matériaux, ce qui donne un rendu cohérent quel que soit l'éclairage. Three.js l'implémente dans MeshStandardMaterial et son extension MeshPhysicalMaterial.
Les deux curseurs qui comptent
- Rugosité (
roughness, de 0 à 1) : à 0, la surface est un miroir parfait ; à 1, elle diffuse la lumière dans toutes les directions, comme du plâtre. Physiquement, c'est la taille des micro-aspérités de la surface. - Métallicité (
metalness, de 0 à 1) : un métal réfléchit la lumière en la colorant (l'or reflète en jaune) et n'a pas de couleur diffuse ; un isolant (bois, plastique, peau) reflète en blanc et diffuse sa couleur propre. Les valeurs intermédiaires n'existent presque pas dans la nature : elles servent aux transitions (rouille, poussière).
Deux lois qui tiennent tout
- Conservation de l'énergie : une surface ne peut pas renvoyer plus de lumière qu'elle n'en reçoit. Ce qui part en reflet est retiré du diffus. C'est ce qui empêche les objets de « briller » de façon irréaliste.
- Effet Fresnel : toute surface réfléchit davantage quand on la regarde en incidence rasante. Regardez un lac à vos pieds (transparent) puis à l'horizon (miroir). Les matériaux PBR le calculent automatiquement.
D'où vient la lumière ?
| Lumière | Modèle physique | Coût | Usage |
|---|---|---|---|
AmbientLight | Aucun : ajoute une même quantité de lumière partout | Nul | Déboucher les ombres, à petite dose |
HemisphereLight | Ciel d'une couleur, sol d'une autre | Très faible | Extérieurs, ambiance crédible à bas prix |
DirectionalLight | Rayons parallèles, comme le soleil | Faible (plus si ombres) | La lumière principale de la plupart des scènes |
PointLight | Ampoule : rayonne dans toutes les directions, décroît avec la distance | Moyen | Lampes, torches, feux |
SpotLight | Cône de lumière | Moyen | Projecteurs, lampes de bureau |
| Environment map | Le monde entier, comme source de lumière et de reflets | Un précalcul, puis faible | Tout ce qui doit avoir l'air réel |
Les ombres portées ne sont pas gratuites : pour chaque lumière qui en projette, le GPU rend la scène une fois de plus, depuis le point de vue de la lumière, pour savoir ce qui est caché. Une lumière avec ombres, rarement plus.
texture.colorSpace).Démo 2 : de la boule de plâtre à la boule de chrome Interactif
Une seule sphère, un seul matériau, deux curseurs. Rugosité à 0 et métallicité à 1 : du chrome. Rugosité à 1 et métallicité à 0 : du plâtre. Coupez l'environnement pour comprendre pourquoi un métal sans rien à refléter est noir.
Le code du matériau (les valeurs suivent vos réglages)
import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js'; // Un environnement synthétique (une pièce éclairée) précalculé pour les reflets const pmrem = new THREE.PMREMGenerator(renderer); scene.environment = pmrem.fromScene(new RoomEnvironment(), 0.04).texture; const material = new THREE.MeshStandardMaterial({ color: '#ee5586', roughness: 0.35, // 0 = miroir, 1 = mat metalness: 0.60 // 0 = isolant, 1 = métal }); const sphere = new THREE.Mesh(new THREE.SphereGeometry(1, 64, 32), material);
7. Ce qu'on en fait de sérieux Espace, science, industrie, commerce
Tous les projets cités ici figurent dans la vitrine officielle de threejs.org ou déclarent explicitement reposer sur Three.js.
Espace : suivre les sondes en direct NASA
Eyes on the Solar System et Mars 2020 : le Jet Propulsion Laboratory affiche la position réelle des planètes, des sondes et du rover Perseverance, à partir des mêmes éphémérides que les équipes de navigation. Ce qui demandait un logiciel à installer est devenu une page web.
Géomatique : 18 milliards de points LiDAR
Potree, visionneuse open source de nuages de points construite sur Three.js, affiche des relevés LiDAR de plusieurs milliards de points dans un navigateur, grâce à une structure hiérarchique qui ne charge que ce que la caméra regarde. Utilisé en topographie, en archéologie et dans le bâtiment.
Biologie : voir une protéine Recherche
NGL Viewer affiche des structures moléculaires (protéines, ADN, ARN) aux formats PDB et mmCIF, ceux des bases de données de cristallographie. Son interface est même dérivée de celle de l'éditeur Three.js. Des dizaines de milliers d'atomes, manipulables au doigt.
Commerce : le produit sous tous les angles E-commerce
Shopify a construit sa page d'annonces Editions Winter 2026 en 3D. La balise <model-viewer> de Google, construite sur Three.js, affiche un modèle glTF dans n'importe quelle page et le projette en réalité augmentée dans votre salon depuis un téléphone. Configurateurs de bijoux, d'appareils photo, de voitures : la 3D remplace la photo quand les combinaisons se comptent en milliers.
Industrie et territoire
FutureCube de Kubota, constructeur de machines agricoles, présente sa vision en 3D navigable. Procedural GL génère des cartes 3D de terrain, optimisées mobile, sur une base Three.js. Même logique pour les maquettes numériques de bâtiments (BIM) et les jumeaux numériques d'usines : un lien remplace une station de travail.
Outils pour les créateurs
Toute une génération d'outils s'est bâtie sur Three.js : Spline (design 3D dans le navigateur), Theatre.js (animation par timeline), Needle (exporter une scène Unity vers le web), A-Frame (réalité virtuelle en balises HTML), l'éditeur officiel. Quand un outil est construit sur une bibliothèque, c'est le signe que la bibliothèque est devenue une plateforme.
8. Ce qu'on en fait de décalé Jeux, portfolios, bizarreries et hommages
Le CV le plus conduit du web
bruno-simon.com : vous arrivez sur un terrain vague miniature au volant d'une petite voiture, et vous renversez le nom du propriétaire pour comprendre que tout se déplace. La version 2019 tournait sur un moteur physique (Cannon.js) synchronisé image par image avec la scène Three.js. La version 2025-2026, refaite pendant plus d'un an et documentée sur YouTube, ajoute la manette, des succès à débloquer, un circuit avec classement quotidien, et publie son code sous licence MIT. Un portfolio devenu jeu, devenu cours, devenu référence.
DOOM, par le créateur de Three.js
three-doom est, selon son dépôt, « un portage de Doom vers Three.js », signé Mr.doob en personne. Il lit les fichiers WAD d'origine (le shareware de 1993 est inclus, vos propres WAD sont acceptés) et reconstruit les niveaux en géométrie Three.js. Détail d'époque : le README crédite deux assistants IA parmi les contributeurs.
Un ordinateur de 1981, dans un onglet, en 3D
VirtualBeeb : un BBC Micro modélisé en 3D, dans lequel tourne un véritable émulateur (celui de Matt Godbolt). Le lien démarre Elite, jeu spatial de 1984 : appuyez sur F10 pour quitter la station. Une machine simulée, dans une machine simulée, dans votre navigateur.
Un Doodle Google jouable
Google a fêté la pétanque avec un Doodle en 3D construit sur Three.js. Quand la page la plus visitée du monde embarque une scène 3D pour une journée, c'est que la technologie est jugée assez fiable pour des centaines de millions de visiteurs.
Un vrai FPS multijoueur, sans installation
Krunker.io est un jeu de tir en ligne complet, gratuit, qui se lance en quelques secondes depuis un onglet. Modes de jeu, classes, cartes créées par la communauté : la démonstration que Three.js tient la charge d'un jeu compétitif, à condition de faire les bons choix graphiques (ici, des formes simples et peu de textures).
L'océan de Zelda, en WebGPU
Wind Waker JS, par Robin Payot : une recréation de la partie navigation de The Legend of Zelda: The Wind Waker, rendue avec Three.js sur WebGPU et TSL. Un hommage de fan qui sert aussi de banc d'essai à la nouvelle génération du moteur.
Une banque transformée en monde à explorer
Coastal World (studio Merci-Michel, 2022) : une offre bancaire présentée comme un jeu d'exploration en 3D, avec sa place de marché. L'exemple type du « site-expérience » que les agences créatives ont fait de Three.js.
Et aussi, dans la vitrine officielle
- putt.day : un trou de mini-golf par jour, le même pour tout le monde, à finir en un minimum de coups.
- Choo-Choo World : un constructeur de circuits de train en bois, à la campagne, dont on partage les créations.
- HexGL : le jeu de course de 2012, toujours jouable, dont le code est un excellent cas d'école.
- Les exemples officiels : plusieurs centaines de scènes, chacune avec son code source visible, du plus simple au plus expérimental. Le meilleur terrain de jeu qui soit.
9. Performance : les règles du jeu Ce qui coûte vraiment, et comment le mesurer
Règle n°1 : compter les appels de dessin, pas les triangles
Chaque Mesh déclenche au moins un appel de dessin (draw call). Avant chaque appel, le processeur prépare l'état du GPU : quelle géométrie, quel matériau, quelles matrices. Ce travail a un coût fixe, quelle que soit la taille de l'objet. Mille cubes de douze triangles coûtent donc bien plus cher qu'un seul objet de douze mille triangles. La règle empirique : quelques centaines d'appels par image sont confortables, quelques milliers deviennent le goulot d'étranglement, surtout sur mobile.
Les trois remèdes classiques :
- Instancing (
InstancedMesh) : N copies de la même géométrie, chacune avec sa matrice et sa couleur, en un appel. Démo ci-dessous. - Fusion de géométries (
BufferGeometryUtils.mergeGeometries) : plusieurs formes statiques deviennent un seul objet. - Atlas de textures et matériaux partagés : deux objets qui partagent géométrie et matériau ne forcent pas le GPU à changer d'état entre les deux.
Démo 3 : 50 000 cubes en un seul appel Interactif
Un nuage de cubes, tous dessinés en un appel grâce à InstancedMesh. Poussez le curseur au maximum : le compteur d'appels reste à 1. Basculez ensuite en mode naïf, un Mesh par cube : les appels explosent et les images par seconde s'effondrent, alors que le nombre de triangles n'a pas changé. Le mode naïf est plafonné à 5 000 cubes : au-delà, certains téléphones décrochent pour de bon.
Le code de la démo (les valeurs suivent vos réglages)
const count = 10000; const geometry = new THREE.BoxGeometry(0.18, 0.18, 0.18); // 12 triangles const material = new THREE.MeshStandardMaterial({ roughness: 0.5 }); // Mode instancié : une géométrie, count matrices, UN appel de dessin const cloud = new THREE.InstancedMesh(geometry, material, count); const m = new THREE.Matrix4(); for (let i = 0; i < count; i++) { m.setPosition(positionAleatoire()); cloud.setMatrixAt(i, m); cloud.setColorAt(i, couleurAleatoire()); } scene.add(cloud);
Les autres postes de dépense
| Poste | Ce qui se passe | Le réflexe |
|---|---|---|
| Textures | Un JPEG de 4096×4096 pèse 1 Mo sur le disque, mais 64 Mo une fois décompressé en mémoire vidéo (4 octets par pixel). Dix textures de ce format saturent un téléphone. | Dimensions raisonnables (1024 ou 2048), formats compressés GPU (KTX2 / Basis Universal) qui restent compressés en mémoire. |
| Résolution | Un écran « Retina » à ratio 3 demande 9 fois plus de pixels qu'un écran classique de même taille. | renderer.setPixelRatio(Math.min(devicePixelRatio, 2)). |
| Ombres | Un rendu supplémentaire par lumière qui projette des ombres, à chaque image. | Une seule lumière avec ombres, carte d'ombre de taille modeste, ombres « cuites » dans les textures pour le statique. |
| Post-processing | Chaque effet est un rendu plein écran de plus. | Peu de passes, résolution réduite pour le flou et le bloom. |
| Géométrie lourde | Un modèle de CAO de 5 millions de triangles bloque le chargement avant même de bloquer le rendu. | Décimation dans Blender, LOD, compression Draco, chargement progressif. |
| Fuites mémoire | Retirer un objet de la scène ne libère pas sa géométrie ni ses textures sur le GPU. | geometry.dispose(), material.dispose(), texture.dispose(). |
| Thermique mobile | Un téléphone qui chauffe réduit sa fréquence : la scène fluide à la première minute rame à la cinquième. | Viser 30 ou 60 images/s stables plutôt que le maximum, mettre en pause hors écran. |
Mesurer avant d'optimiser
renderer.info: appels, triangles, textures et géométries en mémoire, lus après chaque rendu. C'est ce qu'affichent les tableaux de bord de ce guide.- stats.js (dans les addons) : le petit compteur d'images par seconde que l'on voit sur tous les exemples officiels.
- L'onglet Performance des outils de développement du navigateur : sépare le temps JavaScript du temps GPU, et montre les images manquées.
- Spector.js : capture une image WebGL et liste chaque appel, avec son état. L'outil pour comprendre pourquoi une scène fait 400 appels alors qu'elle en devrait 40.
10. L'écosystème et les alternatives Ce qui s'ajoute, et ce qui rivalise
Autour de Three.js
| Besoin | Outils | Remarque |
|---|---|---|
| Intégration à un framework | React Three Fiber (+ drei), Threlte (Svelte), TresJS (Vue) | Une scène décrite en composants. R3F est de loin le plus répandu. |
| Physique | Rapier (écrit en Rust, compilé en WebAssembly), cannon-es, Ammo.js (portage de Bullet), Jolt | Rapier est le choix moderne par défaut ; cannon-es le plus simple pour débuter. |
| Modélisation et pipeline | Blender (libre) → export glTF ; compression Draco (géométrie) et KTX2 (textures) via gltf-transform | Le trio Blender + glTF + Three.js couvre l'immense majorité des projets. |
| Animation | Animations glTF (squelettes, morphs) lues par AnimationMixer ; GSAP ou Theatre.js pour la mise en scène | Le scroll-driven storytelling est presque toujours du GSAP + Three.js. |
| Interface et réglages | lil-gui (le panneau de curseurs des exemples), Tweakpane | Un panneau de réglages dès le premier jour fait gagner des heures. |
| Shaders | TSL (natif), GLSL (WebGL), NodeToy et Polygon.js (éditeurs de nœuds) | Voir la section 11 pour le choix TSL / GLSL. |
| Réalité virtuelle et augmentée | WebXR natif dans Three.js, A-Frame au-dessus, <model-viewer> pour l'AR produit | Testable dans le navigateur d'un casque Quest sans passer par un store. |
Three.js face aux alternatives Comparatif
| Solution | Nature | Licence | Points forts | Limites |
|---|---|---|---|---|
| Three.js | Bibliothèque de rendu | MIT | Légère, souple, énorme communauté, s'intègre à n'importe quelle page | Pas d'éditeur ni de physique intégrés : tout se compose |
| Babylon.js | Moteur complet (Microsoft) | Apache 2.0 | Physique, inspecteur, audio, GUI, TypeScript de bout en bout, WebGPU | Plus lourd, plus « moteur de jeu » dans sa philosophie |
| PlayCanvas | Moteur + éditeur en ligne | MIT (moteur) | Éditeur collaboratif dans le navigateur, très bon sur mobile | L'éditeur est un service hébergé |
| Unity (export web) | Moteur natif exporté | Commerciale | Tout l'outillage Unity, énorme catalogue d'assets | Poids d'export important, chargement long, licence selon revenus |
| Godot (export web) | Moteur natif exporté | MIT | Libre, éditeur complet, léger | Export web moins mûr que le natif |
| Unreal Engine | Moteur natif | Commerciale | Le sommet du rendu temps réel | Plus de cible web officielle depuis la version 4.24 ; portages communautaires seulement |
| WebGL / WebGPU bruts | API du navigateur | Standard | Contrôle total, aucune dépendance | Tout est à écrire, y compris ce que Three.js fait en une ligne |
11. WebGL, WebGPU et TSL Où en est-on en septembre 2026
La couverture réelle des navigateurs Chiffres caniuse.com, septembre 2026
| Navigateur | WebGL 2 depuis | WebGPU depuis | Remarque |
|---|---|---|---|
| Chrome / Edge | 56 (2017) | 113 (mai 2023) | La référence, sur Windows, macOS, ChromeOS et Android |
| Safari / iOS | 15 (2021) | 26 (septembre 2025) | Complet sur iOS, partiel sur macOS selon caniuse |
| Firefox | 51 (2017) | 141 (juillet 2025) | Activé sur Windows uniquement ; désactivé par défaut ailleurs |
Conclusion pratique : en 2026, une scène WebGPU sans repli WebGL exclut encore un visiteur sur huit. Le repli n'est pas une option, c'est une obligation.
Ce que dit le projet lui-même
WebGLRendererreste maintenu et reste le choix recommandé pour une application purement WebGL 2, mais le projet indique qu'il n'y ajoutera plus de grandes fonctionnalités : l'effort va auWebGPURenderer.WebGPURendererse replie automatiquement sur WebGL 2 quand WebGPU n'est pas disponible. Vous n'avez rien à écrire pour cela.- TSL, le Three Shading Language, est la façon d'écrire des matériaux et des effets pour ce nouveau moteur : du JavaScript composable, compilé en WGSL sur WebGPU et en GLSL sur WebGL. Un seul code, deux cibles.
- Ce qui ne passe pas tel quel sur
WebGPURenderer: les matériauxShaderMaterialetRawShaderMaterial, les modifications paronBeforeCompile(), et l'ancienne chaîne de post-processingEffectComposer. Tout cela se réécrit en TSL et en nœuds.
La décision, selon votre situation
| Situation | Recommandation 2026 |
|---|---|
| Nouveau projet, matériaux standard | WebGPURenderer dès le départ, repli WebGL automatique. Le passage se résume souvent à changer l'import. |
| Nouveau projet, shaders sur mesure | Écrire en TSL, même si vous livrez en WebGL aujourd'hui : le WebGPU devient alors un réglage, pas une réécriture. |
| Projet existant avec du GLSL et EffectComposer | Rester sur WebGLRenderer (maintenu), et budgéter la migration comme un vrai chantier de plusieurs semaines : shaders et post-processing sont à réécrire. |
| Simple page vitrine ou démo pédagogique | WebGLRenderer reste parfaitement légitime : couverture maximale et code le plus lisible. C'est le choix de ce guide. |
12. Roadmap d'apprentissage Par où commencer, dans quel ordre
Phase 1 : les fondations Quelques semaines
- JavaScript moderne : modules (
import), fonctions fléchées,async/await, classes. Three.js est écrit ainsi, ses exemples aussi. - Un peu de géométrie : vecteurs (position, direction), radians, ce qu'est une matrice de transformation. Pas de calcul à la main : comprendre ce que Three.js fait pour vous.
- Le cube : reproduire le programme de la section 5 sans le copier. Puis changer la caméra, la forme, la vitesse.
- OrbitControls et les lumières : une
DirectionalLight, uneHemisphereLight, unMeshStandardMaterial. Comprendre pourquoi un objet est noir.
Phase 2 : le pipeline réel 1 à 2 mois
- Blender : modéliser un objet simple, le texturer, l'exporter en glTF, le charger avec
GLTFLoader. - Environnement et PBR : une image HDR ou
RoomEnvironment, rugosité et métallicité, espaces colorimétriques. - Interaction :
Raycasterpour cliquer sur un objet, survol, drag. - Animation :
AnimationMixerpour les animations glTF, GSAP pour le reste. - Un panneau de réglages (lil-gui) sur chaque projet, dès la première heure.
Phase 3 : le niveau professionnel 3 à 6 mois
- Performance : instancing, fusion, LOD, textures KTX2,
renderer.info, tests sur mobile. - Shaders : les bases de GLSL, puis TSL. Comprendre un vertex shader et un fragment shader en les écrivant.
- Intégration : React Three Fiber si votre application est en React ; sinon, Three.js nu suffit.
- Physique : Rapier ou cannon-es, synchronisation corps physique / mesh à chaque image.
- Chargement : barre de progression, chargement différé, gestion des erreurs, poids total sous contrôle.
Phase 4 : l'expertise 6 mois et plus
- WebGPU et compute shaders : simulations de particules, GPGPU, post-processing en nœuds.
- Post-processing sur mesure et effets de rendu (SSAO, réflexions écran, profondeur de champ), avec leur coût.
- WebXR : réalité virtuelle et augmentée, contrôleurs, suivi des mains.
- Architecture : scènes de grande taille, streaming, mémoire, outils de diagnostic.
- Contribuer : un exemple, une correction de documentation, un ticket bien décrit. Le projet a plus de 2 000 contributeurs, et une place pour vous.
Mémo publié par NET&PRO à titre pédagogique. Information générale, sans garantie d'exactitude, d'exhaustivité ni d'actualité, et sans valeur de conseil personnalisé. Avertissement et limites d'usage
Dans le glossaire
Les mots croisés au fil de ce mémo, définis en une phrase. Ils sont soulignés dans le texte : un clic y mène directement.
Mémos liés
Le Frontend & UI/UX de A à Z
HTML, CSS, JS, frameworks, npm, API, design systems, accessibilité et tendances 2026 : du newbie à l'expert.
Lire le mémoLe Backend de A à Z
Du serveur web aux applis hybrides IA/humain : langages, frameworks, bases de données, API, architectures.
Lire le mémoAccessibilité web : par où commencer quand on part de zéro
Qui est vraiment concerné par la loi depuis juin 2025, les sept défauts que n'importe quel outil détecte en trente secondes, pourquoi les surcouches vendues comme solution n'en sont pas, et les trois tests à faire soi-même sans rien installer.
Lire le mémoSi vous préférez me le confier
Sur ce sujet, voici ce que je fais pour mes clients. Les formules disent ce qui est compris, ce qui ne l'est pas, et ce que ça coûte au bout de trois ans.