Analyse
Au cours de nos sessions Vendredis R&D, on a voulu travailler sur une méthode nous permettant d’enchaîner plusieurs scènes WebGL dans une même expérience, comme on peut le voir sur les sites Deso ou Junni.
Dans les deux exemples ci-dessus, les scènes WebGL se succèdent de façon très naturelle, en faisant défiler le contenu de la page. On constate que sur Junni, certains éléments sont présents entre deux scènes, clin d’œil subtil qui rend l’expérience encore plus satisfaisante. Dans Deso, un volet oblique vient faire la transition entre deux longues sections WebGL dans lesquelles la caméra se déplace selon un chemin prédéfini que l’on parcourt en défilant.
Avec ThreeJS, la classe WebGLRenderer fait le rendu d’une scène dans un , selon le point de vue d’une caméra.
Si l’on souhaite faire un rendu de plusieurs scènes, le premier réflexe serait de travailler avec plusieurs canvas. C’est possible, mais ça complexifie grandement l’interactivité entre les scènes (comme voir un élément qui traverse d’une scène à une autre). L’utilisation de plusieurs canvas peut aussi rendre la page plus lourde et affecter sa performance, puisque qu’elle implique plusieurs occurrences de la classe WebGL Renderer. On peut aussi « délimiter » le rendu qu’on souhaite afficher, comme dans cet exemple https://threejs.org/examples/?q=view#webgl_multiple_views. Or, ici non plus la technique n’est pas la plus efficace : la marge de manoeuvre dans les transitions diminue quand on a à gérer des délimitations de rendu pour 6 à 10 scènes.
WebGLRenderTarget à la rescousse
ThreeJS permet de dessiner une scène en arrière-plan dans un espace tampon à l’aide de WebGLRenderTarget. En combinant cette technique à EffectComposer en post-traitement, on peut appliquer des effets sur une image avant de l’afficher à l’écran.
On remarque qu’il y a aucune différence quand on fait un rendu d’une scène avec WebGLRenderTarget. Ce qui est intéressant ici, c’est l’obtention d’une texture qu’on peut manipuler et afficher comme on le souhaite : sur un mesh ou grâce à un calque en post-traitement avec EffectComposer.
Si on va plus loin, il serait donc possible de générer une texture de deux scènes différentes et d’afficher ces deux scènes en même temps avec un effet de post-traitement.
Comment intégrer le multi-scène
Pour obtenir des transitions assez douces sans avoir de coupures entre les scènes, il est primordial d’avoir un rendu de deux scènes : la scène courante et la scène suivante (ou précédente selon la direction du défilement). En résumé, avoir une scène d’avance!
HTML
La partie HTML est optionnelle et, dans le cas qui nous intéresse, est relativement formelle. On a besoin de synchroniser du contenu HTML avec une scène WebGL. Quand on défilera dans dans la page, on pourra faire une transition entre deux scènes. On met en place quatre sections fictives pour que chaque scène WEBGL ait une visibilité basée sur la hauteur de la div à laquelle elle est liée.
ScrollTrigger permet d’accéder aux divers événements de chacune des sections, dans les deux sens du défilement de la page.
Shader et post-traitement
En termes de post-traitement, notre effet sera inclus dans un ShaderPass. Ce type de calque nous permet de lier un shader personnalisé à un calque de notre occurrence de la classe EffectComposer. Pour passer d’une scène WebGL à une autre, on utilise les textures de chaque scène. Dans l’exemple qui suit, on a utilisé la fonction mix pour pouvoir afficher les deux scènes WebGL selon la valeur de uProgress.
Bien sûr, lorsque la scène n’est plus active, elle n’a plus besoin d’être rendue, ça permet d’économiser des rendus inutiles.
Après il est possible de mettre en place d’autres types de transition. Il suffit de faire les changements dans le fragmentShader et d’ajouter d’autres uniforms pour arriver à ce que l’on souhaite.
Le multi-scène, une technique
Cette technique de multi-scène est de plus en plus utilisée dans de longues expériences Webgl qui proposent beaucoup de contenus HTML différents, répartis sur plusieurs scènes Webgl. Elle permet ainsi de maintenir la performance tant sur desktop que sur mobile en effectuant un minimum de rendus. Enfin, le multi-scène donne vie à des scènes tout aussi originales que créatives grâce aux shaders et au post-traitement.
Liens
Threejs (v.147) : Moteur de rendu WebGL qui regorge de fonctionnalités et d’exemples, et rassemble une très grosse communauté.
Book of Shaders: C’est la ressource à lire pour être familier avec les shaders.
ScrollTrigger: Plugin GSAP qui permet de lier des animations avec le défilement.