Skip to content

Génération de paysages avec LOD dynamique et streaming pour les mondes ouverts sur navigateur

Les cartes de hauteur avec bruit de Perlin constituent le point de départ par défaut pour la génération procédurale de terrains. Superposez quelques octaves de fBm, appliquez un dégradé de couleurs, et vous obtenez quelque chose qui ressemble vaguement à un terrain. Tous les tutoriels s'arrêtent là. Mais les paysages réels ne ressemblent pas à un empilement de bruits. Ils présentent des vallées fluviales creusées par l'eau, des parois rocheuses façonnées par des fractures de contrainte, ainsi que des grottes et des arches formées par des millions d'années d'érosion. Leurs textures sont corrélées — herbe sur les terrains plats, roche sur les pentes abruptes, neige au-dessus de la limite des arbres — et émergent des mêmes processus physiques qui ont façonné la géométrie.

Ce guide aborde ce qui vient après le bruit : les méthodes de génération fondées sur la physique, les représentations volumétriques capables de gérer les grottes et les surplombs, la synthèse neuronale de terrains fondée sur la diffusion, ainsi que les pipelines de LOD et de streaming pilotés par le GPU nécessaires pour afficher le tout à 60 i/s dans un onglet de navigateur.

Tout ce qui suit répond à notre contrainte particulière : un monde ouvert multijoueur fonctionnant sous WebGL 2 / WebGPU, diffusé en streaming sur le réseau et modifiable par les créateurs.

Pourquoi les cartes de hauteur ne suffisent pas

Une carte de hauteur stocke une valeur d'altitude par point de la grille. C'est une fonction 2D : étant donné (x, z), elle renvoie y. Cette représentation est compacte, adaptée au GPU et rapide à afficher. Mais elle présente des limites fondamentales qui comptent dans un monde destiné aux créateurs.

Ni grottes ni surplombs. Une carte de hauteur ne peut pas représenter un terrain où un même point possède deux hauteurs différentes. Les grottes, les arches, les surplombs rocheux, les tunnels et les îles flottantes sont donc tous impossibles. C'est pour cette raison que Minecraft, No Man's Sky et Deep Rock Galactic ont besoin de terrains volumétriques.

Pas de structures verticales. Dans une carte de hauteur, une paroi rocheuse verticale correspond à une pente presque infinie, ce qui entraîne un étirement extrême des textures et des artefacts de collision. Les véritables falaises possèdent des structures horizontales — corniches, crevasses — qu'une carte de hauteur ne peut pas représenter.

Le bruit ressemble à du bruit. Même avec 8 octaves de fBm et une déformation de domaine, le terrain conserve un aspect artificiel. Il lui manque la structure directionnelle de la géologie réelle : lignes de crête, réseaux hydrographiques, dépôts sédimentaires et plis tectoniques. Ces motifs émergent de processus physiques, et non de fonctions de bruit.

Les modifications des créateurs sont limitées. Si les créateurs peuvent uniquement modifier les hauteurs, ils ne peuvent ni creuser des tunnels, ni créer des grottes, ni construire des espaces souterrains. Pour qu'ils puissent véritablement façonner un monde, la représentation du terrain doit permettre aussi bien la soustraction que l'addition.

La solution ne consiste pas à abandonner entièrement les cartes de hauteur. Elles restent la meilleure représentation pour les 90 % du terrain qui forment une surface simple. Il faut plutôt adopter une approche hybride : un terrain de base sous forme de carte de hauteur, des superpositions volumétriques là où une géométrie complexe est nécessaire, une génération physiquement réaliste pour obtenir des reliefs crédibles et une synthèse neuronale pour apporter la diversité que le bruit ne peut pas produire.

La réponse rapide : ce que nous construirions réellement

Avant d'entrer dans les détails, voici le cadre décisionnel. La suite de l'article explique chaque élément.

Représentation du terrain

Utilisez un système hybride carte de hauteur + SDF. La carte de hauteur couvre le monde entier : elle est peu coûteuse, compacte et éprouvée. Les volumes SDF n'existent que là où des grottes, des surplombs ou des éléments sculptés par les créateurs l'exigent, soit peut-être 5 à 10 % des chunks. Ainsi, 90 % du monde conserve le faible coût d'une carte de hauteur, tout en permettant une géométrie arbitraire là où elle est nécessaire.

Pipeline de génération

Exécutez côté serveur une chaîne de traitement :

  1. Terrain Diffusion (ou MESA pour les instructions textuelles) génère la carte de hauteur de base à partir d'une graine. Cette méthode remplace le bruit par des reliefs géologiquement réalistes, appris à partir de véritables données d'altitude.
  2. L'érosion analytique (loi de puissance de l'écoulement) affine la carte de hauteur en quelques millisecondes en créant des réseaux fluviaux et des lignes de crête.
  3. TerraFusion ou Geodiffussr génère des textures corrélées à partir de la carte de hauteur. Pour la solution de repli WebGL 2, utilisez plutôt des règles procédurales fondées sur la pente et l'altitude.
  4. Une simulation d'écosystème produit les cartes de densité de la végétation.
  5. Une érosion de type Arenite génère des volumes SDF pour les parois rocheuses, les arches et les grottes là où le terrain l'exige.
  6. Découpage en chunks, compression et envoi vers le CDN. Taille moyenne d'un chunk : 2 à 8 Ko. Chunk complexe comportant des données volumétriques : 20 à 100 Ko.

Les créateurs interagissent avec ce pipeline en ajustant des paramètres (« plus humide », « plus montagneux », « ajouter des grottes »), en esquissant leurs intentions ou en sculptant directement avec des pinceaux et des outils SDF.

Stratégie de LOD

Capacités du navigateurLOD de la carte de hauteurLOD volumétriqueLOD de la végétation
WebGPUQuadtree piloté par le GPU (CDLOD), avec culling par compute shader et dessin indirectSDF multirésolution avec marching cubes par compute shader + TransvoxelComputeInstanceCulling avec dessin indirect
WebGL 2Geometry clipmaps avec mise à jour des anneaux côté CPUMaillages prégénérés à 2 ou 3 niveaux de LOD, mis en cacheCulling du frustum par le CPU, InstancedMesh

Les deux voies utilisent du géomorphing dans le vertex shader afin d'éviter les apparitions brutales lors des transitions. Toutes deux emploient également des imposteurs de type billboard pour la végétation lointaine. La voie WebGPU est plus rapide — budget de 3,5 ms pour le terrain — mais la voie WebGL 2 reste viable avec 6,5 ms.

Streaming

Chargement progressif : géométrie du terrain en premier (<100 ms), textures en deuxième (<300 ms), végétation en troisième (<1 s), données volumétriques en quatrième (❤️ s). Préchargement fondé sur la vitesse du joueur. Budget mémoire total pour le terrain : 256 Mo.

Modification

Pinceaux de carte de hauteur pour sculpter la surface — élever, abaisser, lisser, éroder. Primitives SDF pour la modification volumétrique — creuser des grottes, ajouter des arches. Les deux sont instantanés localement, se synchronisent avec le serveur en 100 à 300 ms et sont transmis aux autres joueurs au moyen de mises à jour différentielles.

Dans quel ordre construire chaque élément

Mois 1 à 2 : terrain avec carte de hauteur et geometry clipmaps. WebGL 2 uniquement. Streaming depuis le CDN. Matériaux procéduraux fondés sur la pente et l'altitude. Cela permet d'afficher le terrain dans tous les navigateurs. Utilisez du bruit et une érosion analytique pour la génération ; Terrain Diffusion peut attendre.

Mois 3 à 4 : végétation et atmosphère. Herbe et arbres instanciés par le GPU à partir de cartes de densité. Ciel procédural avec cycle jour/nuit. Brouillard atmosphérique. Cascaded shadow maps. Le monde commence à ressembler à un véritable lieu.

Mois 5 à 6 : outils de modification pour les créateurs. Pinceaux de carte de hauteur. Synchronisation différentielle des modifications du terrain en multijoueur. Verrouillage spatial pour les modifications simultanées. C'est à ce stade que les créateurs commencent à façonner le monde.

Mois 7 à 9 : terrain volumétrique et voie WebGPU. Superpositions SDF pour les grottes et les surplombs. Marching cubes dans les compute shaders WebGPU. Transvoxel pour les limites entre niveaux de LOD. Outils de sculpture SDF. Cette étape débloque l'ensemble complet des outils de création.

Mois 10 à 12 : génération neuronale et finitions. Terrain Diffusion ou MESA pour la carte de hauteur de base. TerraFusion/Geodiffussr pour les textures. Bruit de phaseur pour les microdétails. Pavage hexagonal pour éviter les répétitions. Texturation virtuelle. Fusion laplacienne. Le terrain atteint une qualité de production.

Avec cet ordre, une version jouable existe après 2 mois, une version esthétique après 4 mois, une version modifiable après 6 mois et une version à la pointe de la technologie après 12 mois.

La suite de cet article présente les recherches qui sous-tendent chaque décision.

Représentations du terrain au-delà des cartes de hauteur

Champs de distance signés (SDF)

Un champ de distance signé stocke, en chaque point de l'espace 3D, la distance jusqu'à la surface la plus proche. Les valeurs positives se trouvent à l'extérieur, les valeurs négatives à l'intérieur, et le passage par zéro correspond à la surface elle-même. Les SDF peuvent représenter des formes 3D arbitraires, notamment des grottes, des arches et des géométries flottantes.

Pour afficher un SDF sous forme de maillage, on exécute marching cubes — ou une variante — afin d'extraire l'isosurface zéro sous forme de triangles. La résolution du maillage dépend de celle de la grille : une grille SDF de 256x256x256 produit un terrain couvrant approximativement un chunk avec une résolution d'un mètre.

Implémentation dans le navigateur : marching cubes sous WebGPU s'exécute entièrement sur le GPU à l'aide de compute shaders. L'implémentation webgpu-marching-cubes de Will Usher traite une grille de 256^3 en temps réel dans le navigateur, avec des performances comparables à une application native. L'algorithme est massivement parallélisable — chaque cellule est traitée indépendamment — ce qui le rend idéal pour le calcul sur GPU.

wgsl
@compute @workgroup_size(4, 4, 4)
fn marchingCubes(@builtin(global_invocation_id) id: vec3<u32>) {
    let sdfValues = sampleSDF(id);
    let caseIndex = classifyCell(sdfValues);
    if (caseIndex == 0u || caseIndex == 255u) { return; }
    let triangles = lookupTriangulation(caseIndex);
    let vertices = interpolateEdges(sdfValues, triangles);
    appendToMeshBuffer(vertices);
}

Coût de stockage : un SDF de 256^3 avec une précision quantifiée sur 8 bits occupe 16 Mo sans compression. Toutefois, la majeure partie du volume est vide — loin de la surface. L'encodage par longueurs de plages ou le stockage dans un octree creux réduit généralement cette taille à 100–500 Ko par chunk, soit un volume comparable à celui d'un terrain sous forme de carte de hauteur.

Modification : les terrains SDF sont naturellement modifiables. L'ajout de matière correspond à une opération min() sur le champ de distance. Le retrait de matière — le creusement — utilise une opération max() avec une forme inversée. La fusion progressive entre les formes emploie smoothMin(). Ces opérations s'exécutent dans un compute shader à des fréquences interactives.

Dual Contouring

Marching cubes place les sommets sur les arêtes de la grille, ce qui produit des surfaces lisses, mais fait disparaître les détails saillants comme les arêtes des falaises et les angles des rochers. Le dual contouring place un sommet par cellule, à la position qui représente le mieux la surface à l'intérieur de celle-ci, préservant ainsi les arêtes vives et les angles.

L'algorithme a besoin à la fois des valeurs du champ de distance et des normales à la surface — le gradient du SDF — en chaque point de la grille. Il résout un petit problème de moindres carrés par cellule afin de déterminer la position optimale du sommet. Le maillage obtenu restitue à la fois les terrains lisses et les reliefs rocheux aux arêtes marquées.

Neural Dual Contouring (Chen et al., 2022, arXiv:2202.01999) remplace le solveur des moindres carrés par un réseau neuronal qui prédit la position optimale des sommets et les intersections avec les arêtes. Cette méthode améliore la précision de la reconstruction des surfaces et la préservation des détails, en particulier pour les formations rocheuses naturelles complexes.

L'algorithme Transvoxel

Le problème le plus difficile des terrains volumétriques n'est pas la génération du maillage, mais les transitions de LOD. Lorsqu'un chunk en haute résolution jouxte un chunk en basse résolution, les maillages ne coïncident pas à leur frontière, ce qui crée des fissures visibles.

L'algorithme Transvoxel, conçu par Eric Lengyel (transvoxel.org), résout ce problème en insérant des cellules de transition spéciales le long des frontières entre les résolutions. Ces cellules comblent la différence de résolution à l'aide de triangles supplémentaires qui correspondent exactement aux deux côtés. L'algorithme réduit ce problème complexe de frontière à 73 classes d'équivalence, contre environ 1,2 million de cas avec une approche par force brute.

Transvoxel est spécialement conçu pour les applications en temps réel dans lesquelles les données voxel changent dynamiquement — modifications des créateurs, érosion, minage. Il est libre de brevets et a été utilisé dans des jeux commercialisés comme Space Engineers et Astroneer. Pour un monde sur navigateur doté d'un terrain volumétrique modifiable, Transvoxel constitue la solution de LOD.

Approche hybride : base sous forme de carte de hauteur et superpositions volumétriques

L'approche pratique pour un monde ouvert sur navigateur repose sur un système en couches :

Couche 1 : le terrain sous forme de carte de hauteur couvre le monde entier. Il s'agit de la représentation peu coûteuse et compacte pour les collines, les vallées et les montagnes. Il est transmis sous forme de petites sections de carte de hauteur par chunk, de 2 à 4 Ko chacune. Le rendu utilise des geometry clipmaps dont le coût GPU reste constant.

Couche 2 : les superpositions volumétriques n'existent que dans les chunks nécessitant une géométrie complexe. Les grottes, les parois rocheuses, les arches, les tunnels creusés par les créateurs et les espaces souterrains sont stockés sous forme de volumes SDF creux. Seuls les chunks contenant des données volumétriques supportent le coût de stockage des SDF et du marching cubes.

Couche 3 : les modifications des créateurs sont stockées sous forme d'opérations SDF superposées aux couches de base. Lorsqu'un créateur creuse un tunnel, la forme SDF de celui-ci est enregistrée. Le système de rendu combine la surface de la carte de hauteur avec les soustractions et les additions volumétriques afin de produire le maillage final.

Cette approche hybride ne coûte presque rien pour les terrains plats — uniquement la carte de hauteur — et son coût n'augmente que là où la complexité l'exige. Dans un monde typique, seuls 5 à 10 % des chunks peuvent nécessiter des données volumétriques.

Génération de terrains physiquement réaliste

Le bruit produit un terrain aléatoire. La physique produit un terrain réaliste. La différence est visible : un terrain généré par du bruit ne possède aucune structure — il est irrégulier de façon aléatoire partout — tandis qu'un terrain physique présente des réseaux fluviaux, des lignes de crête, des cônes alluviaux et des strates rocheuses qui émergent de l'érosion et de la tectonique.

Érosion hydraulique : le fondement

L'implémentation de l'érosion hydraulique de Sebastian Lague en action. Des gouttes de pluie simulées s'écoulent vers le bas, érodent la matière en fonction de leur vitesse et de la pente, puis déposent des sédiments lorsqu'elles ralentissent — transformant un bruit uniforme en vallées fluviales, lignes de crête et cônes alluviaux.

L'eau s'écoule vers le bas, emporte des sédiments et les dépose lorsqu'elle ralentit. Ce processus unique, simulé sur des millions d'années virtuelles, transforme un bruit sans relief distinctif en terrain doté de caractéristiques géologiques reconnaissables. L’approche basée sur des particules dépose des gouttes de pluie simulées sur la carte de hauteur. Chaque goutte s’écoule vers le bas (en suivant le gradient), érode le matériau en fonction de sa vitesse et de la pente, transporte des sédiments sous forme de charge dissoute et les dépose lorsque sa vitesse diminue ou que sa capacité est dépassée. Après 200 000 à 500 000 particules, le terrain développe :

  • Des vallées fluviales qui suivent le trajet du débit d’eau maximal
  • Des lignes de crête qui séparent les bassins versants
  • Des cônes alluviaux là où des vallées abruptes débouchent sur des plaines
  • Des vallées en V dans les terrains montagneux, et en U dans les terrains glaciaires

Implémentation GPU : La simulation de particules est parallélisable. Chaque particule est indépendante (l’approximation ignore les interactions entre particules, ce qui convient pour l’érosion). Un shader de calcul WebGPU traite 10 000 particules par image à 60 i/s, achevant le traitement de 200 000 particules en environ 3 secondes en temps réel.

L’implémentation open source de Sebastian Lague (GitHub) constitue le point de départ de référence. Elle s’exécute sur un seul thread en C# et traite une carte de hauteur de 1024 x 1024 en quelques secondes. La version GPU est 50 à 100 fois plus rapide.

Érosion thermique

L’eau n’est pas la seule force d’érosion. Les variations de température provoquent la fissuration et l’effritement de la roche (altération thermique). Lorsque la pente entre deux points du terrain dépasse l’angle de repos d’un matériau, celui-ci tombe du point le plus élevé vers le plus bas. Cela produit :

  • Des talus d’éboulis au pied des falaises (amas de roches tombées)
  • Des lignes de crête adoucies au fil du temps
  • Des profils dépendant du matériau (la roche dure conserve des pentes raides, tandis que les sols meubles s’affaissent selon des angles plus doux)

L’érosion thermique est plus simple que l’érosion hydraulique. Il s’agit d’une opération locale : pour chaque cellule, on compare la différence de hauteur avec les cellules voisines. Si la pente dépasse le seuil, le matériau est déplacé vers le bas. Chaque itération s’exécute en une seule passe de shader de calcul, et le processus converge en 50 à 100 itérations.

Combiner l’érosion hydraulique et l’érosion thermique produit un terrain nettement plus naturel que l’une ou l’autre seule. L’eau creuse les vallées ; l’érosion thermique adoucit les crêtes qui les séparent et remplit les fonds de vallée de débris.

La loi de puissance des cours d’eau : érosion analytique

Des recherches récentes proposent une alternative à la simulation basée sur des particules. La loi de puissance des cours d’eau (une équation géomorphologique reliant le taux d’érosion à l’aire de drainage et à la pente) peut être résolue analytiquement plutôt que simulée de manière itérative.

Cordonnier et al. (2024, HAL) combinent la loi analytique de puissance des cours d’eau avec des processus de glissement de terrain et de diffusion des versants. Il en résulte une génération de terrain fondée sur la physique, mais qui s’exécute comme une fonction mathématique plutôt que comme une simulation temporelle. Vous fournissez une carte de hauteur basée sur du bruit et des paramètres (taux de précipitations, dureté de la roche, taux de soulèvement tectonique), puis obtenez un terrain érodé en quelques millisecondes.

Cette approche analytique est idéale pour un monde accessible dans le navigateur, car elle ne s’exécute qu’une fois côté serveur lors de la génération du terrain, sans itérations. Les créateurs peuvent ajuster les paramètres (« rendre cette région plus montagneuse » modifie le taux de soulèvement ; « la rendre plus humide » augmente les précipitations et approfondit les vallées).

Arenite : érosion multiphysique (SIGGRAPH 2025)

Arenite simule les contraintes, l’érosion éolienne, l’érosion fluviale et le dépôt de particules afin de générer des arches, des cheminées de fée et des buttes à partir de couches rocheuses. La génération côté serveur produit des volumes SDF qui alimentent directement un pipeline de marching cubes.

Arenite (Page du projet) est un simulateur de grès basé sur la physique qui génère des arches, des alcôves, des cheminées de fée et des buttes à partir de conditions initiales simples. Les utilisateurs peignent des cartes d’érodabilité (couches de roche tendre ou dure) et de végétation, puis le système simule :

  • La répartition des contraintes dans la colonne rocheuse
  • L’érosion éolienne qui élimine en priorité les matériaux tendres exposés
  • L’érosion fluviale due à l’écoulement de l’eau
  • Le dépôt de particules qui crée de nouvelles formations

L’implémentation GPU s’exécute en moins de 5 minutes pour des formations complexes sur un GPU de bureau. Si cela reste trop lent pour une utilisation en temps réel dans le navigateur, c’est suffisamment rapide pour une génération côté serveur. Un créateur pourrait définir une falaise composée de couches rocheuses tendres et dures et obtenir une formation en arche réaliste en quelques minutes.

La sortie est un champ voxelique 3D, qui s’intègre directement à notre pipeline SDF/marching cubes.

Une érosion flexible pour différentes représentations

Un article de 2024 d’IRIT-STORM (« Flexible Terrain Erosion », Springer) résout un problème pratique : la plupart des méthodes d’érosion ne fonctionnent que sur des champs de hauteur. Si votre terrain utilise des voxels, des SDF ou des matériaux en couches, vous devez disposer d’un code d’érosion distinct pour chaque représentation.

La méthode d’érosion flexible décompose l’érosion en deux processus indépendants : l’altération du terrain (retrait de matériau à la surface) et le transport de matériau (déplacement des sédiments par des particules régies par des principes physiques élémentaires). Chaque particule possède une taille, une densité, une restitution et une capacité sédimentaire configurables. Un champ vectoriel facultatif contrôle le mouvement des particules afin de reproduire une dynamique des fluides réaliste.

Comme les particules interagissent avec le terrain par l’intermédiaire d’une interface unifiée d’altération des matériaux, la même simulation fonctionne avec les champs de hauteur, les grilles de voxels, les surfaces implicites et les empilements de matériaux en couches. Pour notre terrain hybride (base en carte de hauteur + superpositions SDF), cela signifie qu’un seul système d’érosion gère les deux représentations. La simulation de particules s’exécute en parallèle sur le GPU.

Réseaux fluviaux et bassins versants

L’érosion creuse les rivières, mais générer des réseaux fluviaux convaincants exige davantage que de simplement faire s’écouler l’eau vers le bas. Deux approches donnent de meilleurs résultats :

Génération fondée d’abord sur le drainage (Amit Patel, Red Blob Games, Projet) construit le réseau fluvial avant d’attribuer les altitudes. On commence par un graphe (Voronoï ou maillage triangulaire). Les arêtes sont classées comme crêtes (aucun écoulement), entrées (l’eau arrive) ou exutoires (l’eau sort). Cela crée des hiérarchies de drainage réalistes, dans lesquelles les rivières convergent depuis de petits affluents vers de grands cours d’eau, conformément au système de classification de Rosgen pour les différents types de rivières (chenaux en tresses sur les terrains plats, gorges étroites en montagne).

L’accumulation des écoulements mesure la quantité d’eau qui traverse chaque cellule du terrain. On simule une pluie uniforme, on fait s’écouler l’eau vers le bas et on compte les passages dans chaque cellule. Les cellules présentant une forte accumulation deviennent des chenaux fluviaux. Celles dont l’accumulation est modérée deviennent des cours d’eau saisonniers. La carte d’accumulation détermine également l’intensité de l’érosion (plus d’eau = plus d’érosion) et la répartition de la végétation (les berges sont plus humides et accueillent donc d’autres espèces végétales).

Pour un monde créé par un utilisateur, le réseau fluvial est généré côté serveur pendant la création du terrain, puis stocké sous forme d’une carte 2D des directions d’écoulement et d’une carte d’accumulation d’eau par chunk. Le client dans le navigateur utilise ces cartes pour afficher les surfaces aquatiques (des plans plats placés à la bonne hauteur dans les chenaux) et déterminer la répartition de la végétation (plus luxuriante près de l’eau).

Génération des côtes et des rivages

Les côtes sont les zones où le terrain rencontre l’eau, et elles présentent des caractéristiques distinctives que l’érosion standard ne produit pas : falaises maritimes, dépôts de plage, vasières intertidales, stacks et plates-formes d’abrasion marine.

NEWTS1.0 (2024, MIT) modélise l’évolution des côtes rocheuses au moyen de deux mécanismes d’érosion : le recul uniforme (taux d’érosion constant) et l’érosion provoquée par les vagues (taux d’érosion dépendant de la distance de fetch et de l’angle d’incidence des vagues). Le modèle couvre des milliers d’années simulées et produit des promontoires, des baies, des stacks et des arches correspondant à la géomorphologie côtière réelle.

Pour un monde dans le navigateur, les éléments côtiers seraient prégénérés lors de la création du monde. Les paramètres (direction dominante des vagues, variation de la dureté de la roche le long de la côte) permettent aux créateurs de contrôler le caractère de leur littoral. Un réglage « fjord norvégien » produit des bras de mer aux versants abrupts. Un réglage « atoll tropical » produit des rivages sablonneux de faible altitude avec des lagons.

Génération de grottes et de souterrains

Les grottes nécessitent un terrain entièrement volumétrique (SDF ou voxels), car les cartes de hauteur ne peuvent pas représenter des espaces clos. Les approches de génération comprennent :

Le seuillage de bruit 3D est la méthode la plus simple. On échantillonne un bruit de Perlin ou simplex 3D dans chaque voxel. Les valeurs inférieures à un seuil sont solides, celles qui sont supérieures sont vides. Le seuil et les paramètres du bruit permettent de contrôler le diamètre des tunnels, leur connectivité et la taille des salles. Cela produit des réseaux de grottes organiques et sinueux qui rappellent Minecraft.

PLUME (Procedural Layer Underground Modeling Engine) (2024, arXiv:2508.20926) génère des environnements réalistes de grottes et de tunnels de lave au moyen de règles procédurales en couches. Initialement conçu pour la recherche sur l’exploration spatiale (simulation de tunnels de lave martiens), il produit des structures souterraines géologiquement plausibles, avec des stalactites, des colonnes et des réseaux de salles.

Les tunnels en système de Lindenmayer avec excavation par métaboules utilisent une grammaire de système de Lindenmayer pour développer des trajectoires de tunnels ramifiées à travers le terrain, puis creusent leur géométrie réelle à l’aide de surfaces implicites de métaboules. Les métaboules produisent des parois de grotte lisses et arrondies. Plusieurs passes avec des paramètres différents créent des galeries principales, des salles latérales et d’étroits tunnels de liaison.

Pour un monde de créateur, la génération de grottes est intégrée au système de superposition SDF. Le terrain de base est une carte de hauteur (sans grottes). Lorsqu’un chunk doit contenir des grottes, qu’elles soient issues de la génération procédurale ou conçues par un créateur, un volume SDF est généré afin de soustraire la géométrie des grottes au terrain de base. Le pipeline de marching cubes affiche la surface combinée.

La végétation comme processus physique

Dans les jeux, la végétation est généralement placée de manière procédurale selon des règles telles que « herbe en dessous de 2 000 m, arbres en dessous de 1 500 m, neige au-dessus de 3 000 m ». Cette méthode est rapide, mais produit une répartition uniforme et peu réaliste.

La simulation de végétation fondée sur la physique modélise chaque plante comme étant en concurrence pour les ressources (lumière, eau, nutriments du sol). La simulation :

  1. Disperse des graines sur le terrain
  2. Fait pousser chaque plante en fonction des ressources disponibles (l’eau provient de la simulation d’érosion hydraulique, l’ensoleillement dépend de la pente et de l’orientation, et la profondeur du sol dépend de l’historique de l’érosion)
  3. Met les plantes en concurrence : les arbres privent l’herbe de lumière, et un couvert dense empêche l’apparition de nouveaux semis
  4. Au fil du temps simulé, fait émerger naturellement des biomes : forêts dans les vallées riches en eau, végétation clairsemée sur les crêtes balayées par le vent, zones humides là où l’eau s’accumule

La simulation d’écosystème de Deussen et al. (Article) génère des répartitions forestières correspondant à des modèles écologiques réels. La simulation s’exécute sur une grille 2D (une cellule par chunk de terrain) et produit des cartes de densité et des attributions d’espèces que le système de rendu utilise pour placer la végétation par instanciation GPU.

Pour un monde dans le navigateur, la simulation de végétation s’exécute une seule fois lors de la génération du monde (côté serveur). La sortie est un ensemble de cartes de densité par chunk : densité d’arbres, densité d’herbe, densité de fleurs et densité de débris rocheux. Le client dans le navigateur utilise ces cartes avec l’instanciation GPU pour disperser la végétation à l’exécution.

Synthèse de terrain basée sur la diffusion

C’est dans ce domaine que les progrès sont les plus rapides. Les modèles de diffusion (la même technologie que celle utilisée par Stable Diffusion pour les images) sont appliqués à la génération de terrains, avec des résultats nettement plus réalistes que ceux des méthodes basées sur le bruit.

Terrain Diffusion : un successeur du bruit de Perlin

Terrain Diffusion s’exécutant dans Minecraft et diffusant en temps réel un terrain infini cohérent avec sa graine. Entraîné sur des données d’altitude réelles, il produit des paysages dotés d’une structure géologique que les fonctions de bruit ne peuvent pas reproduire.

Terrain Diffusion (Goslin, 2025, arXiv:2512.08309, Page du projet) constitue l’avancée la plus importante en matière de génération procédurale de terrains depuis le bruit de Perlin en 1985. Ces travaux ont depuis été acceptés à la SIGGRAPH 2026, et leur titre de référence sur arXiv est désormais « InfiniteDiffusion: Bridging Learned Fidelity and Procedural Utility for Open-World Terrain Generation ». L’algorithme InfiniteDiffusion et le framework Terrain Diffusion constituent les deux volets du même article.

L’innovation principale est InfiniteDiffusion, un algorithme qui reformule l’échantillonnage par diffusion pour des domaines non bornés. Les modèles de diffusion traditionnels génèrent des sorties de taille fixe (par exemple, une carte de hauteur de 512 x 512). InfiniteDiffusion génère un terrain d’étendue infinie avec :

  • Cohérence de la graine : une même graine produit toujours le même terrain, comme avec le bruit de Perlin
  • Accès aléatoire en temps constant : vous pouvez interroger la hauteur de n’importe quel point sans générer d’abord les régions voisines
  • Aucun artefact aux limites : une génération infinie sans raccords visibles ni répétitions

Le système utilise une pile hiérarchique de modèles de diffusion. Le niveau supérieur capture les caractéristiques à l’échelle planétaire (continents, chaînes de montagnes). Chaque niveau suivant ajoute des détails plus fins (sommets individuels, vallées, rugosité à petite échelle). Un encodage laplacien compact stabilise les sorties sur l’immense plage dynamique allant du niveau de la mer aux sommets himalayens.

Performances : La génération suit le rythme d’une exploration en temps réel. L’article indique que, même à la limite théorique d’une vitesse orbitale (environ 7 700 m/s), la synthèse du terrain s’exécute 9 fois plus vite que le déplacement sur un GPU grand public. Le projet comprend une intégration à Minecraft qui démontre la synthèse de terrain en temps réel. Pourquoi c’est important pour nous : Terrain Diffusion produit des paysages entraînés à partir de données d’altitude réelles (la topographie effective de la Terre). Les réseaux fluviaux, chaînes de montagnes, éléments côtiers et plateaux présents dans les résultats sont issus des données d’entraînement, et non de paramètres de bruit réglés manuellement. Un créateur pourrait demander « générer un terrain semblable aux Highlands écossais » et le modèle de diffusion produirait un résultat présentant les caractéristiques géologiques appropriées.

Le modèle s’exécute côté serveur pendant la génération du monde. Le résultat est une carte de hauteur standard, transmise progressivement au navigateur comme n’importe quelle autre donnée de terrain. La méthode de génération est invisible pour le client.

TerraFusion : géométrie et texture générées conjointement

TerraFusion génère conjointement des cartes de hauteur de terrain et les textures de surface correspondantes à partir de croquis grâce à la diffusion latente
TerraFusion génère simultanément une carte de hauteur et une texture à partir d’un croquis dessiné à la main. La corrélation entre géométrie et matériau est intégrée dès la génération : les lits de rivière sont sablonneux, les parois des falaises rocheuses et les terrains plats herbeux, sans aucune peinture manuelle de splat maps.

TerraFusion (2025, arXiv:2505.04050) va plus loin en générant conjointement des cartes de hauteur et des textures de terrain. L’idée clé : la géométrie du terrain et l’apparence de sa surface sont corrélées (les lits de rivière sont sablonneux, les parois des falaises rocheuses et les zones plates herbeuses). Les générer séparément produit des incohérences.

TerraFusion utilise un modèle de diffusion latente doté de VAE distincts pour les cartes de hauteur et les textures, entraîné à modéliser leur distribution conjointe. Le système prend en charge :

  • Génération non conditionnée : terrain plausible aléatoire avec des textures correspondantes
  • Génération conditionnée par un croquis : un créateur dessine une carte approximative (vallées ici, crêtes là, falaises le long de ce bord) et le modèle génère une géométrie détaillée ainsi que des textures correspondant au croquis

Pour un monde de créateur, c’est très puissant. Le créateur esquisse la disposition générale de sa parcelle, puis le système complète le tout avec un terrain géologiquement plausible et des matériaux de surface appropriés. Nul besoin de peindre une carte de hauteur, de projeter des textures par splatting ou d’attribuer manuellement les matériaux.

MESA : du texte au terrain

MESA génère des images de terrain de style satellite et des cartes d’altitude à partir de prompts textuels, grâce à un entraînement sur les données mondiales de Copernicus
MESA produit des paires composées d’images satellite et de MNT à partir de prompts textuels. Entraîné sur le jeu de données mondial de Copernicus, il comprend les terrains réels à toutes les échelles et dans toutes les zones climatiques : fjords, steppes, terres agricoles et crêtes alpines.

MESA (2025, arXiv:2504.07210, atelier CVPR 2025) génère des terrains à partir de descriptions textuelles. Il est entraîné sur les données mondiales de télédétection du programme Copernicus, ce qui l’expose à tous les types de paysages terrestres.

Un prompt tel que « un fjord aux parois abruptes de granite s’ouvrant sur une côte rocheuse » produit une carte de hauteur présentant la structure géologique appropriée. « Des terres agricoles vallonnées, avec de douces collines et une large vallée fluviale » produit un résultat totalement différent.

MESA introduit le jeu de données d’extension Major TOM Core-DEM, qui associe à l’échelle mondiale des images satellite à des modèles numériques d’altitude. Ces données d’entraînement permettent au modèle de comprendre l’apparence des terrains réels à toutes les échelles et dans toutes les zones climatiques.

Geodiffussr : texturation du terrain guidée par du texte

Geodiffussr génère des textures de terrain à partir de descriptions textuelles tout en respectant les données d’altitude : neige sur les sommets, sable sur les côtes et forêt sur les pentes
Geodiffussr prend une carte de hauteur et un prompt textuel, puis génère des textures de surface respectant l’altitude. La neige n’apparaît qu’au-dessus d’altitudes plausibles, la végétation se raréfie avec la hauteur et l’eau occupe les dépressions. La géométrie reste inchangée.

Geodiffussr (2025, arXiv:2511.23029) prend une carte de hauteur existante et génère des textures guidées par des descriptions textuelles, tout en respectant les données d’altitude. « Forêt automnale » produit un feuillage orange et doré sur les pentes modérées, avec de la roche nue sur les parois abruptes. « Côte tropicale » produit une végétation de palmiers sur les terres basses, avec du sable corallien au niveau de la mer.

Le système utilise une agrégation de contenu multi-échelle afin que l’attribution des textures respecte l’altitude : la neige n’apparaît qu’au-dessus d’une altitude physiquement plausible, les étendues d’eau occupent les dépressions et la végétation se raréfie avec l’altitude.

Pour un monde de créateur, cela signifie que les textures du terrain peuvent être régénérées à partir d’un prompt textuel sans modifier la géométrie. Le créateur sculpte le terrain voulu, puis décrit l’ambiance (« sombre étendue volcanique désolée » ou « forêt tempérée luxuriante ») et le système génère les matériaux de surface appropriés.

LOD dynamique pour les terrains dans le navigateur

Il est impossible, dans un navigateur, d’afficher partout un vaste terrain en pleine résolution. Un monde de 4 km sur 4 km avec une résolution d’un mètre représente à lui seul 16 millions de sommets de terrain. Le LOD dynamique ramène ce nombre à une quantité constante et gérable, quelle que soit la taille du monde.

Clipmaps géométriques

La présentation originale des clipmaps géométriques à SIGGRAPH 2004. Des anneaux concentriques de terrain aux résolutions successivement divisées par deux maintiennent un nombre constant de sommets, quelle que soit la taille du monde. Cette technique demeure le fondement de la plupart des systèmes de LOD de terrain dans les navigateurs actuels.

Les clipmaps géométriques (Losasso et Hoppe, SIGGRAPH 2004, Article) restent la référence pour le LOD des terrains reposant sur des cartes de hauteur. Le principe : afficher le terrain sous la forme d’un ensemble d’anneaux carrés concentriques centrés sur la caméra. Chaque anneau couvre une surface deux fois supérieure à celle du précédent, mais à la moitié de sa résolution.

Près de la caméra (anneau le plus intérieur) : pleine résolution, avec un espacement de grille d’un mètre. Anneau suivant : espacement de 2 mètres, couvrant 4 fois plus de surface. Anneau suivant : espacement de 4 mètres, couvrant 16 fois plus de surface. Et ainsi de suite sur 6 à 8 niveaux, jusqu’à ce que l’anneau le plus extérieur couvre toute la distance visible.

Le nombre total de sommets est constant : environ N^2 * niveaux, où N représente la largeur d’un anneau en nombre de sommets. Avec N=256 et 8 niveaux, cela représente environ 500 000 sommets au total. Le rendu reste identique, que le monde mesure 1 km ou 100 km de large.

Implémentation dans le navigateur : les clipmaps géométriques fonctionnent avec WebGL 2, car elles ne nécessitent que des mises à jour standard des tampons de sommets, sans compute shaders. À mesure que la caméra se déplace, le processeur met à jour les données de carte de hauteur de chaque anneau en échantillonnant le terrain à la résolution appropriée. Le vertex shader lit les valeurs d’altitude dans une texture et déplace la grille plane.

Morphing : la transition entre les niveaux de LOD produit des « sauts » visibles lorsqu’elle est gérée naïvement. Le géomorphing, détaillé dans sa propre section ci-dessous, interpole les positions des sommets entre les niveaux au sein d’une zone de transition dans le vertex shader. Il produit ainsi des transitions fluides et sans saut, sans coût d’appel de rendu supplémentaire.

CDLOD : clipmaps adaptatives basées sur un quadtree

CDLOD (Strugar, 2014, Article) améliore les clipmaps géométriques en utilisant un quadtree au lieu d’anneaux concentriques fixes. Le quadtree s’adapte au terrain : les zones planes utilisent des nœuds grossiers, tandis que les zones très détaillées, comme les falaises et les crêtes, bénéficient d’une subdivision plus fine.

C’est important pour un monde de créateur, car la complexité varie d’un chunk à l’autre. Une prairie plane ne nécessite qu’une résolution minimale. Une région montagneuse dotée de falaises et de grottes exige un niveau de détail maximal. CDLOD affecte la résolution là où elle est nécessaire.

Le parcours du quadtree côté processeur est léger, avec quelques centaines de nœuds, et détermine quelles parcelles de terrain afficher et à quelle résolution. Le processeur graphique affiche chaque parcelle sous la forme d’une grille instanciée, avec des uniformes de LOD propres à chaque parcelle.

Arbres binaires concurrents : tessellation à l’échelle planétaire

Tessellation adaptative par CBT pour un terrain à l’échelle planétaire : les triangles se subdivisent près de la caméra et fusionnent au loin, entièrement sur le processeur graphique. Moins de 0,2 ms sur du matériel de console.

Les arbres binaires concurrents (CBT) sont une structure de données adaptée au processeur graphique pour la tessellation adaptative des terrains, présentée par Benyoub et Dupuy (Intel, HPG 2024, Article, GitHub).

Le principe fondamental : représenter le terrain sous la forme d’un arbre binaire dont chaque nœud est un triangle. La subdivision adaptative divise les triangles proches de la caméra et fusionne ceux qui en sont éloignés. L’arbre binaire réside entièrement dans la mémoire du processeur graphique sous forme de tableau unidimensionnel, ou tas binaire, et les opérations de subdivision et de fusion s’exécutent dans des compute shaders.

L’article de 2024 étend les CBT des domaines carrés de cartes de hauteur aux maillages polygonaux arbitraires. Cela permet de tesseller une sphère, pour le rendu planétaire, ou un maillage de base arbitraire, pour un monde de jeu aux limites non rectangulaires. L’amélioration clé consiste à employer le CBT comme gestionnaire de réserve mémoire au lieu d’utiliser un encodage implicite, ce qui autorise des niveaux de subdivision beaucoup plus élevés.

Performances : tessellation d’un terrain à l’échelle planétaire en moins de 0,2 ms sur du matériel de niveau console. L’algorithme évolue linéairement avec le nombre de processeurs. Pour WebGPU, cela ouvre la voie au rendu de terrains à l’échelle planétaire dans un navigateur, même si la mise en œuvre reste complexe.

LOD piloté par le processeur graphique avec WebGPU

WebGPU permet de créer un pipeline de terrain entièrement piloté par le processeur graphique, supprimant toute intervention du processeur central dans les décisions de LOD :

  1. Passe de calcul 1 : élimination par frustum et occlusion. Un compute shader teste la boîte englobante de chaque parcelle de terrain par rapport au frustum de vue et à un tampon d’occlusion, c’est-à-dire le tampon de profondeur de l’image précédente sous-échantillonné. Les parcelles invisibles sont entièrement éliminées.

  2. Passe de calcul 2 : sélection du LOD. Pour les parcelles visibles, le système calcule la taille à l’écran et sélectionne le niveau de LOD approprié. Il écrit le niveau de LOD et l’identifiant de la parcelle dans un tampon de rendu indirect.

  3. Passe de calcul 3 : génération du maillage (pour les terrains volumétriques). Pour les chunks contenant des données SDF, l’algorithme des marching cubes génère le maillage à la résolution de LOD sélectionnée.

  4. Rendu indirect. Un unique appel à drawIndexedIndirect() affiche toutes les parcelles de terrain. Le processeur graphique décide de tout : quoi afficher, à quelle résolution et dans quel ordre.

Ce pipeline présente un coût processeur constant, limité au lancement des compute shaders et à l’appel de rendu indirect, indépendamment de la taille ou de la complexité du monde. Le processeur graphique gère toutes les décisions propres à chaque parcelle.

wgsl
@compute @workgroup_size(64)
fn lodSelection(@builtin(global_invocation_id) id: vec3<u32>) {
    let patchIdx = id.x;
    let bounds = patchBounds[patchIdx];

    if (!frustumTest(bounds, viewProjection)) { return; }
    if (occlusionTest(bounds, depthPyramid) == OCCLUDED) { return; }

    let screenSize = projectedSize(bounds, viewProjection, screenDimensions);
    let lod = clamp(u32(log2(maxScreenSize / screenSize)), 0u, MAX_LOD);

    let drawIdx = atomicAdd(&drawCount, 1u);
    drawArgs[drawIdx] = DrawArgs(patchIdx, lod, indexCount[lod], indexOffset[lod]);
}

Géomorphing : transitions de LOD sans saut

Le principal artefact visuel du LOD de terrain est le saut : les sommets changent brusquement de position lorsqu’une parcelle passe à un autre niveau de LOD. Le géomorphing élimine ce problème en interpolant progressivement la position des sommets entre les niveaux de LOD dans une zone de transition.

L’implémentation réside entièrement dans le vertex shader. Chaque sommet stocke à la fois sa position au LOD actuel et sa position au niveau de LOD moins détaillé suivant. Lorsque la distance de la caméra franchit le seuil de transition, un facteur de morphing effectue l’interpolation entre les deux :

glsl
float morphFactor = smoothstep(lodNear, lodFar, distanceToCamera);
float morphedHeight = mix(fineLodHeight, coarseLodHeight, morphFactor);
gl_Position = viewProjection * vec4(worldPos.x, morphedHeight, worldPos.z, 1.0);

L’article de Hoppe sur les clipmaps géométriques (GPU Gems 2, Chapitre 2) décrit l’implémentation complète pour les anneaux de clipmap. La zone de morphing correspond aux 20 % extérieurs de chaque anneau. Dans cette zone, les sommets convergent progressivement vers la résolution de l’anneau suivant. Visuellement, la géométrie du terrain « fond » entre les niveaux de détail au lieu de changer brutalement. Aux vitesses de caméra habituelles, la transition est invisible.

Le mélange dans l’espace image (Scherzer et al., Article) constitue une autre approche, qui mélange dans l’espace écran les images rendues de deux niveaux de LOD. Cette méthode gère des différences de LOD plus extrêmes, par exemple les transitions entre maillage et billboard, mais nécessite une passe de rendu supplémentaire pour la zone de transition.

Élimination de la végétation pilotée par le processeur graphique

La végétation, notamment les arbres, l’herbe et les rochers, constitue souvent la principale source d’appels de rendu dans un monde ouvert. Une approche naïve affiche chaque instance de végétation à chaque image. L’élimination pilotée par le processeur graphique, désormais disponible dans Three.js via WebGPU, supprime les instances invisibles avant qu’elles n’atteignent le rastériseur.

ComputeInstanceCulling de Three.js (Documentation) assure l’élimination par frustum et par LOD pour les maillages instanciés, avec des gains de performances de 10 à 100 fois lorsque le nombre d’instances est élevé. Le pipeline :

  1. Un compute shader lit les sphères englobantes de toutes les instances
  2. Il teste chacune d’elles par rapport au frustum de la caméra, à l’aide d’un test sur 6 plans
  3. Il applique un LOD fondé sur la distance : les instances situées au-delà d’un seuil passent à un niveau de détail inférieur ou sont entièrement éliminées
  4. Les instances restantes sont compactées dans un tampon et affichées via drawIndirect Le CPU n’effectue aucun travail par instance. Après la configuration initiale, le coût se résume à un dispatch de calcul et un appel de rendu indirect par type de végétation, quel que soit le nombre d’instances.

Pour une végétation plus dense, l’IndirectBatchedMesh de Three.js (Documentation) regroupe plusieurs types de géométrie (arbres, buissons, rochers) dans un seul tampon et les affiche au moyen d’un rendu indirect multi-draw. Un seul appel de rendu suffit pour toute la végétation d’un chunk.

Combiné à la dispersion fondée sur les cartes de densité de notre système de végétation, cela signifie que la carte de densité génère les positions de 50 000 brins d’herbe dans un shader de calcul, que la passe d’élimination retire les 70 % qui sont hors écran ou trop éloignés, puis qu’un seul appel de rendu indirect affiche les 15 000 brins restants. Coût total côté CPU : négligeable.

LOD pour les terrains volumétriques

Les terrains volumétriques (SDF + marching cubes) nécessitent leur propre système de LOD, car le maillage est généré et non créé au préalable. Voici l’approche :

Stockage SDF multirésolution. Stockez le SDF à plusieurs résolutions dans une hiérarchie semblable à celle des mipmaps. Le niveau 0 utilise la pleine résolution (voxels de 1 mètre). Le niveau 1 utilise des voxels de 2 mètres (8 fois moins de données). Le niveau 2 utilise des voxels de 4 mètres. À chaque niveau, le SDF est sous-échantillonné en retenant la distance absolue minimale.

Marching cubes sélectionné selon le LOD. Exécutez marching cubes sur le niveau SDF correspondant au LOD souhaité. Les chunks proches utilisent le niveau 0. Les chunks éloignés utilisent le niveau 2 ou 3. L’algorithme Transvoxel gère la frontière entre les différents niveaux.

Mise en cache. Les maillages générés sont mis en cache jusqu’à ce que le SDF change (modification par un créateur) ou que le niveau de LOD change (déplacement important de la caméra). Pour un terrain statique, le maillage est généré une seule fois, puis réutilisé.

Architecture de streaming du terrain

Format des données d’un chunk

Chaque chunk de terrain (64 × 64 mètres) est transmis sous la forme d’un paquet binaire compact :

ChunkPacket {
  header: {
    chunkX: i16, chunkZ: i16,
    version: u32,
    flags: u8  // hasHeightmap | hasVolumetric | hasVegetation
  }
  heightmap: {
    resolution: u8,      // 65x65 for full, 33x33 for half, 17x17 for quarter
    quantizedHeights: u16[resolution * resolution],  // delta-encoded, zlib compressed
    splatMap: u8[4 * resolution * resolution]         // RGBA blend weights, LZ4 compressed
  }
  volumetric?: {         // only present if flags.hasVolumetric
    sdfResolution: u8,   // typically 32 or 64
    sparseOctree: bytes  // run-length encoded sparse SDF
  }
  vegetation?: {         // only present if flags.hasVegetation
    treeDensityMap: u8[16 * 16],    // 4m resolution density grid
    grassDensityMap: u8[32 * 32],   // 2m resolution density grid
    rockDensityMap: u8[16 * 16]
  }
  creatorObjects: {
    count: u16,
    objects: PlacedObject[]   // assetId + transform + properties, ~40 bytes each
  }
}

Tailles habituelles :

  • Chunk avec carte de hauteur uniquement (terrain plat) : 2 à 4 Ko compressés
  • Carte de hauteur + végétation : 4 à 8 Ko
  • Carte de hauteur + données volumétriques + végétation (chunk complexe) : 20 à 100 Ko
  • Voisinage de 5 × 5 chunks en pleine résolution : 50 à 500 Ko au total

Chargement progressif des chunks

Les chunks sont chargés par ordre de priorité en fonction de la distance, de la direction du déplacement et du type de données :

Priorité 1 (immédiate, <100 ms) : géométrie de la carte de hauteur pour les chunks dans lesquels le joueur est sur le point d’entrer. La surface du terrain apparaît en premier. Même à la résolution la plus basse (17 × 17 par chunk), le sol est présent.

Priorité 2 (rapide, <300 ms) : splat maps et textures du terrain. Le sol acquiert ses couleurs.

Priorité 3 (streaming, <1 s) : passage de la carte de hauteur à la pleine résolution. Cartes de densité de la végétation. L’instanciation GPU génère les arbres et l’herbe.

Priorité 4 (arrière-plan, ❤️ s) : données SDF volumétriques pour les chunks comportant des grottes ou des surplombs. Marching cubes génère le maillage dans un Web Worker, puis transfère le tampon vers le thread principal.

Priorité 5 (différée, <10 s) : objets placés par les créateurs. Textures haute résolution des structures. Objets de détail comme les fleurs, les petits rochers et les débris.

Préchargement prédictif

N’attendez pas que le joueur entre dans un chunk pour le charger. Prédisez sa destination à partir de sa vélocité et chargez les données en avance :

  • Marche (5 km/h) : préchargez 2 chunks en avant (128 m). Avec la latence habituelle d’une connexion haut débit, cela offre une avance de 200 à 400 ms.
  • Course/déplacement à monture (15 km/h) : préchargez 4 chunks en avant. L’anneau de chargement se décale selon la direction de la vélocité.
  • Vol/voyage rapide : suspendez le rendu pendant la transition. Transmettez les chunks de destination avec la priorité la plus élevée. Reprenez le rendu dès que suffisamment de données sont disponibles pour produire une première image.

Le système de préchargement suit les chunks présents dans le cache, ceux en cours de transfert (demandés, mais pas encore reçus) et ceux qui sont nécessaires. Une file de priorité trie les requêtes en attente selon leur urgence. Annulez les requêtes concernant les chunks dont le joueur s’est éloigné.

Budget mémoire et éviction

Un onglet de navigateur dispose de 2 à 4 Go sur un ordinateur de bureau. Le système de terrain doit n’en utiliser qu’une partie, le reste étant réservé au rendu, à la physique, au réseau et au tas JavaScript.

Budget cible : 256 Mo pour toutes les données du terrain.

Avec les tailles habituelles de nos chunks :

  • Chunks en pleine résolution mis en cache : environ 100 (voisinage de 10 × 10) à 5-100 Ko chacun = 5 à 10 Mo de données brutes
  • Géométrie du terrain sur le GPU : environ 50 Mo (tampons de sommets et d’indices du terrain visible)
  • Textures du terrain : environ 100 Mo (compressées en KTX2 et regroupées dans des atlas)
  • Tampons d’instances de végétation : environ 50 Mo (positions, rotations et échelles pour l’instanciation GPU)
  • Volumes SDF et maillages marching cubes mis en cache : environ 50 Mo

Les chunks situés au-delà de la portée visible sont d’abord évincés de la mémoire GPU (textures, tampons de sommets), puis du cache CPU. Les données brutes des cartes de hauteur sont supprimées en dernier, car elles sont les moins coûteuses à conserver et les plus importantes à avoir sous la main lorsque le joueur fait demi-tour.

Transitions entre biomes et suppression des répétitions

Frontières fluides entre les biomes

Les paysages réels ne présentent pas de frontières nettes entre les biomes. Une forêt ne s’arrête pas brusquement sur une ligne pour devenir un désert. Il existe un gradient : la forêt dense s’éclaircit pour laisser place à des arbres dispersés, puis à une végétation de broussailles et enfin à une végétation désertique clairsemée. Une transition réussie donne l’impression d’un monde continu plutôt que constitué de tuiles.

AutoBiomes (Kötter et al., Article) associe la génération procédurale de terrain à une simulation climatique simplifiée. La température, l’humidité et l’altitude déterminent le type de biome en chaque point. Entre les biomes, les poids des matériaux et la densité de la végétation sont interpolés sur une zone de transition, généralement large de 50 à 100 mètres. La largeur de la transition varie selon la paire de biomes : celle entre une forêt et une prairie est large et progressive, tandis que celle entre une falaise et l’eau est étroite et abrupte.

Dans un monde créé par les utilisateurs, l’attribution des biomes s’effectue sur une grille grossière (un échantillon de biome par zone de 16 × 16 mètres). Le shader du terrain lit les valeurs de biome du fragment actuel et de ses voisins, interpole les poids des matériaux dans la zone de transition, puis mélange les textures en conséquence. La dispersion de la végétation utilise les mêmes valeurs de densité interpolées, si bien que la densité des arbres diminue progressivement à la lisière de la forêt.

Contrôle des créateurs : permettez-leur de peindre des remplacements de biome sur leurs parcelles. Le système génère des biomes par défaut à partir des propriétés du terrain, mais les créateurs peuvent les remplacer. Peignez un « marais » dans une zone basse et le matériau se transforme en eau trouble, en mousse et en arbres morts. La carte de peinture des biomes est une grille par chunk de 16 × 16 identifiants de biome (256 octets), qui remplace l’attribution procédurale.

Pavage hexagonal : éliminer la répétition des textures

L’artefact visuel le plus courant dans le rendu de terrain est la répétition des textures. Une texture d’herbe de 1 mètre répétée sur une prairie de 100 mètres produit des motifs de grille visibles. Deux techniques permettent d’y remédier :

Pavage hexagonal (Mikkelsen, Démo) remplace la grille de pavage carrée par une grille hexagonale. Chaque tuile hexagonale échantillonne la texture avec un décalage et une rotation aléatoires. Les limites hexagonales sont fusionnées afin de masquer les raccords. Le résultat est une surface qui semble uniformément aléatoire plutôt que répétitive. Coût : environ 3 échantillonnages de texture supplémentaires par fragment. Cette technique est largement utilisée dans les jeux en production et fonctionne dans n’importe quel fragment shader.

Filtrage stochastique des textures (Pharr et al., NVIDIA, 2024, Article) applique le filtrage après l’ombrage plutôt qu’avant, en utilisant un échantillonnage stochastique. L’erreur issue de cet échantillonnage est minime et bien corrigée par le débruitage spatiotemporel. Cette méthode produit un filtrage plus précis et fonctionne avec les textures compressées ou creuses. Pour le terrain, elle élimine à la fois les artefacts de répétition et ceux de filtrage que le pavage hexagonal peut parfois introduire au niveau des transitions.

Pour un monde dans le navigateur, le pavage hexagonal constitue le choix le plus pratique, car il fonctionne dans n’importe quel shader. Le filtrage stochastique nécessite davantage d’infrastructure, mais produit de meilleurs résultats lorsqu’un débruitage temporel est disponible, comme ce serait le cas dans une chaîne de rendu WebGPU avec TAA.

Système de matériaux du terrain

Projection triplanaire

Les textures utilisant un mapping UV standard s’étirent terriblement sur les pentes raides, car les coordonnées UV se compriment. La projection triplanaire projette les textures le long des trois axes (X, Y, Z) et les mélange selon la normale de la surface :

glsl
vec3 blending = abs(normal);
blending = normalize(max(blending, 0.00001));
blending /= (blending.x + blending.y + blending.z);

vec4 xaxis = texture(material, worldPos.yz * scale);
vec4 yaxis = texture(material, worldPos.xz * scale);
vec4 zaxis = texture(material, worldPos.xy * scale);

vec4 color = xaxis * blending.x + yaxis * blending.y + zaxis * blending.z;

Les parois des falaises utilisent la projection X ou Z, sans étirement. Les sols plats utilisent la projection Y. Le mélange est fluide et automatique. Aucun dépliage UV n’est nécessaire.

Babylon.js possède un matériau triplanaire intégré. Three.js nécessite un shader personnalisé, mais l’implémentation ne demande qu’une trentaine de lignes de GLSL.

Pour un terrain PBR, appliquez la projection triplanaire à tous les canaux : albédo, normales, rugosité et occlusion ambiante. Les mêmes poids de mélange s’appliquent à chaque canal.

Attribution des matériaux selon la pente et l’altitude

Au lieu de peindre manuellement des splat maps, attribuez les matériaux de manière procédurale selon les propriétés du terrain :

glsl
float slope = acos(dot(normal, vec3(0, 1, 0)));
float altitude = worldPos.y;

float grassWeight = smoothstep(0.3, 0.0, slope) * smoothstep(2000.0, 1500.0, altitude);
float rockWeight = smoothstep(0.2, 0.5, slope);
float snowWeight = smoothstep(2500.0, 3000.0, altitude) * smoothstep(0.4, 0.1, slope);
float sandWeight = smoothstep(5.0, 0.0, altitude) * smoothstep(0.15, 0.0, slope);

À basse altitude, les sols plats sont recouverts d’herbe. Les pentes raides sont rocheuses. La neige apparaît en altitude, mais uniquement sur les surfaces suffisamment plates pour qu’elle puisse s’accumuler. Le sable apparaît près du niveau de la mer. Les transitions sont fluides et reposent sur des principes physiques.

Dans un monde créé par les utilisateurs, exposez les seuils d’altitude et les zones de mélange sous forme de paramètres modifiables à la peinture pour chaque chunk. Les créateurs peuvent relever ou abaisser la limite des arbres, étendre la couverture neigeuse ou transformer une colline herbeuse en désert de sable en ajustant les règles de matériaux de leur parcelle.

Mélange laplacien de textures optimisé pour le GPU

Le mélange standard des textures, par interpolation linéaire entre les couches, produit soit des raccords visibles, soit des résultats délavés et peu contrastés. Le mélange par pyramide laplacienne résout ce problème, mais nécessite traditionnellement un prétraitement coûteux.

Wronski (NVIDIA, 2025, JCGT) présente une variante adaptée au GPU qui fonctionne dans des shaders en temps réel, sans prétraitement ni mémoire supplémentaire. Cette technique utilise la chaîne de mipmaps standard comme approximation de la pyramide laplacienne : elle échantillonne la texture à la fois au niveau de mipmap actuel et à un niveau plus grossier, calcule la différence (le laplacien), puis mélange les contributions laplaciennes de chaque couche.

Le résultat préserve les détails locaux nets, comme les brins d’herbe et les fissures des rochers, tout en assurant un mélange fluide à plus grande échelle. Le coût se limite à quelques lectures de texture supplémentaires par fragment. Pour un terrain où plus de quatre couches de matériaux sont mélangées par pixel, cette méthode produit des résultats sensiblement meilleurs que le mélange linéaire, surtout aux transitions entre l’herbe, la roche et le sable.

Bruit de phase pour les détails d’érosion

Les terrains standards paraissent souvent plats de près, car la simulation d’érosion fonctionne à la résolution de la carte de hauteur, sur une grille de 1 mètre. Les terrains réels présentent des motifs d’érosion à petite échelle — rigoles, ravines et fissures dues aux intempéries — de l’ordre du centimètre.

Grenier et al. (2024, CGF) utilisent le bruit de phase pour ajouter en temps réel des microdétails au terrain. Le bruit de phase synthétise des motifs structurés en définissant un champ de phase stochastique fourni à des fonctions périodiques. Appliqué au terrain, il crée des motifs d’érosion spatialement variables qui :

  • Font converger d’étroites rigoles en ravines plus importantes à différentes échelles
  • S’alignent automatiquement sur la pente du terrain, les motifs d’érosion suivant la ligne de plus grande pente
  • Atteignent un facteur d’amplification pouvant aller jusqu’à 32, en ajoutant des détails à une résolution 32 fois supérieure à celle de la carte de hauteur
  • S’exécutent entièrement dans un fragment shader à des fréquences d’images interactives

Pour un monde dans le navigateur, le bruit de phase s’exécute dans le shader du terrain comme une couche de détails. La carte de hauteur fournit la forme à grande échelle. Le bruit de phase ajoute des micro-érosions convaincantes dans le fragment shader sans augmenter la complexité géométrique. Les paramètres — fréquence, amplitude et orientation des motifs — peuvent varier selon le biome : rigoles profondes sur la roche nue, douces ondulations sur les dunes de sable, texture rugueuse évoquant l’écorce sur la boue séchée.

Texturation virtuelle du terrain

À grande échelle, l’atlas de textures du terrain devient difficile à gérer. Un monde de 4 km × 4 km avec 1 texel par centimètre nécessiterait une texture de 400 000 × 400 000 pixels. C’est évidemment impossible.

La texturation virtuelle, également appelée mégatexture d’après Rage d’id Software, résout ce problème en traitant la texture du terrain comme une structure paginée. La texture complète existe conceptuellement, mais seules les tuiles visibles à l’écran sont chargées dans la mémoire GPU. Le pipeline :

  1. Passe de rétroaction : effectuez le rendu du terrain avec un shader qui indique la tuile de texture requise par chaque pixel (ID de tuile et niveau de mipmap). Renvoyez ces données au CPU, ou traitez-les avec un shader de calcul.
  2. Chargement des tuiles : chargez les tuiles demandées depuis le CDN ou générez-les procéduralement à partir des données de la splat map.
  3. Texture d’indirection : une petite texture associe les coordonnées des tuiles virtuelles aux coordonnées des tuiles physiques dans un atlas de textures.
  4. Passe de rendu : le shader du terrain consulte la texture d’indirection pour trouver la bonne tuile physique, puis échantillonne la texture du matériau dans l’atlas.

Les shaders de calcul de WebGPU peuvent gérer entièrement sur le GPU l’analyse de la rétroaction et la gestion de la table des pages. Le CPU ne gère que les entrées-sorties des tuiles.

Résultat : un terrain doté de textures uniques à n’importe quelle résolution, sans explosion de la mémoire dédiée aux textures. Les tuiles éloignées de la caméra sont chargées en basse résolution. Les tuiles vues de près sont chargées en haute résolution. L’utilisation totale de la mémoire reste dans les limites d’un budget fixe, généralement un atlas de textures de 128 à 256 Mo.

Effets de terrain dynamiques

Flaques et surfaces mouillées

La pluie ne fait pas que tomber. Elle s’accumule. Dans les creux, elle forme des flaques. Sur les surfaces, elle crée un éclat humide. Sur les pentes raides, elle ruisselle. La simulation de ces phénomènes donne l’impression que la météo interagit avec le terrain au lieu de n’être qu’une simple surcouche visuelle.

L’approche fondée sur les shaders ne simule pas la dynamique des fluides. Elle utilise la heightmap du terrain pour déterminer où l’eau s’accumule :

glsl
float concavity = heightCenter * 4.0 - heightLeft - heightRight - heightUp - heightDown;
float puddleDepth = max(0.0, concavity * rainIntensity - evaporationRate * timeSinceRain);
float wetness = smoothstep(0.0, 0.02, puddleDepth);

vec3 wetColor = baseColor * 0.7;
float wetRoughness = baseRoughness * 0.3;
vec3 finalColor = mix(baseColor, wetColor, wetness);
float finalRoughness = mix(baseRoughness, wetRoughness, wetness);

Les zones concaves (laplacien négatif de la heightmap) recueillent l’eau. Plus la concavité est profonde, plus la flaque est grande. Les surfaces mouillées s’assombrissent et deviennent plus réfléchissantes, avec une rugosité plus faible. L’effet s’estompe progressivement après l’arrêt de la pluie.

Pour obtenir des reflets complets dans les flaques, ajoutez une passe de réflexion plane au niveau de leur surface. Vous pouvez aussi utiliser des réflexions en espace écran (SSR), moins coûteuses et déjà disponibles dans les piles de post-traitement de Three.js et Babylon.js.

Les gouttes de pluie à la surface des flaques utilisent une simple équation d’onde 2D dans une texture de rétroaction (Saurel, 2026, blog). Chaque goutte crée une onde qui se propage vers l’extérieur avant de s’atténuer. La texture d’onde module la normal map de la flaque, produisant des ondulations convaincantes à 60 images par seconde.

Empreintes de pas et déformation du terrain

Lorsqu’un joueur marche sur un terrain meuble comme le sable, la neige ou la boue, les empreintes renforcent la sensation de présence physique. La technique consiste à conserver une petite texture de déformation par chunk (64 × 64 pixels, soit 4 Ko) qui stocke les décalages de hauteur. Lorsqu’un personnage pose le pied sur un terrain meuble, la forme d’une empreinte est appliquée à la texture de déformation.

Le vertex shader du terrain lit la texture de déformation et soustrait le décalage à la hauteur. Le fragment shader du terrain assombrit la zone de l’empreinte, car le sol comprimé est plus sombre, et augmente sa rugosité pour représenter une surface perturbée.

Les empreintes s’effacent progressivement : la neige les comble et la pluie élimine les traces dans la boue. Pour cela, la texture de déformation est graduellement remise à zéro. La vitesse d’effacement dépend de la météo : elle est rapide sous la pluie et lente par temps sec.

Dans un monde multijoueur, les données des empreintes sont éphémères et locales. Chaque client génère les empreintes des joueurs visibles. Il n’est pas nécessaire de synchroniser la texture de déformation entre les clients, car chacun voit sa propre version de ces empreintes temporaires. Cela évite le coût réseau qu’impliquerait la diffusion de chaque pas.

Ciel procédural et cycle jour/nuit

Le ciel est la plus grande surface visible de tout monde ouvert. Il définit l’ambiance de l’ensemble du terrain.

Three.js dispose d’un système de ciel complet comprenant un soleil et une lune procéduraux, un cycle jour/nuit, des nuages, des étoiles et des reflets de lentille. L’exemple Sky intégré à Three.js, également disponible avec WebGPU, implémente le modèle analytique de ciel de Preetham.

Pour des résultats physiquement plus précis, webgpu-sky-atmosphere implémente le modèle atmosphérique de Hillaire sous la forme d’un post-traitement WebGPU. Il prend en charge plusieurs fonctions de phase de diffusion et produit, à partir de principes physiques, une perspective aérienne correcte où le terrain lointain paraît plus brumeux, ainsi que les couleurs du soleil et du coucher de soleil et les dégradés du ciel.

TerrainView7 présente le rendu d’une planète à l’échelle réelle dans WebGPU avec une diffusion atmosphérique précalculée, prouvant qu’un rendu atmosphérique physiquement précis peut fonctionner dans un navigateur.

Dans un monde de créateurs, les paramètres du ciel — position du soleil, couverture nuageuse et densité de la brume — sont synchronisés entre tous les clients à partir de l’horloge du monde gérée par le serveur. Le shader du ciel s’exécute localement sur chaque client, produisant un éclairage cohérent pour tous les joueurs.

Éclairage du terrain : illumination indirecte

La lumière directe du soleil est gérée par les shadow maps. Mais la couleur et la luminosité du terrain dans l’ombre, c’est-à-dire la lumière ambiante et indirecte, sont tout aussi importantes pour la qualité visuelle. Des ombres entièrement noires ne sont pas réalistes. Elles doivent être teintées par la couleur du ciel : bleues par temps clair, grises par temps couvert.

Pour un monde dans le navigateur, l’approche pratique est la suivante :

L’éclairage indirect en espace écran avec masque de bits de visibilité (Jimenez et al., 2023, article) améliore le SSAO standard en suivant 32 secteurs de visibilité directionnelle par pixel. Il détermine ainsi non seulement le degré d’occlusion d’un point, mais aussi la direction de cette occlusion. Les surfaces minces laissent correctement passer la lumière provenant de l’autre côté. Le résultat est une illumination indirecte qui réagit à la géométrie voisine sans nécessiter d’infrastructure d’illumination globale.

Le coût est comparable à celui du SSAO, soit 1 à 2 ms. L’amélioration visuelle est importante : le terrain au fond des canyons reçoit la lumière réfléchie par leurs parois. Le dessous des surplombs est éclairé par la réflexion du sol. Cet effet se combine à la diffusion atmosphérique du shader du ciel pour produire un éclairage ambiant fondé sur des principes physiques.

Intégration de la physique du terrain

Colliders de heightfield Rapier

Le moteur physique WASM Rapier fournit des colliders de heightfield natifs optimisés pour le terrain. La création d’un collider de terrain est simple :

typescript
const heights = new Float32Array(65 * 65);
// Fill with heightmap data...
const groundCollider = RAPIER.ColliderDesc.heightfield(
  64, 64, heights, new RAPIER.Vector3(64.0, 100.0, 64.0)
);
world.createCollider(groundCollider);

Le collider de heightfield exploite la grille structurée pour effectuer efficacement les requêtes de broadphase. Un raycast sur une heightfield a une complexité O(log n), contre O(n) sur un maillage triangulaire. Pour un chunk de 65 × 65, les requêtes de collision sont résolues en quelques microsecondes.

Pour les chunks comportant un terrain volumétrique, sous forme de surcouches SDF, générez un maillage triangulaire à partir du résultat de marching cubes et utilisez un collider de trimesh. Celui-ci est plus coûteux qu’un collider de heightfield, mais prend en charge une géométrie arbitraire. Ne générez des colliders de trimesh que pour les 3 à 5 chunks les plus proches du joueur. Les chunks éloignés n’ont pas besoin de physique.

Performances : le collider de heightfield de Rapier pour un chunk de 65 × 65 ajoute environ 0,1 ms par étape de simulation physique pour les requêtes du contrôleur de personnage. Cinq chunks actifs dotés de colliders de heightfield prennent 0,5 ms. Un collider de trimesh pour un chunk volumétrique prend de 0,2 à 0,5 ms. Le budget total de la physique du terrain reste inférieur à 1 ms, bien dans la limite du budget de 2 à 3 ms consacré à la physique de l’ensemble du monde.

Contrôleur de personnage adapté au terrain

Le contrôleur de personnage doit réagir aux propriétés du terrain :

  • Limitation de pente : le personnage peut marcher sur des pentes allant jusqu’à 45 degrés. Les pentes plus raides le font glisser. Ce comportement utilise la normale du terrain à la position du personnage, calculée à faible coût à partir du gradient de la heightmap.
  • Réaction au matériau de surface : marcher sur de la roche produit des bruits de pas et une vitesse de déplacement différents de ceux du sable ou de la boue. La splat map du terrain fournit le matériau de surface en tout point.
  • Franchissement de marches : le personnage peut franchir des rebords mesurant jusqu’à 0,5 mètre. Le KinematicCharacterController de Rapier gère automatiquement ce comportement grâce à une hauteur de marche configurable.

Édition interactive du terrain dans le navigateur

Dans un monde de créateurs, le terrain n’est pas seulement généré. Il est sculpté, modifié et remodelé par les joueurs. Les outils d’édition doivent être réactifs, avec un retour visuel instantané, et mis en réseau afin que les autres joueurs voient les modifications en quelques secondes.

Éditeur SDF WebGPU

Le WebGPU SDF Editor de Reinder Nijhoff démontre qu’une modélisation SDF complète fonctionne aujourd’hui dans le navigateur. L’éditeur prend en charge :

  • Six formes primitives — sphère, boîte, cône, cylindre, capsule et tore — avec position, rotation et échelle
  • Des opérations booléennes — union, soustraction et intersection — avec fusion progressive et rayons de fusion configurables
  • Des graphes de scène hiérarchiques avec des groupes et des opérations imbriquées
  • Le rendu en temps réel à l’aide de plusieurs étapes de shaders de calcul GPU, d’un partitionnement spatial fondé sur un octree couvrant 16 384 cellules de grille et d’une extraction de surface par marching cubes ou surface nets
  • L’anticrénelage temporel et l’occlusion ambiante au moyen de shadow maps

Chaque primitive est stockée sous la forme de 28 nombres flottants (112 octets) dans un unique tampon GPU. Grâce à cette représentation compacte, une modification complexe du terrain — des dizaines de primitives SDF définissant l’entrée d’une grotte, une arche ou une falaise sculptée — pèse moins de 5 Ko et se synchronise instantanément avec les autres joueurs.

Dans un monde de créateurs, le processus d’édition SDF est le suivant :

  1. Le créateur sélectionne un outil de sculpture : ajout d’une sphère, soustraction d’une boîte ou fusion progressive.
  2. Il clique ou fait glisser le pointeur dans le monde afin de positionner et de dimensionner la primitive SDF.
  3. Le client exécute immédiatement marching cubes sur le SDF modifié afin d’actualiser le maillage local, avec un retour en moins de 16 ms.
  4. La modification SDF — type de primitive, transformation et mode de fusion, soit environ 100 octets — est envoyée au serveur.
  5. Le serveur valide la modification, en vérifiant qu’elle se trouve dans la parcelle du créateur et qu’elle ne chevauche aucune zone protégée, puis la diffuse aux joueurs proches.
  6. Les clients des autres joueurs appliquent la modification SDF et régénèrent leur maillage local.

Le temps aller-retour total nécessaire pour qu’une modification devienne visible par les autres joueurs est de 100 à 300 ms, selon la latence réseau. Le créateur voit sa modification instantanément, car elle est appliquée localement avant la confirmation du serveur.

Édition de heightmap au pinceau

Pour la couche de heightmap, qui représente les 90 % du terrain ne nécessitant aucune fonctionnalité volumétrique, un modèle d’édition plus simple suffit. Le créateur peint les modifications de hauteur avec un pinceau :

  • Élever/abaisser : ajouter ou soustraire de la hauteur dans un rayon, avec atténuation
  • Lisser : calculer la moyenne des hauteurs dans un rayon afin de supprimer les reliefs abrupts
  • Aplanir : régler toutes les hauteurs d’un rayon sur une valeur cible
  • Pinceau d’érosion : appliquer localement quelques étapes d’érosion hydraulique dans le rayon du pinceau

La modification de la heightmap est un delta : une petite zone de changements de hauteur superposée au terrain de base. Cette zone de delta est minuscule — une grille de 32 × 32 décalages de hauteur sur 16 bits, soit 2 Ko — et se synchronise avec les autres joueurs dans un seul message. Plusieurs zones de delta s’accumulent par chunk et sont périodiquement fusionnées côté serveur dans la heightmap persistante du chunk.

Contraintes de l’édition collaborative

Lorsque plusieurs créateurs modifient simultanément le même chunk, le système doit appliquer certaines règles :

  • Verrouillage spatial : un seul créateur à la fois peut modifier une sous-région donnée de 8 × 8 mètres. Le verrou est acquis lorsque le créateur commence un trait et libéré lorsqu’il relève le pinceau. Les verrous expirent après 10 secondes d’inactivité.
  • Modifications sans chevauchement : si deux créateurs modifient des parties différentes du même chunk, les deux modifications sont appliquées sans conflit, car elles affectent des cellules de heightmap ou des régions SDF différentes.
  • Modifications avec chevauchement : si deux créateurs modifient le même emplacement, le serveur sérialise les modifications dans leur ordre d’arrivée. Après réconciliation, les deux clients voient le même résultat final.

Cette approche est plus simple que le modèle CRDT complet utilisé pour les objets placés, car les modifications de terrain sont des opérations additives appliquées à un champ continu — hauteurs ou distances SDF — plutôt qu’à l’état d’objets discrets.

Géométrie virtuelle de type Nanite dans WebGPU

Nanite d’Unreal Engine 5 affiche des milliards de triangles en construisant au moment de la compilation un DAG de clusters, c’est-à-dire un graphe orienté acyclique, puis en sélectionnant à l’exécution le bon LOD pour chaque cluster selon l’erreur en espace écran. L’ensemble du pipeline s’exécute sur le GPU. Cette approche a été portée vers WebGPU.

Nanite WebGPU

Nanite WebGPU effectuant dans un navigateur le rendu d’une scène complexe composée de plusieurs objets à l’aide d’une hiérarchie de LOD par meshlets et d’un rastériseur logiciel
Nanite WebGPU effectuant le rendu d’une scène complète dans Chrome à l’aide de LOD par meshlets, d’une rastérisation logicielle dans des shaders de calcul WGSL et d’un culling du frustum et des occlusions par meshlet. Aucun plugin natif : uniquement WebGPU.

Nanite WebGPU de Scthe, qui compte plus de 1 100 étoiles sur GitHub, est une implémentation complète dans le navigateur de l’architecture fondamentale de Nanite :

  • Une hiérarchie de LOD par meshlets construite hors ligne à l’aide de la génération de clusters de meshoptimizer
  • Un rastériseur logiciel implémenté dans des shaders de calcul WGSL, qui tient compte des contraintes de WebGPU lorsque la rastérisation matérielle ne peut pas exécuter efficacement des appels de rendu par cluster
  • Un culling par instance et par meshlet fondé sur des tests de frustum et d’occlusion
  • Des imposteurs de type billboard pour les objets extrêmement éloignés
  • La prise en charge des textures et des normales par sommet Le pipeline fonctionne ainsi : les maillages sont divisés en clusters d’environ 128 triangles. Les clusters voisins sont regroupés, puis chaque groupe est simplifié (à l’aide de meshoptimizer) tout en préservant les frontières communes. Ce processus se répète récursivement jusqu’à ce que le maillage entier soit réduit à un seul cluster. À l’exécution, un shader de calcul parcourt le DAG et sélectionne, pour chaque groupe, le cluster le moins détaillé produisant une erreur inférieure à 1 pixel à la résolution d’écran actuelle.

THREE-Nanite est une implémentation Three.js émergente qui atteint 20 à 40 FPS sur du matériel graphique intégré tout en gérant des centaines de milliers de triangles. Elle démontre qu’un rendu de type Nanite est viable même sur du matériel peu puissant dans un navigateur.

meshoptimizer : la fondation du pipeline de LOD

meshoptimizer (par Arseny Kapoulkine) est la bibliothèque à la base de la plupart des pipelines de LOD compatibles avec les navigateurs. La version 1.0 (2025) fournit :

  • Simplification de maillage avec métriques d’erreur (mesurant à quel point la forme a changé, afin de sélectionner le LOD)
  • Génération de clusters pour les hiérarchies de meshlets de type Nanite
  • Optimisation du cache de sommets pour un ordonnancement des triangles adapté au GPU
  • Optimisation du surdessin afin de réduire le coût des shaders de pixels
  • Quantification et compression des sommets pour réduire la taille des téléchargements

meshoptimizer 1.0 (publié en décembre 2025) inclut un nouveau fichier d’en-tête unique, clusterlod.h, qui implémente directement un LOD continu de type Nanite. Il construit une hiérarchie de clusters progressivement regroupés et simplifiés, utilisable telle quelle ou comme référence pour un pipeline personnalisé. Il s’agit exactement de la primitive de DAG de clusters dont le pipeline de terrain a besoin pour gérer le LOD des maillages issus de SDF et de marching cubes.

Pour notre pipeline de terrain, meshoptimizer traite la sortie de marching cubes du terrain SDF afin de produire des maillages optimisés et organisés en clusters avec des hiérarchies de LOD. Le traitement hors ligne s’exécute côté serveur. Le navigateur reçoit des maillages préregroupés en clusters et effectue à l’exécution une sélection du LOD pilotée par le GPU.

L’association de meshoptimizer pour générer les LOD et du calcul WebGPU pour les sélectionner à l’exécution donne au terrain dans le navigateur le même modèle architectural que Nanite, adapté aux contraintes du Web.

Conception de niveaux guidée par le terrain

Le terrain n’est pas seulement une surface sur laquelle marcher. Sa forme guide les déplacements des joueurs, oriente leur attention et crée le rythme émotionnel de l’exploration. Les meilleurs mondes ouverts utilisent le terrain comme outil de conception.

Lignes de vue et points de repère

Le chapitre sur l’orientation du Level Design Book explique comment l’altitude du terrain contrôle ce que les joueurs voient et où ils vont. Une crête cache ce qui se trouve derrière elle et suscite la curiosité. Une vallée canalise les déplacements vers son point le plus bas. Un point de repère élevé (une tour, un sommet montagneux ou un arbre inhabituel), visible de loin, donne aux joueurs un objectif vers lequel marcher.

Pour un monde créé par les utilisateurs, cela signifie que la génération du terrain doit produire des éléments d’orientation naturels. Les lignes de crête doivent interrompre les lignes de vue et créer des « moments de révélation » lorsqu’un joueur atteint le sommet d’une colline et découvre une nouvelle zone. Les vallées doivent converger vers des lieux intéressants. Des points élevés doivent être disponibles pour permettre aux créateurs d’y placer des repères visibles de loin.

Exploration guidée par la curiosité

Une étude de l’université Purdue (article) identifie quatre déclencheurs de l’exploration spatiale :

  1. Atteindre des points extrêmes (le plus haut sommet, la limite la plus éloignée, la grotte la plus profonde). Le terrain doit comporter des extrêmes clairement identifiables qui récompensent les joueurs lorsqu’ils les atteignent.
  2. Découvrir ce que cachent les obstacles visuels (qu’y a-t-il derrière cette falaise ? à l’intérieur de cette grotte ?). Un terrain qui bloque la vue incite à se déplacer pour découvrir ce qui est caché.
  3. Repérer des objets incongrus (une structure en pleine nature, une lumière dans l’obscurité). Les objets placés par les créateurs sur un terrain naturel créent un contraste qui attire l’attention.
  4. Comprendre les connexions spatiales (comment cette vallée rejoint-elle cette côte ?). Un terrain qui crée une géographie lisible encourage la lecture de carte et la planification d’itinéraires.

PlotMap : placement de points d’intérêt assisté par l’IA

PlotMap (arXiv:2309.15242) automatise la disposition des points d’intérêt en prenant des contraintes narratives (cette quête nécessite un village près d’une rivière, cette autre quête nécessite des ruines au sommet d’une colline) et en recherchant des emplacements qui satisfont ces contraintes spatiales. Pour un monde créé par les utilisateurs, un système similaire pourrait suggérer où placer des structures selon les propriétés du terrain : « ce sommet offre de bonnes lignes de vue pour une tour de guet », « cette vallée abritée conviendrait à un village ».

Eau courante et cascades

Les rivières et les cascades sont des éléments du terrain qui combinent attrait visuel, ambiance sonore et possibilités de gameplay (l’eau comme obstacle, ressource ou voie de déplacement).

Rendu des rivières

Dans les mondes ouverts, les rivières sont généralement rendues sous la forme de bandes texturées qui suivent la surface du terrain. Le maillage de la bande est généré à partir de la spline de la rivière (stockée sous forme de points de contrôle), puis projeté sur la carte de hauteur du terrain. Le shader de la rivière applique :

  • Des UV alignées sur le courant qui défilent dans le sens de la rivière pour créer l’apparence d’une eau en mouvement
  • De l’écume sur les bords, là où la rivière rencontre la berge (en fonction de la profondeur, comme l’écume du littoral)
  • Une variation de vitesse selon la largeur du chenal (les sections étroites s’écoulent plus vite, les sections larges plus lentement)
  • Une transparence avec une couleur dépendant de la profondeur (l’eau peu profonde est claire, l’eau profonde est sombre)

Pour un monde dans le navigateur, les données d’une rivière sont compactes : une spline (20 à 50 points de contrôle par segment de rivière, environ 400 octets), plus des paramètres de largeur et de vitesse d’écoulement. Le client génère localement le maillage de la rivière en projetant la spline sur la surface de son terrain.

Rendu des cascades

Lorsqu’une rivière tombe d’une falaise, un système de particules de cascade remplace la surface plane de la rivière. L’approche hybride issue de la recherche sur la simulation de l’eau en temps réel (EG) convertit les régions qui ne peuvent pas être représentées par un champ de hauteur (cascades, éclaboussures) en particules d’embruns, d’éclaboussures et d’écume qui échangent masse et quantité de mouvement avec la simulation du fluide.

Pour un monde dans le navigateur, les cascades sont plus simples : détecter l’endroit où la spline de la rivière traverse une discontinuité de hauteur du terrain, générer à cet endroit un système de particules doté d’une vitesse descendante, puis ajouter une gerbe d’écume à la base. Les particules sont des quadrilatères instanciés par le GPU avec des textures alpha défilantes. 500 particules par cascade, en un seul appel de rendu. Le bruit de l’eau qui tombe utilise l’API Web Audio avec une atténuation en fonction de la distance.

Imposteurs pour les éléments de terrain éloignés

Les arbres, rochers, bâtiments et autres éléments du terrain deviennent minuscules à distance. Les afficher sous forme de maillages 3D complets gaspille des cycles GPU. Les imposteurs remplacent les objets éloignés par des images planes prérendues orientées vers la caméra.

Atlas d’imposteurs octaédriques

Un imposteur octaédrique capture l’apparence d’un objet 3D sous plusieurs angles de vue et les stocke dans un atlas de textures. À l’exécution, le shader échantillonne l’atlas en fonction de la direction de vue actuelle et interpole entre les deux angles capturés les plus proches.

Un atlas hémi-octaédrique (avec uniquement des vues depuis l’hémisphère supérieur, puisqu’on regarde rarement les arbres par-dessous) offre une résolution angulaire deux fois supérieure à celle d’un atlas octaédrique complet de même taille. Le système d’imposteurs de Unity indique que le temps de calcul d’une image passe de 111 ms à 5,78 ms lorsque 1 600 instances d’arbres sont remplacées par des imposteurs au lieu d’utiliser leurs véritables maillages (140 000 triangles chacun).

Pour un monde dans le navigateur, le pipeline d’imposteurs fonctionne ainsi :

  1. Côté serveur : afficher chaque ressource sous 16 à 32 angles de vue en capturant la couleur, les normales et la profondeur
  2. Regrouper ces captures dans un atlas de textures (un atlas par ressource, environ 256 × 256 pixels, moins de 100 Ko au format KTX2)
  3. À l’exécution : afficher les instances situées au-delà de la distance d’imposteur (généralement 100 à 200 m) sous forme de panneaux échantillonnant l’atlas
  4. Effectuer un fondu enchaîné entre le maillage et l’imposteur sur une zone de transition de 20 m afin de masquer le changement

Projection de panneaux (BBSplat)

Billboard Splatting (2024, arXiv:2411.08508) va plus loin en utilisant des primitives planes texturées pouvant être apprises. Au lieu d’employer des vues prérendues, BBSplat optimise la position et les textures des panneaux afin de représenter au mieux l’objet 3D sous n’importe quel angle. Cette méthode permet une compression jusqu’à 17 fois supérieure à celle du 3D Gaussian Splatting tout en conservant une apparence dépendante du point de vue. Pour les éléments de terrain éloignés dans un monde exécuté dans le navigateur, BBSplat pourrait réduire l’espace de stockage des imposteurs par ressource tout en améliorant la couverture angulaire.

Outils de terrain professionnels et enseignements à en tirer

Avant de créer un pipeline de terrain à partir de zéro, il est utile de comprendre le fonctionnement des outils professionnels hors ligne. Ces outils représentent des décennies de recherche sur la génération de terrains, condensées en workflows de production.

Gaea (QuadSpinner) est accéléré par le GPU et fournit un retour presque instantané sur les modifications. Il prend en charge des générations en tuiles allant jusqu’à 2 millions de pixels de côté, l’export automatique de maillages avec LOD et un graphe à base de nœuds dans lequel chaque nœud représente un processus physique (érosion, sédimentation, soulèvement, altération thermique). Les nœuds d’érosion de Gaea produisent des terrains qui semblent sculptés à la main parce qu’ils modélisent des processus physiques précis plutôt qu’un bruit générique. L’idée essentielle : Gaea n’utilise pas un algorithme d’érosion unique. Il propose des nœuds distincts pour l’érosion fluviale (creusement par les rivières), l’érosion thermique (effritement des falaises), l’érosion côtière (action des vagues) et l’érosion éolienne (formation de dunes de sable). Leur combinaison dans un graphe produit un terrain possédant le caractère géologique d’un climat donné.

World Machine adopte une approche similaire par graphe, en mettant l’accent sur la macrostructure du terrain. Son « générateur de disposition » permet aux artistes d’esquisser la forme générale des éléments du terrain (une montagne ici, une vallée là, un littoral le long de ce bord), puis le système ajoute des détails physiquement plausibles. C’est exactement le workflow que nous souhaitons pour les créateurs : esquisser une intention et obtenir une géologie.

World Creator se distingue par son aperçu en temps réel pendant l’édition et par son système intégré de génération de rivières, qui analyse le terrain et calcule automatiquement les trajectoires d’écoulement à partir d’une analyse du drainage.

Ce que nous retenons de ces outils : l’approche par graphe de nœuds, qui combine des processus physiques, est plus puissante que n’importe quel algorithme isolé. Notre pipeline de génération côté serveur doit permettre d’enchaîner les étapes : bruit de base > soulèvement tectonique > érosion hydraulique > altération thermique > érosion côtière > végétation. Les créateurs contrôlent les paramètres à chaque étape. Le pipeline s’exécute côté serveur en quelques secondes et produit des cartes de hauteur, des splat maps et des cartes de densité de végétation.

SoilMachine : géomorphologie open source

SoilMachine : simulateur modulaire open source de géomorphologie montrant un terrain soumis à des érosions hydraulique, thermique et éolienne couplées
SoilMachine associe les érosions hydraulique, thermique et éolienne dans un modèle de terrain stratifié unique. La structure de données multicouche prend en charge des éléments que les cartes de hauteur ne peuvent pas représenter : grottes, surplombs, buttes et répartition des eaux souterraines.

SoilMachine est un simulateur modulaire open source de géomorphologie qui associe plusieurs systèmes d’érosion (hydraulique, thermique et éolienne) au transport et au dépôt de sédiments. Développé en C++ avec du calcul GPU, il fournit une implémentation de référence de l’approche d’érosion multiprocessus utilisée par les outils professionnels.

La bibliothèque associée soillib (C++20, licence MIT) fournit les primitives sous-jacentes de simulation géomorphologique sous forme de bibliothèque réutilisable. Quant à hydro-gen, il implémente à la fois une érosion hydraulique basée sur une grille (eaux peu profondes) et une autre basée sur des particules (gouttes de pluie), au moyen de shaders de calcul OpenGL dont les paramètres peuvent être ajustés en temps réel.

Ces outils open source pourraient être adaptés à notre pipeline de génération côté serveur. Les implémentations en shaders de calcul peuvent être transposées directement vers WebGPU si nous souhaitons un jour exécuter l’érosion dans le navigateur afin d’offrir aux créateurs un retour en temps réel.

Matériaux de terrain multicouches

Un terrain réel n’est pas une surface unique. Il est constitué de couches : roche mère au fond, terre au-dessus, puis neige ou sable s’accumulant sur les surfaces. La superposition dynamique modifie le caractère visuel du terrain selon les saisons, la météo et les actions des créateurs.

Représentation par champs de hauteur stratifiés

Au lieu d’une carte de hauteur unique, utilisez plusieurs couches de hauteur par cellule de grille :

Cell {
  bedrock_height: f16,    // surface rocheuse permanente
  soil_height: f16,       // terre/sédiments accumulés au-dessus de la roche mère
  snow_height: f16,       // accumulation dynamique de neige
  water_height: f16       // profondeur de l’eau stagnante
}

Total : 8 octets par cellule (contre 2 octets pour une carte de hauteur unique). Pour un chunk de 65 × 65, cela représente 34 Ko avant compression. Cela reste compact.

La surface visuelle correspond à bedrock + soil + snow. Le shader du terrain lit toutes les couches et mélange les matériaux en conséquence : là où la couche de terre est mince, la roche affleure. Là où la neige s’est accumulée, la surface est blanche. Là où l’eau stagne, des flaques ou des lacs apparaissent.

Accumulation dynamique

Lorsqu’il neige, la neige s’accumule sur les surfaces planes orientées vers le haut. Le taux d’accumulation dépend de la normale de la surface (les pentes raides ne retiennent pas la neige), de la température (qui dépend de l’altitude) et de la présence d’un abri (les zones situées sous des surplombs restent dégagées). Une passe de shader de calcul met à jour la couche de neige à chaque cycle météorologique, toutes les quelques secondes.

L’accumulation de sable fonctionne de façon similaire, avec un dépôt entraîné par le vent. Le vent emporte les particules depuis les surfaces exposées et les dépose derrière les obstacles et dans les zones abritées.

Pour un monde créé par les utilisateurs, l’accumulation dynamique signifie que le terrain change d’apparence selon la météo. La neige recouvre le monde pendant une tempête, puis fond lorsque le ciel se dégage. La pluie remplit les dépressions d’eau. Le monde paraît ainsi réactif sans que les créateurs aient à intervenir.

Érosion multicouche

L’article de 2024 « 3D Real-Time Hydraulic Erosion Simulation using Multi-Layered Heightmaps » (EG) étend l’érosion afin qu’elle agisse sur plusieurs couches. L’eau érode la terre plus rapidement que la roche mère. Les sédiments se déposent sous forme d’une nouvelle couche de terre. La simulation préserve l’intégrité des couches (la roche mère reste sous la terre) tout en permettant des structures complexes comme les surplombs, lorsque la roche mère surplombe la terre érodée en dessous. Performances : environ 6 ms par étape de simulation sur une RTX 3070 à une résolution de 2048x2048. C’est suffisamment rapide pour une génération côté serveur, mais trop lent pour une simulation à chaque image dans le navigateur. La représentation en couches convient à la génération de terrains statiques, tandis que l’accumulation dynamique de neige et d’eau s’exécute dans un shader par image moins coûteux.

Rendu de l’herbe, des rochers et des détails

Le paysage ne se résume pas à la géométrie et aux textures du terrain. Il lui faut des brins d’herbe qui ondulent au vent, des rochers dispersés sur les pentes et de petits détails comme des fleurs, des cailloux et des branches tombées pour rendre les vues rapprochées naturelles.

Herbe instanciée sur le GPU

Un million de brins d’herbe rendus par instanciation GPU en un seul appel de rendu. La même technique fonctionne dans Three.js et WebGPU : transformations par instance, animation du vent dans le shader de sommets et carte de densité pour répartir les brins à partir des données du terrain.

Le rendu de l’herbe dans le navigateur est une technique éprouvée avec Three.js et repose sur l’instanciation GPU. L’approche de la démo d’herbe d’al-ro rend 100 000 brins d’herbe en un seul appel de rendu avec InstancedBufferGeometry.

Chaque brin d’herbe est un simple quadrilatère (4 à 8 triangles). Des attributs par instance définissent sa position, sa hauteur, la direction de sa courbure, ses variations de couleur et sa phase d’animation dans le vent. Le shader de sommets :

  1. Lit la transformation propre à l’instance
  2. Applique une animation du vent à l’aide d’ondes sinusoïdales déterminées par la position dans le monde et le temps
  3. Courbe le brin en fonction de la force du vent (courbure plus forte à la pointe, nulle à la base)
  4. Applique un dégradé de couleur (plus sombre à la base et plus clair à la pointe pour simuler la diffusion sous la surface)

Le tutoriel de Codrops sur l’herbe duveteuse (2025, Tutoriel) présente une approche de texturation par couches : le plan du sol est rendu plusieurs fois avec des décalages croissants, chaque couche échantillonnant une texture de bruit pour créer l’apparence d’un volume d’herbe dense. Cette méthode est moins coûteuse que l’instanciation de brins individuels pour une couverture très dense, mais moins réaliste de près.

Dans un monde créé par les utilisateurs, la densité de l’herbe provient de la carte de densité de la végétation de chaque chunk. Le GPU répartit les positions des brins à partir de cette carte au moment du rendu. Aucune donnée propre à chaque brin n’est stockée ni transmise. La carte de densité est une grille de 32x32 par chunk (1 Ko), à partir de laquelle le GPU génère des milliers d’instances de brins.

Détails procéduraux des rochers et des falaises

Les parois des falaises et les terrains rocheux ont besoin de détails géométriques que la carte de hauteurs ou le SDF de base ne peuvent pas fournir à une résolution raisonnable. Deux approches se complètent :

Resurfaçage par mesh shader sur le GPU (Raad et al., Eurographics 2025, Article) génère une géométrie procédurale au moment du rendu à partir d’un maillage de contrôle grossier. Le mesh shader lit une surface de terrain de base et ajoute du déplacement, des fissures et des protubérances sans stocker la géométrie détaillée en mémoire. Cela réduit l’utilisation de la VRAM et permet un LOD dynamique.

La répartition de rochers instanciés place des maillages de rochers préfabriqués sur les pentes raides et au bord des falaises au moyen de l’instanciation GPU. Un shader de calcul lit la normale et la pente du terrain, puis répartit les instances de rochers là où la pente dépasse un certain seuil. Chaque instance est un petit maillage (200 à 500 triangles) doté d’une rotation et d’une échelle aléatoires. Grâce à l’instanciation, 10 000 rochers dispersés n’ajoutent qu’un coût de rendu négligeable.

Routes et chemins

Les routes, sentiers et chemins placés par les créateurs doivent épouser le terrain et modifier le matériau de sa surface en remplaçant l’herbe par de la terre ou de la pierre.

L’approche employée par tous les principaux moteurs de jeu consiste à définir le chemin comme une spline, c’est-à-dire une série de points de contrôle. La spline est projetée sur la surface du terrain. Un maillage en bande qui suit la spline et se situe légèrement au-dessus du terrain est ensuite généré. Une texture de route est appliquée à cette bande. Dans le shader du terrain, le matériau du terrain est progressivement mélangé au matériau de la route sur la largeur de la spline à l’aide d’une texture projetée ou d’un décalque.

Dans un monde accessible par navigateur, un créateur dessine un chemin sur le terrain. Le client génère les points de contrôle et les envoie au serveur, soit quelques dizaines de valeurs vec3. Le serveur stocke la spline. Tous les clients rendent localement la bande de la route en projetant la spline sur leur maillage de terrain. Les données de la route sont minuscules — les points de sa spline, soit environ 200 octets — mais son impact visuel est considérable : des chemins reliant les créations donnent l’impression que le monde est habité.

Ombres du terrain

Les ombres du terrain sont essentielles à sa lisibilité — pour comprendre sa forme — et à son atmosphère — pour évoquer un moment de la journée. Dans un monde ouvert, le soleil projette des ombres sur l’ensemble du terrain visible.

Cartes d’ombres en cascades (CSM)

Les CSM divisent le frustum de vue en 3 à 4 plages de distance, ou cascades. Chaque cascade produit une carte d’ombres depuis le point de vue du soleil, à une résolution adaptée à sa distance. Cascade proche : haute résolution pour les ombres détaillées sous les arbres et les bâtiments. Cascade lointaine : basse résolution pour les grandes ombres des montagnes.

Three.js et Babylon.js prennent tous deux en charge les CSM. L’optimisation essentielle pour le terrain consiste à ne rendre que celui-ci dans la carte d’ombres, et non chaque brin d’herbe ou petit détail. L’herbe reçoit ses ombres depuis la carte d’ombres du terrain plutôt que de calculer ses propres ombres.

Budget de performances : 3 à 4 cascades d’ombres de 1024x1024 chacune. Le rendu du terrain dans les cartes d’ombres coûte 0,5 à 1 ms, car sa géométrie se trouve déjà dans la mémoire du GPU. L’échantillonnage de 4 cascades dans le shader du terrain ajoute 0,2 à 0,3 ms.

Auto-ombrage du terrain à partir de la carte de hauteurs

Pour les très grands terrains où les CSM deviennent coûteuses, il est possible de précalculer une carte d’horizon : pour chaque cellule du terrain, elle stocke l’angle d’élévation maximal dans 8 directions cardinales et intercardinales. Au moment du rendu, l’angle du soleil est comparé à la carte d’horizon pour déterminer si un point se trouve dans l’ombre. C’est ainsi que Skyrim gère l’auto-ombrage du terrain lointain, au-delà de la portée des CSM.

La carte d’horizon est calculée côté serveur à partir de la carte de hauteurs, en quelques secondes de traitement, puis transmise sous forme de texture de 128x128 par chunk, soit 16 Ko compressés. L’impact visuel est important : les vallées montagneuses s’assombrissent de manière réaliste, même à des distances d’affichage extrêmes.

Compression des données de terrain pour la diffusion

Le réseau est le goulot d’étranglement d’un monde accessible par navigateur. Chaque octet économisé dans les données du terrain réduit le temps de chargement.

Compression des cartes de hauteurs

Les cartes de hauteurs brutes sur 16 bits se compressent bien, car les cellules adjacentes présentent des valeurs similaires. Le pipeline est le suivant :

  1. Encodage différentiel : stocker la différence entre chaque cellule et sa valeur prédite, obtenue par la moyenne de ses voisines. Les valeurs différentielles sont petites et se concentrent près de zéro.
  2. Quantification : pour les chunks éloignés, réduire la précision de 16 bits à 12 ou 8 bits. À 500 mètres de distance, une précision de hauteur sur 8 bits — résolution de 0,4 m sur une plage d’altitudes de 100 m — est impossible à distinguer d’une précision sur 16 bits.
  3. Codage entropique : appliquer une compression zlib ou brotli au flux encodé par différences. Taux de compression habituel : 4 à 8x.

Résultat : un chunk de 65x65 sur 16 bits passe de 8,4 Ko de données brutes à 1 ou 2 Ko compressés. Avec une précision réduite à 8 bits : 0,5 à 1 Ko.

Diffusion progressive des cartes de hauteurs

Le terrain est d’abord envoyé en basse résolution, puis progressivement affiné. Une carte de hauteurs de 17x17 — le minimum pour un chunk de 64 m avec un espacement de 4 m entre les cellules — représente 578 octets bruts et moins de 200 octets compressés. Le terrain apparaît instantanément. L’affinement en 33x33 est ensuite transmis, en ajoutant les échantillons des lignes et colonnes impaires, puis vient la résolution complète de 65x65. Chaque niveau ajoute des détails sans remplacer les données précédentes.

Cela correspond aux anneaux de LOD de la geometry clipmap : le terrain lointain utilise la version en basse résolution (17x17), la moyenne distance utilise la version intermédiaire (33x33) et les vues rapprochées utilisent la résolution complète (65x65). La priorité de diffusion suit le LOD de rendu.

Compression des volumes SDF

Les volumes SDF clairsemés se compressent fortement, car la plupart des voxels sont éloignés de la surface et représentent donc un espace vide. Plusieurs options existent :

Codage par plages : encode les suites de valeurs identiques, comme les voxels vides. Les volumes SDF courants sont vides à plus de 95 %, si bien que le RLE atteint un taux de compression de 10 à 50x.

Octree clairsemé : ne stocke que les nœuds de l’octree qui contiennent des voxels traversés par la surface. L’espace vide ne comporte aucun nœud. Un volume SDF de 64^3 contenant un seul tunnel de grotte peut ne comporter que 2 000 à 5 000 nœuds occupés, contre 262 144 voxels au total, chacun étant stocké sur 1 à 2 octets.

Compression progressive guidée par l’entropie (2024, HAL) s’applique aux données spatiales 3D en partitionnant récursivement l’espace au moyen de plans optimisés selon l’entropie et d’une quantification adaptative. Elle produit un flux d’affinements optimisé pour les compromis entre débit et distorsion, particulièrement avantageux aux faibles débits de la diffusion sur réseau.

Assemblage de l’ensemble : le pipeline de terrain pour navigateur

La vue d’ensemble stratégique présentée au début de cet article fournit un cadre de décision rapide et un plan de développement par phases. Cette section détaille entièrement le pipeline de génération côté serveur et le pipeline de rendu dans le navigateur.

Pipeline de génération côté serveur

Le pipeline de génération s’exécute sous la forme d’un graphe orienté de processus physiques, inspiré de l’approche par graphe de nœuds de Gaea et World Machine. Chaque étape reçoit la sortie de l’étape précédente et l’affine. Les créateurs contrôlent les paramètres de chaque étape.

ÉtapeEntréeProcessusSortieDurée
1. Terrain de baseGraine ou requête textuelleTerrain Diffusion / MESA / bruit + fBmCarte de hauteurs sur 16 bits1-5 s
2. ÉrosionCarte de hauteursPuissance analytique des cours d’eau + érosion thermiqueCarte de hauteurs érodée, carte d’accumulation des écoulements, carte des sédiments0,5-2 s
3. RivièresCarte de hauteurs érodée, carte des écoulementsExtraction du réseau hydrographique, creusement des chenauxSplines des rivières, carte du niveau de l’eau0,5 s
4. LittoralCarte de hauteurs près du niveau de la merÉrosion par les vagues de type NEWTSÉléments du littoral (falaises, plages, stacks)1-3 s
5. VolumétrieCarte de hauteurs + intention du créateurÉrosion Arenite / génération de grottes / sculpture SDFVolumes SDF clairsemés pour les chunks concernés1-60 s
6. MatériauxCarte de hauteurs + cartes d’érosionTerraFusion / Geodiffussr / règles procéduralesSplat maps, textures du terrain1-5 s
7. VégétationCarte de hauteurs + carte des écoulements + matériauxSimulation de la concurrence entre écosystèmesCartes de densité par biome et par chunk1-3 s
8. Cartes d’horizonCarte de hauteurs finaleAngle d’élévation maximal dans 8 directionsTexture d’auto-ombrage par chunk2-5 s
9. Découpage en chunksToutes les sortiesDécoupage, encodage différentiel, compression, hachagePaquets de chunks sur le CDN5-10 s
Total15-90 s

Un nouveau monde de 4x4 km est généré en 15 à 90 secondes. Les modifications des créateurs — sculpture ou changements de paramètres — ne relancent que les étapes et les chunks concernés, généralement en moins de 5 secondes.

Pipeline de rendu dans le navigateur

ÉtapeParcours WebGPUSolution de repli WebGL 2Budget par image
1. DiffusionFile de priorité, préchargement prédictifIdentiqueN/A (asynchrone)
2. Terrain par carte de hauteursQuadtree CDLOD piloté par le GPU, culling par calcul, rendu indirectGeometry clipmaps, mise à jour des anneaux par le CPU0,5-1 ms
3. Maillage volumétriqueMarching cubes par calcul + TransvoxelMaillages prégénérés dans un Web Worker, 2 à 3 LOD en cache0,5-2 ms
4. Transitions de LODGeomorphing dans le shader de sommetsIdentiqueInclus ci-dessus
5. MatériauxPBR triplanaire + mélange laplacien + détails par bruit de phaseurs + texturation virtuellePBR triplanaire + mélange linéaire + splat maps précalculées1-1,5 ms
6. VégétationComputeInstanceCulling + IndirectBatchedMesh, couverture végétale au sol pavée en hexagonesCulling du frustum par le CPU + InstancedMesh1-1,5 ms
7. EauBandes de rivière alignées sur l’écoulement, écume du rivage fondée sur la profondeurIdentique (réflexions simplifiées)0,5 ms
8. OmbresCSM à 3 ou 4 cascades + auto-ombrage par carte d’horizonCSM à 2 cascades0,5-1 ms
9. AtmosphèreModèle de ciel de Hillaire + brouillard volumétrique + particules météorologiquesCiel de Preetham + brouillard de distance0,5 ms
10. Effets dynamiquesAccumulation des flaques, déformation par les empreintes, neige/pluieAccumulation des flaques, particules de pluie0,3 ms
Total du terrain3,5-6,5 ms

À 60 ips — 16,6 ms par image — le système de terrain utilise 21 % du budget d’une image avec WebGPU et 39 % avec WebGL 2. Le reste est disponible pour les avatars des joueurs, les objets des créateurs, l’interface, le réseau et le post-traitement.

Pourquoi cela fonctionne dans un navigateur

L’ensemble du pipeline est conçu autour de trois contraintes propres aux navigateurs :

Mémoire (2 à 4 Go maximum) : le budget de 256 Mo consacré au terrain est respecté, car les chunks de carte de hauteurs ne pèsent que 2 à 8 Ko chacun après encodage différentiel, les volumes SDF sont clairsemés — 100 à 500 Ko par chunk volumétrique —, la végétation est générée à l’exécution à partir de cartes de densité de 1 Ko et les textures utilisent la compression KTX2 — 150 Ko par texture de 1024x1024. À tout moment, le monde visible dans le navigateur pèse au total entre 50 et 200 Mo.

Aucun accès au disque : tout est diffusé sur le réseau. Le chargement progressif permet au joueur de voir le terrain en moins de 100 ms grâce à une carte de hauteurs en basse résolution, le terrain texturé en moins de 300 ms et tous les détails en moins de 3 s. Le préchargement fondé sur la vitesse masque les temps de chargement pendant l’exploration normale.

Les performances des GPU varient énormément : le parcours WebGPU prend en charge les ordinateurs haut de gamme. La solution de repli WebGL 2 couvre tous les autres appareils, y compris les mobiles. Les mêmes données de chunks alimentent les deux parcours. Seule la technique de rendu diffère, pas le format des données. Un Chromebook exécutant WebGL 2 affiche le même monde qu’une RTX 4090 exécutant WebGPU, simplement avec moins de détails et une distance d’affichage plus courte.

Articles de recherche

Représentation du terrain et génération de maillages

« Marching Cubes: A High Resolution 3D Surface Construction Algorithm » — Lorensen et Cline (SIGGRAPH 1987). DOI. L’algorithme fondateur pour extraire des maillages triangulaires à partir de données volumétriques. Trente-huit ans plus tard, il reste la méthode d’extraction d’isosurfaces la plus utilisée. Ses implémentations parallèles sur GPU s’exécutent en temps réel dans les shaders de calcul WebGPU. « Dual Contouring of Hermite Data » -- Ju, Losasso, Schaefer, Warren (SIGGRAPH 2002). DOI. Produit des maillages qui préservent les arêtes vives (bords de falaises, angles rocheux) que l’algorithme des marching cubes tend à arrondir. Nécessite les normales de surface en plus des valeurs de distance.

« Neural Dual Contouring » -- Chen et al. (2022). arXiv:2202.01999. Remplace le placement des sommets par moindres carrés du dual contouring par un prédicteur entraîné. Offre une meilleure qualité de surface pour les formes naturelles complexes.

« The Transvoxel Algorithm » -- Lengyel (2009, mis à jour en 2024). transvoxel.org. Transitions de niveau de détail fluides pour les terrains voxelisés. Élimine les fissures aux limites de résolution grâce à 73 types de cellules de transition. Sans brevet et conçu pour les applications en temps réel.

Niveau de détail et rendu des terrains

« Geometry Clipmaps: Terrain Rendering Using Nested Regular Grids » -- Losasso et Hoppe (SIGGRAPH 2004). Article. Rendu de terrain à coût constant avec des anneaux concentriques de niveaux de détail. Gère des terrains de 40 Go à des fréquences interactives. Constitue la base de la plupart des moteurs de rendu de terrain dans le navigateur.

« CDLOD: Hybrid LOD for Terrain Rendering » -- Strugar (2014). Article. Amélioration adaptative par quadtree des geometry clipmaps. Alloue la résolution selon la complexité du terrain plutôt que selon la seule distance.

« GPU-Driven Rendering Pipelines » -- Ubisoft (SIGGRAPH 2015), Wihlidal et Hoppe. A formalisé l’approche pilotée par le GPU, dans laquelle les compute shaders gèrent l’élimination des éléments invisibles, la sélection des niveaux de détail et la génération des appels de rendu. Le modèle architectural de notre pipeline de terrain WebGPU.

Génération physique de terrains

« Physically-Based Analytical Erosion for Fast Terrain Generation » -- Cordonnier et al. (2024). HAL. Érosion analytique fondée sur la loi de puissance de l’écoulement, évitant les simulations itératives. Génère des terrains physiquement plausibles en quelques millisecondes.

« Fast Hydraulic Erosion Simulation and Visualization on GPU » -- Mei, Decaudin, Hu (2007). HAL. Érosion hydraulique parallélisée sur GPU à l’aide d’une simulation en eaux peu profondes. Sert de base à la plupart des implémentations d’érosion dans les moteurs de jeu.

« Arenite: A Physics-Based Sandstone Simulator » -- SIGGRAPH 2025. Projet. Érosion multiphysique générant des arches, des cheminées de fée et des alcôves à partir de simulations de contraintes et d’érosion. S’exécute en moins de 5 minutes sur des GPU de bureau.

« Efficient Debris-flow Simulation for Steep Terrain Erosion » -- Purdue CGVLAB (2024). Article. Simulation accélérée par GPU des coulées de débris et de l’érosion des fortes pentes, produisant des reliefs montagneux réalistes.

« Flexible Terrain Erosion » -- IRIT-STORM (2024). Springer. Érosion fondée sur des particules, compatible avec les champs de hauteur, les grilles de voxels, les surfaces implicites et les matériaux stratifiés grâce à une interface unifiée. Permet d’utiliser un même système d’érosion pour des représentations hybrides du terrain.

Détails et texturation des terrains

« GPU-Friendly Laplacian Texture Blending » -- Wronski (NVIDIA, 2025). JCGT. Fusion en temps réel par pyramide laplacienne pour les matériaux de terrain, sans précalcul. Préserve les détails nets tout en éliminant les artefacts de raccord. Ne nécessite que quelques lectures de texture supplémentaires par fragment.

« Real-time Terrain Enhancement with Controlled Procedural Patterns » -- Grenier et al. (2024). CGF. Détails de micro-érosion fondés sur le bruit de phaseurs, jusqu’à 32 fois la résolution de la carte de hauteur. Les motifs alignés sur les pentes s’exécutent entièrement dans un fragment shader.

Tessellation adaptative

« Concurrent Binary Trees for Large-Scale Game Components » -- Benyoub et Dupuy (Intel, HPG 2024). Article. Structure de données en arbre binaire adaptée au GPU pour la tessellation adaptative des terrains. Affiche une géométrie à l’échelle planétaire en moins de 0,2 ms. Étendue des domaines carrés aux maillages polygonaux arbitraires.

Génération de grottes et de souterrains

« PLUME: Procedural Layer Underground Modeling Engine » -- 2024. arXiv:2508.20926. Framework open source destiné à générer des environnements réalistes de grottes et de tunnels de lave au moyen de règles procédurales superposées. Initialement conçu pour la robotique d’exploration spatiale.

Synthèse neuronale de terrains

« InfiniteDiffusion: Bridging Learned Fidelity and Procedural Utility for Open-World Terrain Generation » -- Goslin (2025, SIGGRAPH 2026). arXiv:2512.08309. Génération de terrains infinis et cohérents à partir d’une graine, à l’aide de modèles de diffusion hiérarchiques avec encodage laplacien. 9 fois plus rapide que la méthode de référence sur des GPU grand public.

« TerraFusion: Joint Generation of Terrain Geometry and Texture » -- 2025. arXiv:2505.04050. Diffusion latente pour la synthèse simultanée de cartes de hauteur et de textures, avec conditionnement par croquis.

« MESA: Text-Driven Terrain Generation » -- Atelier CVPR 2025. arXiv:2504.07210. Génération de terrains à partir de texte, entraînée sur les données de télédétection Copernicus.

« Geodiffussr: Generative Terrain Texturing with Elevation Fidelity » -- 2025. arXiv:2511.23029. Génération guidée par le texte de textures de terrain qui respectent les données d’altitude grâce au flow matching.

« Sketch2Terrain: AI-Driven Real-Time Terrain Sketch Mapping » -- 2025. Projet. Transformation en temps réel de croquis en terrains dans la réalité augmentée. Amélioration de l’efficacité de 38 % par rapport à la cartographie manuelle.

Simulation de la végétation et des écosystèmes

« GPU-Based Real-Time Procedural Distribution of Vegetation on Large-Scale Virtual Terrains » -- SBGames 2018. Article. Répartition de la végétation fondée sur un quadtree, utilisant des facteurs biotiques et abiotiques sur GPU.

« Procedural Generation and Rendering of Forests » -- 2022. Article. Génération d’arbres par systèmes de Lindenmayer combinée à une simulation de concurrence écosystémique afin d’obtenir une distribution réaliste des forêts.

« Real-Time Procedural Generation with GPU Work Graphs » -- AMD GPUOpen 2024. Article. Graphes de tâches GPU générant plus de 79 000 instances de végétation en moins de 4 ms.

Technologie GPU dans le navigateur

« GSWT Renderer » -- SIGGRAPH Asia 2025. GitHub. Moteur de rendu WebGPU + Rust/Wasm utilisant des tuiles de Wang par Gaussian Splatting pour créer des terrains 3D infinis avec niveau de détail dynamique et streaming.

« GPU Compute in the Browser at the Speed of Native: WebGPU Marching Cubes » -- Usher (2024). Blog. Démontre que le calcul WebGPU atteint des performances comparables au code natif pour les algorithmes parallèles de génération de maillages.

Rendu voxel et scènes à grande échelle

« Aokana: A GPU-Driven Voxel Rendering Framework for Open World Games » -- 2025. arXiv:2505.02017. DAG de voxels épars avec niveaux de détail et streaming pour des scènes contenant des dizaines de milliards de voxels. Réduit la mémoire utilisée d’un facteur 9 et accélère le rendu d’un facteur 4,8 par rapport aux meilleures méthodes antérieures. Conçu pour être intégré aux moteurs de jeu.

Géométrie procédurale et reconstruction de surfaces

« Real-time Procedural Resurfacing using GPU Mesh Shaders » -- Raad et al. (Eurographics 2025). Article. Génère au moment du rendu des surfaces géométriques détaillées à partir de maillages de contrôle grossiers, à l’aide de mesh shaders. Permet des niveaux de détail dynamiques sans stocker en mémoire une géométrie haute résolution.

Ombres des terrains

« Optimizing Terrain Shadows » -- AMD GPUOpen. Blog. Optimisation pratique des cascaded shadow maps pour les terrains à grande échelle. Aborde la répartition des cascades, le rendu des cartes d’ombres efficace sur GPU et les optimisations propres aux terrains.

Géométrie virtuelle et optimisation des maillages

« Nanite WebGPU » -- Scthe (2024). GitHub, Démo. Implémentation complète dans le navigateur de l’architecture Nanite d’UE5 : hiérarchie de niveaux de détail par meshlets, rastériseur logiciel en WGSL, élimination par meshlet et imposteurs en panneaux.

« Billions of Triangles in Minutes » -- Kapoulkine (2025). Blog. Meshoptimizer v1.0 pour la génération hiérarchique de niveaux de détail regroupés. Convertit efficacement des maillages massifs en DAG de groupes de style Nanite.

« Billboard Splatting (BBSplat) » -- 2024. arXiv:2411.08508. Primitives planes texturées et entraînables pour la synthèse de nouveaux points de vue, offrant une compression 17 fois supérieure à celle du Gaussian Splatting 3D.

Éclairage des terrains et illumination globale

« Global Illumination in Once Human » -- GDC 2025. Session. Illumination globale hybride pour un monde ouvert de 16 km : sondes compressées par réseau neuronal (rapport de 69:1), correction par apprentissage automatique des fuites entre intérieur et extérieur et réactions dynamiques des sondes.

« GI with AMD FidelityFX Brixelizer » -- GDC 2024. Article. Cascades de champs de distance épars calculées par compute shaders, avec sondes en espace écran. Aucun ray tracing matériel requis.

« Radiance Cascades » -- 2024. Blog. Illumination globale en temps réel sans bruit, utilisant des structures de radiance en cascade sans accumulation temporelle.

Conception de niveaux et exploration

« PlotMap: Automated Layout Design for Building Game Worlds » -- 2023. arXiv:2309.15242. Placement assisté par IA de points d’intérêt respectant les contraintes spatiales narratives du terrain.

« Spatial Exploration Triggers » -- Université Purdue (FDG 2022). Article. Quatre motifs de conception qui encouragent l’exploration par les joueurs : points extrêmes, obstacles visuels, objets incongrus et connexions spatiales.

Compression et streaming des données

« Entropy-driven Progressive Compression of 3D Point Clouds » -- SGP 2024. Article. Compression progressive optimisée selon le compromis débit-distorsion, utilisant un partitionnement récursif de l’espace avec quantification adaptative. Produit des flux de raffinement adaptés au streaming réseau à bande passante variable.

Édition interactive

« WebGPU SDF Editor » -- Nijhoff (2026). Projet. Outil complet de modélisation SDF dans le navigateur, avec marching cubes en temps réel, opérations booléennes, fusion lissée et partitionnement spatial par octree. 112 octets par primitive.

Génération de cours d’eau et de littoraux

« Procedural River Drainage Basins » -- Patel (Red Blob Games). Projet. Génération de cours d’eau donnant la priorité au drainage, fondée sur la classification des arêtes d’un maillage de Voronoï/triangles. Construit les hiérarchies fluviales avant d’attribuer l’altitude du terrain.

« NEWTS1.0: Numerical Model of Coastal Erosion by Waves and Transgressive Scarps » -- MIT (2024). Article. Modèle simplifié d’érosion côtière utilisant un recul uniforme et une érosion causée par les vagues. Génère des caps, des baies, des stacks marins et des arches conformes à la géomorphologie réelle.

Pour aller plus loin

Essayez tout de suiteIntégrez un paysage généré à un jeu

Un terrain est encore meilleur quand on peut l’explorer à pied.

Créer gratuitement →C'est gratuit, ça tourne dans votre navigateur, rien à installer.