Pourquoi ce moteur
Pas une liste de fonctionnalités — la poignée de décisions qui changent ce que vous pouvez construire, et pourquoi elles comptent en pratique.
Un seul modèle, partout
L'éditeur, le lecteur web, l'application mobile et le serveur exécutent la même scène : les mêmes objets, les mêmes composants, le même comportement.
Pas d'étape d'export, pas de « format d'exécution » séparé, pas de seconde implémentation qui dériverait de la première. Ce que vous avez disposé dans l'éditeur est ce qui tourne, et un bug que vous voyez dans le lecteur est reproductible partout.
La conséquence pratique est ennuyeuse et précieuse : les choses ne changent pas de sens quand vous publiez.
Les graphes deviennent du code, pas un interpréteur
Dans la plupart des outils, un graphe visuel est une donnée que quelque chose parcourt à l'exécution, nœud après nœud, à chaque image. Ici il est compilé en un script ordinaire, une fois, et c'est ce script qui tourne.
| Vitesse | un graphe coûte autant que du code écrit à la main, parce qu'il est du code |
| Inspectable | ouvrez le panneau de code et lisez exactement ce qu'est devenu votre graphe |
| Composable | un graphe peut appeler un script et un script peut appeler un graphe, parce que ce sont la même chose en dessous |
Il n'y a donc pas de plafond où il faudrait abandonner l'outil visuel et tout réécrire en code. Vous ajoutez un script à côté du graphe que vous avez déjà.
Les matériaux sont des graphes de bout en bout
Les types de matériaux intégrés ne sont pas un ensemble figé avec un éditeur de nœuds greffé dessus. Ce sont des points à l'intérieur du même système qu'utilise un graphe personnalisé — un matériau en graphe n'est donc pas plus lent, pas un citoyen de seconde zone, et pas limité au web : le même graphe compile pour le navigateur et pour le moteur de rendu natif d'un téléphone.
Et ce que vous n'utilisez pas ne coûte rien. Les extras physiques laissés à leurs valeurs par défaut sont éliminés à la compilation : un matériau ayant l'option du verre est exactement aussi bon marché qu'un matériau sans elle.
Cela fonctionne comme un tableur
C'est la décision sur laquelle tout le reste repose, et le plus simple est de l'expliquer par analogie.
Dans un tableur, vous changez une cellule et seules les formules qui l'utilisent se recalculent. Personne ne recalcule toute la feuille, et vous n'appuyez jamais sur un bouton « actualiser ».
La scène fonctionne exactement ainsi. Changez la couleur d'un objet et les seules choses qui réagissent sont celles qui lisaient la couleur. Pas l'objet — la couleur.
changement material.color
│
├─ le moteur de rendu repeint cette surface
├─ le champ de l'inspecteur qui l'affiche se met à jour
├─ le changement est mis en file pour vos collaborateurs
└─ …et rien d'autre ne s'exécute
Ce que cela vous apporte
Rien n'interroge en boucle et rien ne se re-rend par précaution. Il n'y a pas de passe par image comparant le monde à une copie de lui-même pour trouver ce qui a bougé. Une image fait le travail qu'exigent les changements, et une scène immobile ne coûte presque rien.
Les grandes scènes restent réactives pendant que vous les éditez. Une timeline de vingt mille keyframes ne se redessine pas parce que l'un d'eux a bougé : un panneau peut dépendre de « les keyframes ont changé » sans s'abonner à chaque keyframe de la liste. C'est cette distinction qui garde les gros projets utilisables.
Le chargement ne demande pas de code de chargement. Un système demande une ressource et ne reçoit rien si elle n'est pas arrivée ; quand elle arrive, le système se réexécute simplement. Personne n'écrit de callbacks, n'interroge un drapeau « prêt », ni ne traite deux fois le cas « pas encore chargé ».
Un seul flux de changements alimente tout. Le moteur de rendu, l'inspecteur, l'annulation, vos collaborateurs, le bac à sable des scripts et la simulation physique lisent les mêmes mises à jour — c'est pourquoi ils ne peuvent pas diverger ni être en désaccord sur ce que contient la scène. L'annulation n'est pas un chemin spécial ; c'est un changement de plus dans le même tuyau.
Vous ne pouvez pas oublier de prévenir le moteur. Pas de « marquer comme sale », pas de « rafraîchir », aucune invalidation manuelle à retenir. Écrire la valeur est la notification.
Mettre à jour une valeur fusionne dans ce qui existe déjà au lieu de le remplacer : tout ce qui observait reste attaché à la même chose qu'il observait. Cela a l'air d'un détail d'implémentation ; c'est la différence entre une animation fluide et une cadence d'images qui s'affaisse à mesure que votre scène grandit.
Ce n'est pas une fonctionnalité du framework — c'est le substrat
La réactivité est son propre paquet, et le même vous est accessible. Un panneau de plugin, une extension de composant et l'inspecteur de l'éditeur sont tous écrits avec lui : une extension que vous écrivez se met à jour exactement pour la même raison que les panneaux intégrés.
import { signal, computed, effect, batch } from '@was/signals';
const score = signal(0);
const label = computed(() => `Score: ${score.value}`);
effect(() => render(label.value)); // relancé seulement quand le score bouge
batch(() => { score.value += 1; score.value += 1; }); // une mise à jour, pas deux
Trois propriétés méritent d'être nommées, car la plupart des systèmes réactifs en ont une ou deux :
| Fine granularité | les dépendances sont suivies par valeur lue, pas par composant. Rien ne se re-rend « au cas où ». |
| Profondeur | tout un arbre d'objet devient réactif : surveiller position.y ne revient pas à surveiller l'objet |
| Dépendance bon marché | vous pouvez dépendre du fait que quelque chose a changé sans le lire — c'est ce qui empêche une énorme liste de se re-rendre quand un élément bouge |
Le dernier a l'air obscur et c'est la raison pour laquelle une timeline de vingt mille keyframes reste éditable.
Une validation qui ne vous coûte pas une image
Chaque composant est décrit par un schéma, et les schémas signifient normalement un impôt : quelque chose parcourt une description à l'exécution, champ par champ, à chaque arrivée de données.
Ici le schéma est compilé une fois en code pour cette forme précise. Il n'y a pas de parcours. La différence n'est pas académique — mesurée sur le banc d'essai de ce projet :
| Analyse | Ajouté au bundle | |
|---|---|---|
| La bibliothèque habituelle (zod) | 94,7 ns par opération | +267 Ko minifiés, +61 Ko gzippés |
| Celle-ci (svdt) | 5,0 ns par opération | rien — elle est déjà là |
Environ dix-neuf fois plus rapide, et rien de plus à télécharger pour vos visiteurs.
Cela compte parce que la validation n'est pas un événement rare ici : elle tourne à chaque changement qui traverse la frontière entre l'éditeur, le bac à sable des scripts, la simulation physique et vos collaborateurs. Un coût par champ qui paraît négligeable devient le budget d'animation quand il se produit des milliers de fois par seconde.
C'est le même paquet que votre propre plugin peut importer pour ses propres données. → Les paquets partagés
Le travail lourd sort de l'image
Deux choses qui bloquent habituellement une page de navigateur en sont sorties :
- Vos scripts tournent isolés de la page : une boucle lente ne peut pas geler le rendu.
- La physique tourne à côté de l'image plutôt que dedans.
Une scène reste réactive pendant qu'elle est occupée, au lieu de perdre des images quand votre logique devient intéressante.
Le runtime refuse le travail tant qu'il n'en a pas besoin
C'est la partie qui se manifeste comme du temps de chargement pour vos visiteurs.
La physique ne démarre pas, et ne se télécharge pas, tant qu'une scène n'en a pas réellement besoin. Un décor sans pièces mobiles ne paie jamais le simulateur : ce sont des mégaoctets que vos visiteurs n'attendent pas. La vérification est vivante : une balle créée en cours de session fait démarrer la physique pour elle-même.
Dix mille copies coûtent à peu près une. Herbe, foules, débris et particules se dessinent en un seul appel. Leur disposition est générée à partir d'une graine plutôt que stockée : elle ne coûte rien dans le fichier, rien sur le réseau, et paraît identique pour chaque participant.
Rien au niveau de la particule n'est jamais synchronisé. Les mêmes réglages produisent le même effet partout : un effet élaboré est donc gratuit en multijoueur.
Un seul vocabulaire pour le comportement
Événements, graphes de patch et scripts entendent les mêmes déclencheurs — on-click veut dire
la même chose dans les trois. Vous apprenez un jeu de noms, puis vous choisissez combien de code
vous voulez écrire.
Cela veut aussi dire que vous pouvez commencer une interaction comme un événement, la promouvoir en patch quand il lui faut une condition, et passer au script quand il lui faut de la vraie logique — sans rien réapprendre.
Bâti pour plus d'une personne
La collaboration n'est pas une fonctionnalité greffée : un space est un monde vivant partagé par tous ceux qui s'y trouvent, donc les modifications apparaissent au fur et à mesure et l'annulation fonctionne par personne.
La même machinerie synchronise l'éditeur, le bac à sable des scripts et la simulation physique — c'est pourquoi ils ne peuvent pas être en désaccord sur ce que contient la scène.
Il tourne là où votre public est déjà
Un projet publié s'ouvre depuis un lien, dans un navigateur, sans rien à installer. C'est tout l'intérêt de la WebAR : pas de magasin d'applications, pas de téléchargement, pas de « installez d'abord notre application » entre votre visiteur et ce que vous avez fait.
À partir de là, le même projet va plus loin sans être reconstruit :
| Où | Comment il y arrive |
|---|---|
| N'importe quel navigateur mobile | le lien publié, ou un QR code — rien à installer |
| App Clip iOS | s'ouvre depuis un lien, un QR code ou du NFC, sans installation depuis l'App Store |
| L'application native | un moteur de rendu natif — voir ci-dessous |
| Navigateurs de casques | le même lien publié — le runtime parle WebXR |
| Lunettes et casques AR | une couche XR native pour XREAL One, Quest 3 et PICO 4 — voir ci-dessous |
| Casques via Unity | le SDK Unity — XREAL, PICO, Apple Vision Pro, HoloLens 2, Magic Leap 2, Rokid |
Quelqu'un pointe une caméra vers un code et votre expérience s'ouvre — pas de magasin, pas de compte, pas d'attente. Apple limite la taille d'un clip : gardez la première scène légère et chargez le reste une fois qu'elle tourne.
Les téléphones fonctionnent d'emblée. Les paquets propres aux appareils — pipelines de rendu, profils de manettes, modèles de déploiement — sont accordés par compte. → Plateformes prises en charge
Sur un téléphone, une vitesse de rendu native
Dans un navigateur vous avez WebGL : rapide, avec un plafond. L'application native ne rend pas du tout à travers un navigateur : elle utilise un moteur de rendu natif sur iOS comme sur Android, en parlant directement à Metal et à Vulkan.
Le même projet obtient donc le budget graphique d'une application native — ombres en temps réel, matériaux plus lourds, davantage à l'écran — sans que vous mainteniez une seconde version. Vos matériaux compilent pour ce moteur comme pour le web, et c'est ce qui rend « le même projet » vrai plutôt qu'ambitieux.
Utilisez le build web pour la portée, et l'application pour les projets qui ont besoin du budget d'image.
Les lunettes, nativement
Une couche XR native met le runtime AR Clip lui-même sur des lunettes : le même projet, la même scène, rendue sur l'appareil plutôt que dans un navigateur.
Elle est bâtie comme une interface unique avec des backends fournisseurs interchangeables : un appareil est donc un backend et non un fork du runtime — et cela ne passe pas par Unity :
| Appareil | Par | Ce qui fonctionne |
|---|---|---|
| XREAL One | le SDK du fabricant | affichage, suivi de la tête, caméra, enregistrement de session |
| Meta Quest 3 | OpenXR | affichage, suivi, manettes, suivi des mains, enregistrement de session |
| PICO 4 | OpenXR | idem, avec la caméra désactivée |
Un backend déclare ce qu'il prend réellement en charge au lieu de faire semblant. PICO n'a pas de passthrough caméra ici : une scène qui a besoin du monde réel derrière elle appartient à XREAL ou à Quest ; une scène qui n'en a pas besoin tourne sur les trois.
Quel que soit le chemin par lequel arrive un visiteur, c'est la même scène, avec les mêmes composants et le même comportement. Vous ne maintenez pas une version web et une version casque.
Et il est extensible aux endroits qui comptent
Vos propres étapes et déclencheurs peuvent être enregistrés depuis une application. L'éditeur accepte des plugins qui ajoutent des panneaux, génèrent des scènes ou apportent des types de composants entièrement nouveaux. Le catalogue de nœuds a une sortie de secours pour le seul cas qu'il ne couvre pas.
Chaque tableau de composants, de déclencheurs, d'étapes et de nœuds de ce site est généré depuis le moteur lui-même. Quand le moteur gagne un nœud, la référence gagne une ligne — personne n'a à penser à la mettre à jour.
Suite : Objets et scènes — le modèle au complet.