Suggerimento rapido come eseguire il rendering su una trama in Three.js

Per impostazione predefinita, tutto ciò che viene visualizzato in Three.js viene inviato sullo schermo. Dopo tutto, qual è il punto di rendere qualcosa se non riesci a vederlo? Si scopre che c'è un punto molto importante: catturare i dati prima viene inviato allo schermo (e quindi perso). 

Ciò rende molto più semplice applicare effetti di post-elaborazione, come la correzione del colore, lo spostamento del colore o la sfocatura, ed è utile anche per gli effetti shader.

Questa tecnica è conosciuta come rendendo a una trama o rendering su un frame buffer; il risultato finale è memorizzato in una texture. che puoi quindi visualizzare sullo schermo. In questo suggerimento rapido, ti mostrerò come farlo, e poi ti illustrerò un esempio pratico di come rendere un cubo in movimento sulle superfici di un altro cubo in movimento.

Nota: Questo tutorial presume che tu abbia una certa familiarità con Three.js. In caso contrario, consulta Come imparare Three.js per lo sviluppo del gioco.

Implementazione di base

Ci sono molti esempi là fuori su come fare questo che tendono ad essere incorporati in effetti più complicati. Ecco il minimo indispensabile per il rendering di qualcosa su una trama in Three.js:

// @author Omar Shehata. 2016. // Stiamo caricando la libreria Three.js dal CDN qui: // http://cdnjs.com/libraries/three.js/ //// Questa è la configurazione di base della scena //// var scene = nuovo THREE.Scene (); var width, height = window.innerWidth, window.innerHeight; var camera = new THREE.PerspectiveCamera (70, larghezza / altezza, 1, 1000); var renderer = new THREE.WebGLRenderer (); renderer.setSize (larghezza, altezza); document.body.appendChild (renderer.domElement); //// Qui viene creato il nostro obiettivo di rendering fuori schermo //// // Crea una scena diversa per contenere i nostri oggetti buffer var bufferScene = new THREE.Scene (); // Crea la trama che memorizzerà i nostri risultati var bufferTexture = new THREE.WebGLRenderTarget (window.innerWidth, window.innerHeight, minFilter: THREE.LinearFilter, magFilter: THREE.NearestFilter); //// // Aggiungi tutto ciò che vuoi rendere / catturare in bufferScene qui // //// function render () requestAnimationFrame (render); // Renderizza sul nostro renderer.render texture off-screen (bufferScene, camera, bufferTexture); // Infine, disegna sullo schermo renderer.render (scene, camera);  render (); // Render tutto!

Per prima cosa abbiamo l'impostazione di base della scena. Quindi, creiamo un'altra scena, bufferScene; qualsiasi oggetto aggiunto a questa scena verrà disegnato sul nostro obiettivo fuori schermo anziché sullo schermo.

Quindi creiamo bufferTexture, che è un WebGLRenderTarget. Questo è ciò che Three.js usa per farci eseguire il rendering su qualcosa di diverso dallo schermo. 

Infine, diciamo a Three.js di renderizzare bufferScene:

renderer.render (bufferScene, camera, bufferTexture);

Questo è come mostrare una scena normale, tranne che specifichiamo un terzo argomento: il render target. 

Quindi i passaggi sono:

  1. Crea una scena per contenere i tuoi oggetti.
  2. Crea una texture per memorizzare ciò che rendi
  3. Rendi la tua scena sulla tua texture

Questo è essenzialmente ciò che dobbiamo fare. Non è molto eccitante, però, dal momento che non possiamo vedere nulla. Anche se hai aggiunto cose al bufferScene, ancora non vedrai nulla; questo perché devi rendere in qualche modo la texture che hai creato sulla tua scena principale. Quello che segue è un esempio di come farlo.

Esempio di utilizzo

Creeremo un cubo in una scena, lo disegneremo su una trama e poi useremo quello come una trama per un nuovo cubo!

1. Inizia con una scena di base

Ecco la nostra scena di base con un cubo rosso rotante e un piano blu dietro di esso. Non c'è niente di speciale qui, ma puoi controllare il codice passando a CSSJS schede nella demo.

Puoi fork e modificare questo su CodePen.

2. Renderizza questa scena su una trama

Ora lo prenderemo e lo trasformeremo in una texture. Tutto ciò che dobbiamo fare è creare un bufferScene proprio come nella precedente implementazione di base, e aggiungere i nostri oggetti ad esso.

Puoi fork e modificare questo su CodePen.

Se fatto bene, non vedremo nulla, dal momento che ora non viene eseguito il rendering sullo schermo. Invece, la nostra scena è renderizzata e salvata in bufferTexture.

3. Rendering di un cubo strutturato

bufferTexture non è diverso da qualsiasi altra trama. Possiamo semplicemente creare un nuovo oggetto e usarlo come trama:

var boxMaterial = new THREE.MeshBasicMaterial (map: bufferTexture); var boxGeometry2 = new THREE.BoxGeometry (5, 5, 5); var mainBoxObject = new THREE.Mesh (boxGeometry2, boxMaterial); // Spostalo indietro in modo che possiamo vederlo mainBoxObject.position.z = -10; // Aggiungilo alla scena principale scene.add (mainBoxObject);
Puoi fork e modificare questo su CodePen.

Potresti potenzialmente disegnare qualsiasi cosa nella prima texture e quindi renderla su qualsiasi cosa tu voglia! 

Usi potenziali

L'uso più diretto è qualsiasi tipo di effetto di post-elaborazione. Se volevi applicare una sorta di correzione del colore o spostarti sulla tua scena, invece di applicare a ogni singolo oggetto, potresti semplicemente rendere l'intera scena su una texture, e poi applicare qualsiasi effetto vuoi a quella texture finale prima di renderla a lo schermo. 

Qualsiasi tipo di shader che richiede passaggi multipli (come la sfocatura) farà uso di questa tecnica. Spiego come utilizzare i frame buffer per creare un effetto fumo in questo tutorial.

Spero che tu abbia trovato utile questo piccolo consiglio! Se noti errori o domande, per favore fammelo sapere nei commenti!