Astuce comment rendre une texture dans Three.js

Par défaut, tout ce que vous rendez dans Three.js est envoyé à l'écran. Après tout, à quoi ça sert de rendre quelque chose si on ne peut pas le voir? Il s'avère qu'il y a un point très important: capturer les données avant il est envoyé à l'écran (et donc perdu). 

Cela facilite beaucoup l'application d'effets post-traitement, tels que la correction des couleurs, le changement de couleur ou le flou, et c'est également utile pour les effets de shader..

Cette technique est connue sous le nom de rendu à une texture ou rendu dans un frame buffer; votre résultat final est stocké dans une texture. que vous pouvez ensuite rendre à l'écran. Dans ce petit conseil, je vais vous montrer comment faire, puis vous montrer un exemple pratique de rendu d'un cube en mouvement sur la surface d'un autre cube en mouvement..

Remarque: Ce tutoriel suppose que vous ayez une connaissance de base de Three.js. Sinon, consultez Comment apprendre Three.js pour le développement de jeux.

Mise en œuvre de base

Il existe de nombreux exemples sur la façon de procéder qui tendent à être intégrés à des effets plus complexes. Voici le strict minimum dont vous avez besoin pour rendre quelque chose sur une texture dans Three.js:

// @auteur Omar Shehata. 2016. // Nous chargeons la bibliothèque Three.js à partir du CDN ici: // http://cdnjs.com/libraries/three.js/ //// Ceci est la configuration de base de la scène //// var scene = nouveau THREE.Scene (); var width, height = window.innerWidth, window.innerHeight; var camera = nouvelle THREE.PerspectiveCamera (70, largeur / hauteur, 1, 1000); var renderer = new THREE.WebGLRenderer (); renderer.setSize (largeur, hauteur); document.body.appendChild (renderer.domElement); //// C'est ici que nous créons notre cible de rendu hors écran //// // Créez une scène différente pour contenir nos objets de tampon var bufferScene = new THREE.Scene (); // Crée la texture qui stockera notre résultat var bufferTexture = new THREE.WebGLRenderTarget (window.innerWidth, window.innerHeight, minFilter: THREE.LinearFilter, magFilter: THREE.NearestFilter); //// // Ajoutez tout ce que vous voulez rendre / capturer dans bufferScene ici // //// function render () requestAnimationFrame (render); // Rendu sur notre rendu de texture hors écran.render (bufferScene, camera, bufferTexture); // Enfin, dessinez le moteur de rendu d'écran.render (scène, caméra);  render (); // tout rendre!

Nous avons d’abord la configuration de base de la scène. Ensuite, nous créons une autre scène, bufferScene; tout objet ajouté à cette scène sera dessiné sur notre cible hors écran plutôt que sur l'écran.

Nous créons ensuite tamponTexture, qui est un WebGLRenderTarget. C’est ce que Three.js utilise pour nous laisser rendre sur autre chose que l’écran. 

Enfin, nous disons à Three.js de rendre bufferScene:

renderer.render (bufferScene, camera, bufferTexture);

C'est comme si vous rendiez une scène normale, sauf que nous spécifions un troisième argument: la cible de rendu. 

Les étapes sont donc les suivantes:

  1. Créez une scène pour contenir vos objets.
  2. Créez une texture pour stocker ce que vous rendez
  3. Rendez votre scène sur votre texture

C’est essentiellement ce que nous devons faire. Ce n'est pas très excitant, cependant, puisque nous ne pouvons rien voir. Même si vous avez ajouté des choses à la bufferScene, vous ne verrez toujours rien; C'est parce que vous devez en quelque sorte rendre la texture que vous avez créée sur votre scène principale. Ce qui suit est un exemple de comment faire cela.

Exemple d'utilisation

Nous allons créer un cube dans une scène, le dessiner sur une texture, puis utiliser cette comme texture pour un nouveau cube!

1. Commencez avec une scène de base

Voici notre scène de base avec un cube rouge en rotation et un avion bleu derrière. Il n’ya rien de spécial ici, mais vous pouvez vérifier le code en passant à la CSS ou JS onglets dans la démo.

Vous pouvez créer et éditer ceci sur CodePen.

2. Rendre cette scène sur une texture

Maintenant, nous allons prendre cela et le rendre sur une texture. Tout ce que nous devons faire est de créer un bufferScene comme dans l'implémentation de base ci-dessus, et y ajouter nos objets.

Vous pouvez créer et éditer ceci sur CodePen.

Si cela est fait correctement, nous ne verrons rien car, à présent, rien ne s'affiche à l'écran. Au lieu de cela, notre scène est rendue et enregistrée dans tamponTexture.

3. Rendre un cube texturé

tamponTexture n'est pas différent de n'importe quelle autre texture. Nous pouvons simplement créer un nouvel objet et l'utiliser comme notre texture:

var boxMaterial = new THREE.MeshBasicMaterial (map: bufferTexture); var boxGeometry2 = new THREE.BoxGeometry (5, 5, 5); var mainBoxObject = new THREE.Mesh (boxGeometry2, boxMaterial); // Recule le pour que nous puissions le voir. MainBoxObject.position.z = -10; // Ajoutez-le à la scène principale scene.add (mainBoxObject);
Vous pouvez créer et éditer ceci sur CodePen.

Vous pouvez potentiellement dessiner n'importe quoi dans la première texture, puis le rendre comme bon vous semble! 

Utilisations Potentielles

L'utilisation la plus simple est toute sorte d'effet de post-traitement. Si vous souhaitez appliquer une sorte de correction de couleur ou de décalage à votre scène, au lieu de l'appliquer à chaque objet, vous pouvez simplement rendre toute la scène sur une texture, puis appliquer le résultat souhaité à la texture finale avant de la restituer. l'écran. 

Tout type de shader nécessitant plusieurs passes (telles que le flou) utilisera cette technique. J'explique comment utiliser les tampons d'image pour créer un effet de fumée dans ce tutoriel.

J'espère que vous avez trouvé cette petite astuce utile! Si vous remarquez des erreurs ou avez des questions, merci de me le faire savoir dans les commentaires.!