Marco Del Valle Marco Del Valle - 4 years ago 519
Javascript Question

Three.JS: Drawing texture directly to canvas without creating a plane (in a billboard fashion)

I'm rendering a custom texture using a

WebGLRenderTarget
. What I need now is to be able to draw the resulting
renderTarget.texture
directly to the canvas, without adding it to a plane first.

The reason for this is that my camera is orbiting and moving a lot, and I want the texture to be fixed on the top-right corner, like a billboard, without getting left behind.Example

My pseudo-code looks like this:

// Create renderer 1
var renderer1 = new THREE.WebGLRenderer();
renderer1.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer1.domElement);

// Create renderer 2
var renderer2 = new THREE.WebGLRenderer();
renderer2.setSize(100, 100);
document.body.appendChild(renderer2.domElement);

var renderTarget = new THREE.WebGLRenderTarget(100, 100);

// Create texture to renderTarget
renderer1.render(textureScene, ortoCam, renderTarget, false);

// Render textureScene to second renderer to see texture
renderer2.render(textureScene, ortoCam);

// Render the rest of the scene, with a moving perspective camera
renderer1.render(scene, perspCam);


This works, but feels very inefficient, especially since I'm creating a second renderer to add a second 100x100 canvas. Is there any way to grab the
renderTarget.texture
and draw it on top of the first canvas so I can skip using the second renderer? I need the renderTarget output to create height maps, but also need it to be visible in a billboard fashion on the top-right corner.

Update:
I've tried creating a 2D canvas context and using
context.drawImage(this.renderTarget.texture.image, 10, 10, 20, 20);
but
renderTarget.texture.image
is undefined. Any ideas why I can't get that image data?

Answer Source

You should only need a single renderer.

You can render an overlay inset by using a pattern like so:

renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.autoClear = false; // important!
document.body.appendChild( renderer.domElement );

In the render() function,

renderer.clear();

// render to texture
renderer.render( texture_scene, ortho_camera, renderTarget, true );

// render scene first
renderer.setViewport( 0, 0, window.innerWidth, window.innerHeight );
renderer.render( scene, camera );

// render inset second
renderer.clearDepth(); // clear the depth buffer
renderer.setViewport( 10, window.innerHeight - insetHeight - 10, insetWidth, insetHeight );
renderer.render( inset_scene, ortho_camera );

three.js r.84

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download