De nombreux bugs ont été corrigés sur la démonstration du configurateur de maisons disponible ici : configurateur de maisons web 3D.
Nous sommes actuellement en train de développer l’aspect commercial du projet, l’objectif étant d’avoir un produit commercialisable à compter de septembre prochain. D’ici là, la compatibilité avec le webgl aura encore augmenté (elle est actuellement d’environ 55% en général, de 85% si tout le monde utilisait Chrome, et continue d’augmenter), le logiciel sera débogué et nous aurons des modèles de maisons issus de partenariats avec des constructeurs.
SPACEGOO.com conservera sa même interface, un peu old school ;). Pour le configurateur nous créeront à terme un site internet pour regrouper les offres des constructeurs.
Le projet principal sur lequel nous travaillons depuis 5 mois est un configurateur de maisons, LIGNUM. Du fait des développements de la démo de jeu d’échecs webgl/webrtc , de la démo Paris Bubbles ainsi que du petit jeu Teach me to fly, le temps effectif passé sur le projet est plutôt de 4 mois.
LIGNUM est une application en ligne permettant de créer sa propre maison à partir d’un modèle prédéfini, en personnalisant le modèle. Nous visons dans un premier temps le marché français des maisons individuelles et plus particulièrement celui des maisons à ossature bois. Nous comptons commercialiser l’application en service as a software à compter de début septembre 2012.
Ce configurateur est conçu pour être utilisé soit par le prospect, à partir du site internet du fabricant ou d’un autre site agglomérant les offres, ou par un commercial devant le client. Il permettra de réduire la durée de la phase de conception en 3D de la maison, pendant laquelle un architecte dessine la future maison sans savoir encore si le client va signer le contrat. Il permettra aussi de présenter au client immédiatement un rendu. La plupart des maisons vendues étant proches de modèles sur catalogue, LIGNUM devrait pouvoir satisfaire à terme ces demandes.
D’ici là, il reste une importante phase de débogage, de rajout de fonctionnalités spécifique demandées par les constructeurs, ainsi que l’ajout de modèles de maisons, de matériaux et d’objets 3D (fenêtres, mobilier, barrières, …).
Au niveau technique, le rendu et l’éditeur de terrain sont réalisés en utilisant la technologie webgl. Les phases de configuration 2D avec vue de dessus utilisent l’élément CANVAS 2D d’HTML5.
TEACH ME TO FLY est un petit jeu de vol en webgl développé en deux jours en utilisant la librairie Three.js . Le code est disponible sur github ici.
Ce jeu peut facilement être recustomisé. Tux est un modèle Collada créé sous Blender puis exporté. La map est dans l’index.html et elle est composée de lignes sous la forme :
FF 32 00 EA EA EF EF FF FF A8 00 FF \
Chaque ligne de ce type représente une rangée de building. Chaque bloc de charactères hexadécimaux représente un building. La forme du building correspond à la notation binaire du bloc en hexadécimal. Par exemple FF s’écrit 11111111 en binaire, et sera donc un building plein de hauteur maximale.
L’éclairage de la scène se compose d’une spotlight placée au niveau du pingouin pour éclairer les buildings, d’une lumière ambiante, d’une pointlight orangée placée au niveau de la caméra pour éclairer surtout le pingouin, et d’une lumière directionnelle utilisée uniquement pour l’ombrage.
Nous avons effectué un petit break dans le projet sur lequel nous travaillons depuis 3 mois, et sur lequel nous n’avons encore rien communiqué, afin de développer un sympathique jeu d’échecs en 3D en 5 jours.
Au niveau 3D, la démonstration repose sur une version allégée du moteur 3D SPACEGOO. L’éclairage est réalisé par combinaison d’ambient occlusion par cuisson de texture (baking) avec le modèle d’éclairage de Blinn Phong ( http://en.wikipedia.org/wiki/Blinn%E2%80%93Phong_shading_model ). Les ombres sont réalisées en ombres projetées, en activant l’option GL.BLEND et en utilisant le stencil buffer pour ne pas foncer plusieurs fois les mêmes pixels de l’ombre.
Au niveau de la retransmission webcam, nous avons utilisé la récente technologie webrtc ( http://www.webrtc.org ) . Cette dernière permet de récupérer l’image de la webcam dans l’élément VIDEO d’HTML5, et de la retransmettre en P2P.
Pour l’ouverture du canal de transmission et la transmission P2P, nous avons utilisé le serveur d’exemple (peerconnection_server) dont la compilation est expliquée ici : http://www.webrtc.org/reference/getting-started . Ce serveur ayant tendance à être assez capricieux (il communique par requêtes AJAX avec les clients et parfois il ne les retransmet pas), il a été nécessaire de rajouter un petit protocole de transmission de données avec ACK pour éviter des deadends au cours des parties.
Cette démonstration serait présentée au meeting de l’IETF à Paris à la fin du mois, dans le but de promouvoir la technologie webrtc et de montrer que cette dernière peut apporter bien plus qu’un simple « Skype dans le navigateur ».
En attendant que la démo soit en ligne (il manque le serveur pour la faire tourner, et pour l’instant notre contrat d’hébergement ne nous permet pas de faire tourner ce serveur sur spacegoo.com), voici une video screenshot du résultat :
Webgl/Webrtc CHESS
Runtime
6:29
Compteur de vues
6,581
Il ne reste plus qu’à espérer que cette technologie se démocratise rapidement. Elle est pour l’instant disponible sur les builds des canaux Dev et Canary de Chrome, et elle devrait arriver d’ici peu dans les Firefox Nighties.
Nous avons mis en ligne une nouvelle démo : marching cubes sandbox que vous pouvez voir ici : http://www.spacegoo.com/marchingCubes
Pour les gens qui ne sont pas compatibles, nous avons réalisé une vidéo capture d’écran :
Marching Cubes Sandbox
Runtime
0:59
Compteur de vues
1,269
Dans cette démo, nous avons implémenté l’algorithme marching cubes dans un version modifiée. En effet, webgl ne permet pas d’accéder au geometry shader comme dans le code original. Nous avons donc du migrer la génération des vertex du côté du javascript, avant d’en faire le rendu par WebGL.
Rappelons brièvement comment fonctionne l’algorithme. Il s’agit de générer une géométrie à partir d’une fonction appelée « fonction de densité ». Celle-ci prend la forme Par exemple, si on veut générer une sphère, on prendra
On divise ensuite l’espace en cubes ou « chunks » pour récupérer la terminologie initiale. Ceux-ci sont disposés dans l’ordre idoine (celui des z-croissants) au sein du cône de vue WebGL. Chacun d’entre eux est ensuite divisé en une grille de 32*32*32 « voxels » pour lesquels on va générer les vertex. Pour décider si l’on en génére ou non, on regarde les valeurs de la fonction au huit sommets du « voxel ». Si cette valeur est positive, on attribue la valeur 1 au sommet, sinon la valeur 0. On se retrouve avec 256 cas possibles, qui se réduisent à 14 modulo le groupe de symétrie du cube. Voici ces cas (l’image est tirée du site nVidia) :
Les 14 cas primitifs
Une fois qu’on a parcouru tous les voxels, on se retrouve donc avec un tableau contenant les sommets et les faces à générer.
Il y a alors deux problèmes.
La plupart des calculs qu’on effectue aboutissent à un voxel qui ne génère pas de vertex, soit qu’il soit complètement en dehors de la surface, soit qu’il soit complètement en dedans.
Une fois qu’on a généré la géométrie, la plupart des vertex sont générés en plusieurs exemplaires, ce qui alourdit le rendu. De plus, les vertex index buffers de webgl sont limités à 65536 sommets, puisqu’ils sont encodés sur des short.
Pour résoudre ces problèmes, nous avons choisi en première approche une solution qui n’est pas optimale, mais permet d’aboutir simplement à de bons résultats.
Nous avons rêglé le premier problème en remplaçant chaque chunk par un octree dont la racine est le chunk en question et dont on subdivise les cellules seulement si elles doivent générer des vertex. Par une astuce, on peut aussi s’assurer que la fonction de densité ne sera jamais évaluée deux fois au même endroit.
Le deuxième problème est beaucoup plus complexe, et nous avons choisi de générer les vertex doubles, mais de faire une passe de calcul supplémentaire où on les enlève. Nous faisons ceci par un tri rapide simultané sur les deux buffers (vertex et index) et puis en supprimant les doublons.
Cette solution a l’avantage d’être rapide car le tri rapide ne prend que peu de temps. L’inconvénient est qu’au cours du calcul, juste avant la phase de tri, les buffers sont énorme (plus de 4 fois plus gros que nécessaire) ce qui surcharge de travail le garbage collector javacript et peut rapidement saturer la mémoire du navigateur. Il faut noter en passant que notre première implémentation de l’octree était récursive ce qui, quand ça ne faisant pas planter la call stack de javascript, explosait le garbage collector. Nous avons donc préféré l’implémenter à la main.
Nous avons donc pour projet d’optimiser cela en reprenant l’idée originale de l’algorithme, qui consiste à « marcher » dans l’octree en suivant les composantes connexes de la surface à mailler.
Mais cela fera l’objet d’un autre article plus détaillé!