Advertisement
  1. Game Development
  2. Three.js

Consejo rápido: cómo renderizar a una textura en Three.js

Scroll to top
Read Time: 5 min

Spanish (Español) translation by Carlos (you can also view the original English article)

Por defecto, todo lo que renderizas en Three.js es enviado a la pantalla. Después de todo, ¿qué sentido tiene renderizar algo si no puedes verlo? Resulta que hay un punto muy importante: capturar los datos antes de que se envíen a la pantalla (y por consiguiente se pierdan).

Esto facilita la aplicación de efectos de postprocesamiento, como corrección de color, cambio de color o desenfoque, y también es útil para los efectos de sombreado.

Esta técnica es conocida como renderizado a una textura o renderizado a un frame buffer; tu resultado final se almacena en una textura. Que luego puedes renderizar en la pantalla. En este consejo breve, te enseñaré cómo hacerlo, y luego te guiaré a través de un ejemplo práctico de cómo renderizar un cubo en movimiento sobre las superficies de otro cubo en movimiento.

Nota: Este tutorial asume que tienes cierto conocimiento básico de Three.js. Si no, consulta: Cómo aprender Three.js para el desarrollo de juegos.

Implementación básica

Existen muchos ejemplos sobre cómo hacer esto que suelen estar integrados en efectos más complicados. Aquí está lo mínimo que se necesita para renderizar algo en una textura en Three.js:

1
// @author Omar Shehata. 2016.

2
// We are loading the Three.js library from the CDN here: 

3
// https://cdnjs.com/libraries/three.js/

4
5
//// This is the basic scene setup ////

6
7
var scene = new THREE.Scene();
8
var width, height = window.innerWidth, window.innerHeight;
9
var camera = new THREE.PerspectiveCamera( 70, width/height, 1, 1000 );
10
var renderer = new THREE.WebGLRenderer(); 
11
renderer.setSize( width,height);
12
document.body.appendChild( renderer.domElement );
13
14
//// This is where we create our off-screen render target ////

15
16
// Create a different scene to hold our buffer objects

17
var bufferScene = new THREE.Scene();
18
// Create the texture that will store our result

19
var bufferTexture = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, { minFilter: THREE.LinearFilter, magFilter: THREE.NearestFilter});
20
21
////

22
// Add anything you want to render/capture in bufferScene here //

23
////

24
25
function render() {
26
	requestAnimationFrame( render );
27
	// Render onto our off-screen texture

28
	renderer.render(bufferScene, camera, bufferTexture);
29
	// Finally, draw to the screen

30
	renderer.render( scene, camera );
31
}
32
33
render(); // Render everything!

Primero tenemos la configuración básica de la escena. Luego, creamos otra escena, BufferScene; cualquier objeto que añadamos a esta escena será atraído a nuestro objetivo fuera de la pantalla en vez de a la pantalla.

Después, creamos bufferTexture, que es un WebGLRenderTarget. Esto es lo que Three.js utiliza para permitirnos renderizar en algo más que la pantalla.

Por último, le decimos a Three.js que renderice bufferScene:

1
renderer.render(bufferScene, camera, bufferTexture);

Esto es como renderizar una escena normal, excepto que especificamos un tercer argumento: el objetivo de la renderización.

Así que los pasos son:

  1. Crear una escena para contener tus objetos.
  2. Crear una textura para almacenar lo que renderizas
  3. Renderizar tu escena en tu textura

Esto es básicamente lo que necesitamos hacer. Sin embargo, no es muy emocionante, puesto que no podemos ver nada. Aun si has añadido cosas a BufferScene, seguirás sin ver nada; esto se debe a que de alguna manera tienes que renderizar la textura que has creado en tu escena principal. El siguiente es un ejemplo de cómo hacerlo.

Ejemplo de uso

Vamos a crear un cubo en una escena, dibujarlo en una textura, y ¡luego utilizar eso como una textura para un nuevo cubo!

1. Empieza con una escena básica

Aquí está nuestra escena básica con un cubo rojo girando y un plano azul detrás de él. No hay nada especial aquí, pero puedes revisar el código cambiando a las pestañas CSS o JS en la demostración.

Puedes hacer un fork (bifurcar) y editar esto en CodePen.

2. Renderiza esta escena en una textura

Ahora vamos a tomar eso y renderizarlo en una textura. Todo lo que debemos hacer es crear un bufferScene como en la implementación básica anterior, y añadirle nuestros objetos.

Puedes bifurcar y editar esto en CodePen.

Si se ha hecho bien, no veremos nada, ya que ahora no se está proyectando nada en la pantalla. En lugar de ello, nuestra escena se ha renderizado y se ha guardado en BufferTexture.

3. Renderiza un cubo texturizado

bufferTexture no es diferente de cualquier otra textura. Podemos simplemente crear un nuevo objeto y utilizarlo como nuestra textura:

1
var boxMaterial = new THREE.MeshBasicMaterial({map:bufferTexture});
2
var boxGeometry2 = new THREE.BoxGeometry( 5, 5, 5 );
3
var mainBoxObject = new THREE.Mesh(boxGeometry2,boxMaterial);
4
5
// Move it back so we can see it

6
mainBoxObject.position.z = -10;
7
// Add it to the main scene

8
scene.add(mainBoxObject);
Puedes bifurcar y editar esto en CodePen.

¡Podrías dibujar cualquier cosa en la primera textura, y luego renderizarla en lo que quieras!

Usos potenciales

El uso más simple es cualquier tipo de efecto de postprocesamiento. Si quisieras aplicar algún tipo de corrección o cambio de color a tu escena, en vez de aplicarla a cada uno de los objetos, podrías simplemente renderizar toda la escena en una textura, y luego aplicar el efecto que desees a esa textura final antes de renderizarla en la pantalla.

Cualquier tipo de sombreador que requiera múltiples pasadas (como el desenfoque) hará uso de esta técnica. Explico cómo utilizar frame buffers de para crear un efecto de humo en este tutorial.

¡Esperamos que te haya resultado útil este pequeño consejo ! Si detectas algún error o tienes alguna pregunta, ¡por favor házmelo saber en los comentarios!

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Game Development tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.