Lesson 22 - Bump Mapping

 

Introduction

This lesson is an introduction to bump mapping. Bump mapping was invented by Jim Blinn in 1978 as part of his work for the visualization of the Voyrager space-probe project. Bump mapping is a technique in computer graphics for simulating bumps and wrinkles on the surface of an object. This is achieved by perturbing the surface normals of the object and using the perturbed normal during lighting calculations. The result is an apparently bumpy surface rather than a smooth surface although the surface of the underlying object is not changed. (We'll look at actual height-mapping in lesson 34).

How Does It Work?

Three.js uses the height map for simulating the surface displacementwhich yields the modified normal. How does this work? Before a lighting calculation is performed for each visible point (or pixel) on the object's surface:

  • Look up the height in the heightmap that corresponds to the position on the surface
  • Calculate the surface normal of the heightmap
  • Combine the surface normal from step two with the true ("geometric") surface normal so that the combined normal points in a new direction
  • Calculate the interaction of the new "bumpy" surface with lights in the scene using, typically, the Phong reflection model

But how is the "height map" calculated? The answer is that the height map is a second texture or image (usually monochrome) whose values are treated a range of values.

or example, the original image (there are now two you can switch between) was


 

The height map for that image is:



The lighter the tone, the "lower" it is simulated as and vice versa.

Using a Bump Map

The actual code is very simple. We initialize the GFXScene same as always. Then the bump mapping is very simple as three.js does all the work:

function makeMesh( bumped, image ) {

    gfxScene.remove(mesh);

    var geom = new THREE.CubeGeometry( 2, 2, 2 );

    var texture = new THREE.ImageUtils.loadTexture("images/" + image + ".jpg");
    var bumpName = "images/" + image + "-bump.jpg";
    var bump = bumped === true ? new THREE.ImageUtils.loadTexture(bumpName) : null;
    var scale = bumped === true ? 0.2 : 0;

    var mat = new THREE.MeshPhongMaterial( { map:texture, bumpMap:bump, bumpScale:scale } );

    mesh = new THREE.Mesh( geom, mat );
  
    gfxScene.add(mesh);
}

We create a 2-unit cube centered on the origin. First load the texture, then check if "bumping" is currently requested (pressing the 'b' key, default is true). If bumping is on, then load the "bump" texture. Then create the material, passing in the bump-map if requested. The value of the scale is arbitrary, but large values don't really make a difference.

And that's it! Click on this link to see the actual rendered demo in all it's bumpy glory!

As always, the original sources are on github here.



About Us | Contact Us | ©2017 Geo-F/X