Skip to content

Créer un monde ouvert dans le navigateur, partie 1 : nous avons commencé par essayer de le faire céder

Par Oleg Sidorkin, CTO et cofondateur de Cinevva

Vous découvrez la série ? Consultez le guide de la série. Il explique ce qu'est un prototype exploratoire et contient des liens vers toutes les parties.

Nous créons un monde ouvert multijoueur qui fonctionne entièrement dans le navigateur. Aucune installation, aucune boutique d'applications, juste une URL. Dès le départ, le principal risque était évident : un navigateur peut-il seulement afficher un monde 3D persistant à une fréquence d'images jouable, tout en conservant une marge suffisante pour le gameplay, la physique et le réseau ?

La plupart des projets de mondes ouverts échouent selon un ordre prévisible. On commence par avoir un bon concept. Puis une jolie scène. Et l'on finit par constater que tout le budget par image est déjà consommé avant même que le gameplay n'existe.

Nous voulions répondre à la question du budget de rendu avant d'investir dans quoi que ce soit d'autre. Le prototype exploratoire 1 a donc laissé de côté la jolie bande-annonce pour passer directement aux mesures.

Ouvrir le prototype exploratoire 1 dans un nouvel onglet ↗ · Voir le code source

La configuration était volontairement simple. Un maillage de terrain de 512 mètres, un relief procédural obtenu à partir de plusieurs couches de bruit sinusoïdal avec une atténuation vers les bords de l'île, un plan d'eau, un brouillard atmosphérique et 500 objets instanciés. Nous avons utilisé WebGL directement avec Three.js, le tone mapping ACES et aucune ombre.

L'apparence nous importait peu. Ce qui comptait, c'était que la scène reste stable lorsque la caméra s'y déplaçait.

Deux conclusions tirées de ce prototype exploratoire ont façonné l'ensemble du projet.

Premièrement, nous avons confirmé que nous disposions d'une véritable marge de performances sur ordinateur, à condition de rester rigoureux lors de la première passe. Cela nous a donné la confiance nécessaire pour nous attaquer ensuite à une architecture de terrain plus complexe.

Deuxièmement, nous avons établi un contrat de référence. Chaque prototype exploratoire suivant devait justifier son coût par rapport à cette scène. Si une nouvelle fonctionnalité était séduisante mais trop coûteuse, elle n'était pas retenue.

Cette rigueur autour de la référence est devenue cruciale par la suite, lorsque nous avons rencontré des artefacts aux raccords, des transitions entre différents niveaux de détail et une génération de maillage pilotée par des shaders de calcul. Sans référence stable, chaque bug paraît plus important qu'il ne l'est réellement.

Dans la partie 2, nous passons du rendu aux sensations de contrôle. La physique exécutée dans un worker paraît excellente dans les documents d'architecture. Mais cela n'a d'intérêt que si le personnage réagit toujours instantanément lorsque vous appuyez sur une touche.

Technologies mentionnées dans ce chapitre

Terrain à carte de hauteurs. Une grille 2D dans laquelle chaque cellule stocke une seule valeur d'altitude. Le GPU déplace un maillage plat dans le shader de sommets pour créer la surface du terrain. Les cartes de hauteurs sont compactes (une zone de 65x65 occupe environ 8 Ko en 16 bits), adaptées au GPU et rapides à afficher. Leur limite est qu'elles ne peuvent pas représenter les grottes, les surplombs ni aucune surface qui se replie sur elle-même. Pour en savoir plus sur les limites des cartes de hauteurs et les solutions qui leur succèdent, consultez notre guide de génération de paysages.

Three.js. La bibliothèque de rendu que nous avons utilisée tout au long de ce projet. Three.js encapsule WebGL 2 (puis WebGPU) dans un graphe de scène comprenant des caméras, des lumières, des matériaux et des objets géométriques. Elle fournit InstancedMesh pour afficher de nombreux exemplaires d'une même géométrie en un seul appel de rendu, ainsi que l'élimination selon le frustum, des matériaux PBR et des effets de post-traitement. Consultez Three.js sur GitHub. Pour comprendre la place de Three.js dans l'architecture d'un monde ouvert sur navigateur, consultez notre guide des technologies 3D pour navigateur.

InstancedMesh. Une fonctionnalité de Three.js qui affiche N exemplaires d'une même géométrie en un seul appel de rendu, chacun avec une position, une rotation et une échelle différentes. Les transformations propres à chaque instance sont stockées dans un tampon d'attributs matriciels. C'est ainsi que nous avons affiché 500 objets dans le prototype exploratoire 1 sans effectuer 500 appels de rendu distincts. Pour gérer la végétation à grande échelle, l'élimination des instances pilotée par le GPU pousse ce principe encore plus loin. Consultez notre guide sur l'élimination de la végétation par le GPU.

Budget par image. À 60 images par seconde, chaque image dispose de 1000 ms6016.7 ms pour tout exécuter : la logique JavaScript, la physique, le rendu et la composition. Un prototype exploratoire de « vérification du budget » mesure la part de ce temps consommée par une scène de référence. La marge restante pour tout ce que vous ajouterez ensuite est donc tfeatures=16.7tbaseline. Si la scène de référence consomme déjà 12 ms, il ne reste qu'environ 4,7 ms pour le gameplay, la physique et le réseau réunis. Cette approche vient du développement de mondes ouverts AAA, où GTA V, Skyrim et Elden Ring utilisent tous des niveaux de détail et du chargement en continu très agressifs pour respecter des budgets fixes par image.


Partie 1 sur 12.
À suivre : Partie 2 — La physique dans un worker et la crainte de la latence des commandes
Guide de la série : /fr/blog/2026-02-25-open-world-browser-series-guide