• No se han encontrado resultados

In most recipes, we only focus on the 3D aspect of Three.js. We show recipes that explain how 3D objects and scenes are rendered, how they can be viewed with different cameras, and how you can change how they look through materials. When you are creating games, you usually also have a 2D layer on top of your 3D scene. You can use this to show health bars, 2D maps, inventory, and much more. In this recipe, we'll show you how to create a 2D overlay using

Getting ready

For this recipe, we require an image that we will use as an overlay. To demonstrate this recipe, we create a simple image that looks like this:

In this recipe, we'll combine this static image with a 3D scene to create the scene that can be seen by opening the 03.05-create-an-hud-overview.html example in your browser:

In this example, you can see that we've got a 3D rotating scene with a static 2D overlay on top of it.

How to do it...

Let's look at the steps you need to take:

1. Let's start with creating the 2D overlay. The overlay we use in this recipe is the one with a fixed width and height (800 by 600). So, before we create the cameras, let's first create the div variable that serves as container for the rendered scene:

container = document.createElement( 'div' ); container.setAttribute(

"style","width:800px; height:600px"); document.body.appendChild( container );

2. Next, let's create the camera that we use to render the overlay. For this, we require

THREE.OrthographicCamera:

orthoCamera = new THREE.OrthographicCamera( WIDTH / - 2, WIDTH / 2, HEIGHT / 2, HEIGHT / - 2, - 500, 1000 );

orthoCamera.position.x = 0; orthoCamera.position.y = 0; orthoCamera.position.z = 0;

The WIDTH and HEIGHT properties are defined as constants with values of 800 and 600. This code fragment creates and positions a standard

THREE.OrthographicCamera object.

3. For the 2D overlay, we create a separate scene where we put the 2D elements:

orthoScene = new THREE.Scene();

4. The only thing we want to add to the 2D scene is the overlay image we showed in the Getting ready section of this recipe. As it's a 2D image, we'll use a

THREE.Sprite object:

var spriteMaterial = new THREE.SpriteMaterial({map: THREE.ImageUtils.loadTexture(

"../assets/overlay/overlay.png")});

var sprite = new THREE.Sprite(spriteMaterial); sprite.position.set(0,0,10);

sprite.scale.set(HEIGHT,WIDTH,1); orthoScene.add(sprite);

THREE.Sprite is always rendered in the same size (1 by 1 pixels) regardless of its distance to the camera. To make the sprite fullscreen, we scale the x axis with 800 (WIDTH) and the y axis with 600 (HEIGHT). With THREE.SpriteMaterial, which we used in the previous code fragment, we point to the overlay image so that it is shown when we add THREE.Sprite to the scene.

5. At this point, we've got THREE.OrthogonalCamera and THREE.Scene, which show you the overlay as an 800 by 600 image. The next step is to create the 3D screen on which we want to apply this overlay. You don't have to do anything special here; you can create a 3D scene by defining THREE.PerspectiveCamera and THREE.Scene

and adding some lights and objects. For this recipe, we assume you've got a camera and a scene with the following names:

persCamera = new THREE.PerspectiveCamera(60, WIDTH / HEIGHT, 1, 2100 );

persScene = new THREE.Scene();

6. Before we move to the render loop where we define that we want to render the 2D scene as an overlay, we need to configure an additional property on the renderer:

renderer = new THREE.WebGLRenderer(); renderer.setClearColor( 0xf0f0f0 ); renderer.setSize( 800, 600 );

renderer.autoClear = false;

container.appendChild( renderer.domElement );

On THREE.WebGLRenderer, we set the autoclear property to false. This means that the screen isn't automatically cleared before renderer renders a scene.

7. The final step is to alter the render loop. We first want to render the 3D scene, and without clearing the 3D-rendered output, render the overlay on the top:

function render() { renderer.clear();

renderer.render( persScene, persCamera ); renderer.clearDepth();

renderer.render( orthoScene, orthoCamera ); }

The first thing we do in the render loop is clear the current output by calling the

clear function on the renderer. We need to do this, as we disabled autoclear on renderer. Now, we render the 3D scene, and before we render the 2D overlay, we call the clearDepth function on the renderer. This makes sure the 2D overlay is rendered completely on top and won't intersect at places with the 3D scene. So finally, we render the 2D overlay by passing in orthoScene and orthoCamera.

How it works...

How this recipe works is actually very simple. We can use the same renderer to render multiple scenes with multiple different cameras in the same render loop. This way, we can position various render results on top of each other. With a THREE.OrthoGraphic camera and THREE.Sprite, it is easy to position an object at absolute positions on screen. By scaling it to the required size and applying a texture, we can display images using a renderer. This output, combined with a regular 3D result, allows you to create these kinds of overlays.

See also

There are a couple of recipes that use an orthographic camera and more advanced tricks to compose the final rendering:

f In this chapter, we explored how to set up THREE.OrthographicCamera in the

Using an orthographic camera recipe.

f In Chapter 4, Materials and Textures, we'll show how you can use an HTML5 canvas

and a HTML5 video as an input to a texture in the Using HTML canvas as a texture and Using an HTML video as a texture recipes.

f In chapter 6, Point Clouds and Postprocessing, we show you how to set up a more

complex rendering pipeline in the Setting up a postprocessing pipeline recipe.

Documento similar