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.
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:
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.
Creeremo un cubo in una scena, lo disegneremo su una trama e poi useremo quello come una trama per un nuovo cubo!
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 CSS o JS schede nella demo.
Puoi fork e modificare questo su CodePen.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.
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
.
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!
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!