Edit in JSFiddle

// Processing.jsでバンプマッピング

BumpMappedBox myBox;
void setup() {
  size(200, 200, P3D);

  myBox = new BumpMappedBox(100,
    createTexture(),
    createHeightMapImage());
}

void draw() {
  background(0xff);
  camera();
  noStroke();
  pushMatrix();
    translate(.5 * width, .5 * height);

    float baseAngle = radians(millis() * 0.015);
    rotateX(baseAngle);
    rotateZ(baseAngle);
    rotateY(baseAngle);
   
    myBox.render();  
  popMatrix();
}

PImage createTexture() {
  
  int step = 0x20;
  PImage tex = createImage(0x80, 0x80, RGB);
  tex.loadPixels();
  
  for(int i = 0; i < tex.width; i++) {
    for(int j = 0; j < tex.height; j++) {
      tex.set(i, j, 
        (floor(i / step) + floor(j / step)) % 2 == 0 ?
          color(0xcc) : color(0xff));
    }
  }
  tex.updatePixels();
  return tex;
}

PImage createHeightMapImage() {
  int step = 0x20;
  PImage tex = createImage(0x80, 0x80, RGB);
  tex.loadPixels();
  
  for(int i = 0; i < tex.pixels.length; i++) {
    tex.pixels[i] = color(0xff - random());
  }
  for(int i = step; i < tex.width -1; i += step) {
    for(int j = 0; j < tex.height; j++) {
      tex.pixels[i + j * tex.width] = 0xff << 0x16;
    }
  }
  for(int i = 0; i < tex.width; i++) {
    for(int j = step; j < tex.height; j += step) {
      tex.pixels[i + j * tex.width] = 0xff << 0x16;
    }
  }
  tex.updatePixels();
  return tex;
}

// ----------------------------------------

interface Renderable {
  void render();
}

// ----------------------------------------

abstract class RenderHelper implements Renderable {
  private final int NUM_TEXTURE_COORDS_DEFAULT = 4;

  protected final int DIFFUSE_COLOR   = 0x7f;
  protected final PVector LIGHT_DIRECTION = new PVector(0, 0, -1);
  protected final PVector ZERO_VECTOR     = new PVector(0, 0, 0);

  protected PVector eyePoint = new PVector(.5 * width, 
                                           .5 * height, 
                                           .5 * height / tan(PI / 6.0));
  protected PVector _origin = new PVector();
  protected PVector _normal = new PVector();
  protected PImage  _originalTexture;

  protected PVector[] _worldVertices;
  protected PVector[] _localVertices;
  protected PVector[] _originalTextureCoords;

  private PImage  _texture;
  private boolean _isBack = false;
  
  public abstract void render();
  
  public void setEyePoint(PVector p) {
    if(p != null) {
      eyePoint.set(p);
    } else {
      setEyePoint(0, 0, 0);
    }
  }
  public void setEyePoint(float x, float y, float z) {
    eyePoint.set(x, y, z);
  }
  
  protected void initVertices(int numVertices) {
    if(numVertices < 1) return;
    
    _worldVertices = new PVector[numVertices];
    _localVertices = new PVector[numVertices];
    
    for(int i = 0; i < numVertices; i++) {
      _worldVertices[i] = new PVector();
      _localVertices[i] = new PVector();
    }
  }
  
  protected void initTextureCoords() {
    _originalTextureCoords = new PVector[NUM_TEXTURE_COORDS_DEFAULT];
    for(int i = 0; i < _originalTextureCoords.length; i++) {
      _originalTextureCoords[i] = new PVector(i < NUM_TEXTURE_COORDS_DEFAULT / 2        ? 0 : 1, 
                                      i % (NUM_TEXTURE_COORDS_DEFAULT - 1) == 0 ? 0 : 1);
    }
  }
  
  protected void initTextureCoords(int numVertices) {
    _originalTextureCoords = new PVector[numVertices];
    
    for(int i = 0; i < numVertices; i++) {
      _originalTextureCoords[i] = new PVector();
    }
  }
  
  protected PVector[] updateWorldVertices(PVector[] localVertices, PVector[] destWorldVertices) {
    for(int i = 0; i < destWorldVertices.length; i++) {
      updateWorldVertex(localVertices[i], destWorldVertices[i]);
    }
    return destWorldVertices;
  }
  
  protected PVector[] updateWorldVertices() {
    return updateWorldVertices(_localVertices, _worldVertices);
  }
  
  protected PVector updateWorldVertex(PVector localVertex, PVector destWorldVertex) {
    destWorldVertex.set(
      modelX(localVertex.x, localVertex.y, localVertex.z), 
      modelY(localVertex.x, localVertex.y, localVertex.z),
      modelZ(localVertex.x, localVertex.y, localVertex.z));      
    return destWorldVertex;
  }
  
  protected PVector updateWorldVertex(PVector localVertex) {
    return new PVector (
      modelX(localVertex.x, localVertex.y, localVertex.z), 
      modelY(localVertex.x, localVertex.y, localVertex.z),
      modelZ(localVertex.x, localVertex.y, localVertex.z));      
  }
  
  protected PVector updateOrigin(PVector center) {
    updateWorldVertex(center, _origin);
    return _origin;
  }
  
  protected PVector updateOrigin() {
    return updateOrigin(ZERO_VECTOR);
  }
  
  protected PVector updateNormalVector(PVector v1, PVector v2) {
    _normal.set(v1.cross(v2));
    _normal.normalize();
    return _normal;
  }
  
  private PVector _ = new PVector();
  protected int getDefaultTintColor() {
    subVec(_origin, eyePoint, _);
    _isBack = 0 < _normal.dot(_);
    float arg = (_isBack ? 1.0 : -1.0) * _normal.dot(LIGHT_DIRECTION);
    return (int)(arg * (0xff - DIFFUSE_COLOR) + DIFFUSE_COLOR);
  }
  
  protected void subVec(PVector p1, PVector p2, PVector dest) {
    dest.set(p1.x - p2.x, p1.y - p2.y, p1.z - p2.z);
  }
  

  protected void renderWithoutShade(PVector[] worldVertices, PVector[] textureCoords) {
    if(!checkArgsBeforeRender(_originalTexture, 
                              worldVertices, 
                              textureCoords)) return;
    getDefaultTintColor();
    if(_isBack) return;
    
    if(!setupRenderTexture()) return;
    _texture.resize(_texture.width, _texture.height);
    renderMain(0xff, _texture, worldVertices, textureCoords);
  }
  
  protected void renderWithShade(PVector[] worldVertices, PVector[] textureCoords) {
    if(!checkArgsBeforeRender(_originalTexture, 
                              worldVertices, 
                              textureCoords)) return;

    int tintColor = getDefaultTintColor();
    if(_isBack) return;
    renderMain(tintColor, _originalTexture, worldVertices, textureCoords);
  }

  private boolean checkArgsBeforeRender(PImage originalTexture, PVector[] worldVertices, PVector[] textureCoords) {
    if(_originalTexture == null || worldVertices == null || textureCoords == null) return false;
    if(textureCoords.length < worldVertices.length) return false;
    if(_originalTexture.get(0, 0) == 0) return false;
    return true;
  }
  
  private boolean setupRenderTexture() {
    // 毎回 createImage しないとうまくレンダリングされない...    
    _texture = createImage(_originalTexture.width, _originalTexture.height, RGB);
    
    updateTexture(_originalTexture, _texture);
    return !(_texture == null || _texture.get(0, 0) == 0);
  }
  
  protected void updateTexture(PImage originalTexture, PImage destUpdatedTexture) {
    destUpdatedTexture.loadPixels();
    for(int i = 0; i < originalTexture.pixels.length; i++) {
      destUpdatedTexture.pixels[i] = originalTexture.pixels[i];
    }
    destUpdatedTexture.updatePixels();
  }
  
  private void renderMain(int tintColor, PImage textureImage, PVector[] worldVertices, PVector[] textureCoords) {
    pushMatrix();
      resetMatrix();
      camera();
      noLights();
      beginShape();
        textureMode(NORMAL);
        texture(textureImage);
        tint(tintColor);
        for(int i = 0; i < worldVertices.length; i++) {
          vertex(worldVertices[i].x, worldVertices[i].y, worldVertices[i].z, 
                 textureCoords[i].x, textureCoords[i].y);
        }
      endShape(CLOSE);
    popMatrix();    
  }
  
  protected void renderWithShade() {
    renderWithShade(_worldVertices, _originalTextureCoords);
  }
  
  protected void renderWithoutShade() {
    renderWithoutShade(_worldVertices, _originalTextureCoords);
  }
}

// ----------------------------------------

class BoxWithTexture extends RenderHelper {
  protected final int NUM_VERTICES    = 8;
  protected final int NUM_PLANES      = 6;
  protected final int NUM_SIDE_PLANES = 4;
  protected final int NUM_VERTICES_PER_PLANE = 4;
  
  protected float _width;
  protected float _height;
  protected float _depth;
  
  protected PVector[]   _centers = new PVector[NUM_PLANES];
  protected PVector[][] _surface = new PVector[NUM_PLANES][NUM_VERTICES_PER_PLANE];  
  
  public BoxWithTexture(float size, PImage tex) {
    this(size, size, size, tex);
  }
  
  public BoxWithTexture(float w, float h, float d, PImage tex) {
    _width   = w;
    _height  = h;
    _depth   = d;
    _originalTexture = tex;  

    setupSurface();
  }
  
  private void setupSurface() {
    float halfWidth  = .5 * _width;
    float halfHeight = .5 * _height;
    float halfDepth  = .5 * _depth;
    
    initTextureCoords();
    initVertices(NUM_VERTICES);
    for(int i = 0; i < NUM_VERTICES; i++) {
      int j = i < NUM_VERTICES_PER_PLANE ? 
                i : i - NUM_VERTICES_PER_PLANE;
                
      _localVertices[i].set(j % 3 == 0 ? -halfWidth  : halfWidth, 
                            i < 4      ? -halfHeight : halfHeight,
                            i % 4 < 2  ? -halfDepth  : halfDepth);
    }
    
    setupSide(halfWidth, halfDepth);
    setupTopAndBottom(halfHeight);

  }
  
  private void setupSide(float halfWidth, float halfDepth) {
    for(int i = 0; i < NUM_SIDE_PLANES; i++) {
      float _x = halfWidth * (i % 2 == 0 ? 0 : i < 2 ?  1 : -1);
      float _z = halfDepth * (i % 2 != 0 ? 0 : i < 2 ? -1 :  1);
      _centers[i] = new PVector(_x, 0, _z);

      for(int j = 0; j < NUM_VERTICES_PER_PLANE; j++) {        
        int surplus = j % (NUM_VERTICES_PER_PLANE - 1);
        int index = surplus != 0 ? 
                    (i + surplus + (NUM_VERTICES_PER_PLANE - 1)) % 
                      NUM_VERTICES_PER_PLANE + 
                        NUM_VERTICES_PER_PLANE :
                    (i + (j < NUM_VERTICES_PER_PLANE / 2 ? 0 : 1)) % 
                      NUM_VERTICES_PER_PLANE;
        _surface[i][j] = _worldVertices[index];
      }
    }
  }
  
  private void setupTopAndBottom(float halfHeight) {
    for(int i = NUM_SIDE_PLANES; i < _centers.length; i++) {
      float _y = halfHeight * (i == NUM_SIDE_PLANES ? -1 : 1);
      _centers[i] = new PVector(0, _y, 0);
      
      for(int j = 0; j < NUM_VERTICES_PER_PLANE; j++) {        
        int index = i == NUM_SIDE_PLANES ? j : NUM_VERTICES - (j + 1);
        _surface[i][j] = _worldVertices[index];
      } 
    }
  }
  
  public void render() {
    updateWorldVertices();
    for(int i = 0; i < _surface.length; i++) {
      updateOrigin(_centers[i]);       
      updateNormalVector(PVector.sub(_surface[i][1], _surface[i][0]), 
                         PVector.sub(_surface[i][3], _surface[i][0]));
      renderWithShade(_surface[i], _originalTextureCoords);
    }
  }
}

// ----------------------------------------

class BumpMappedPlane extends RenderHelper { 
  private final int NUM_VERTICES = 4;

  private float  _width;
  private float  _height;
  private PImage _heightMap;
  private PVector[][] _normalMap; // 法線マップ
  
  public BumpMappedPlane(float w, float h, PImage tex, PImage hMap) {
    _width   = w;
    _height  = h;
    
    _originalTexture = tex;  
    _heightMap       = hMap;

    float halfWidth  = .5 * _width;
    float halfHeight = .5 * _height;
    
    initTextureCoords();
    initVertices(NUM_VERTICES);
    for(int i = 0; i < NUM_VERTICES; i++) {
      _localVertices[i].set(i < 2      ? -halfWidth  : halfWidth, 
                            i % 3 == 0 ? -halfHeight : halfHeight, 0);
    }
  }
  
  PVector _worldNormal = new PVector();
  PImage  _dummyTexture;
  
  public void render() {
    if(_originalTexture.get(0, 0) != 0) {
      if (_normalMap == null) {
        _normalMap = createNormalMap(_heightMap);
      }
    }

    updateOrigin();
    updateWorldVertices();
    updateNormalVector(PVector.sub(_worldVertices[1], _worldVertices[0]), 
                       PVector.sub(_worldVertices[3], _worldVertices[0]));
    renderWithoutShade();
  }
  
  protected PVector zeroVec = new PVector();
  
  protected void updateTexture(PImage originalTexture, PImage destUpdatedTexture) {
    destUpdatedTexture.loadPixels();
    int imgWidth = destUpdatedTexture.width;

    for(int i = 0; i < _normalMap.length; i++) {
      for(int j = 0; j < _normalMap[0].length; j++) {
        updateWorldVertex(_normalMap[i][j], _worldNormal);
        _worldNormal.sub(_origin);
        float arg = _worldNormal.dot(LIGHT_DIRECTION);
        
        float coef = (arg * (0xff - DIFFUSE_COLOR) / 0xff) + (DIFFUSE_COLOR / 0xff);
        int originalColor = originalTexture.pixels[j * imgWidth + i];
        int b = (int)(coef * (originalColor         & 0xff));
        int g = (int)(coef * (originalColor >>  0x8 & 0xff));
        int r = (int)(coef * (originalColor >> 0x10 & 0xff));
        
        destUpdatedTexture.pixels[j * imgWidth + i] = 0xff << 0x18 | r << 0x10 | g << 0x8 | b;
      }
    }
    destUpdatedTexture.updatePixels();
  }
  
  private float dU(PImage heightMap, int i, int j) {
    if(i < 1) return dU(heightMap, 1, j);
    if(!(i < heightMap.width-1)) return dU(heightMap, heightMap.width - 2, j);

    return .5 * (getHeight(heightMap, i+1,j) - getHeight(heightMap, i-1,j));
  }
  
  private float dV(PImage heightMap, int i, int j) {
    if(j < 1) return dV(heightMap, i, 1);
    if(!(j < heightMap.height-1)) return dV(heightMap, i, heightMap.height - 2);

    return .5 * (getHeight(heightMap, i, j+1) - getHeight(heightMap, i,j-1));
  }
  
  private int getHeight(PImage heightMap, int i, int j) {
    return 0xff & heightMap.pixels[i + j * heightMap.width];
  }
  
  private PVector[][] createNormalMap(PImage heightMapImage) {
    int mapWidth  = heightMapImage.width;
    int mapHeight = heightMapImage.height;
    
    PVector[][] normalMap = new PVector[mapWidth][mapHeight];
    PVector v1 = new PVector();
    PVector v2 = new PVector();
    
    for(int i = 0; i < mapWidth; ++i) {
      for(int j = 0; j < mapHeight; ++j) {
                 
        v1.set(1.0, 0, dU(heightMapImage, i, j));
        v1.normalize();
        v2.set(0, 1.0, dV(heightMapImage, i, j));
        v2.normalize();

        normalMap[i][j] = v1.cross(v2);
        normalMap[i][j].normalize();
      }
    }
    return normalMap;
  }
}

// ----------------------------------------

class BumpMappedBox implements Renderable {
  private BumpMappedPlane[] _surface = new BumpMappedPlane[6];
  private float _size;
  
  BumpMappedBox(float boxSize, PImage tex, PImage hMap) {
    _size = boxSize;
    for(int i = 0; i < 6; i++) {
      _surface[i] = new BumpMappedPlane( _size, _size, tex, hMap);
    }
  }
 
  void render() {
    pushMatrix();
    for(int i = 0; i < 4; i++) {
      rotateY(i * HALF_PI);
      
      pushMatrix();
      translate(0, 0, -.5 * _size);
      _surface[i].render();
      popMatrix();
    }
    popMatrix();

    pushMatrix();
      rotateX(HALF_PI);
      for(int i = 4; i < 6; i++) {
        rotateX(i * PI);   
        pushMatrix();
          translate(0, 0, -.5 * _size);
          _surface[i].render();
        popMatrix();
      }
    popMatrix();
  }
}
<canvas width="200px" height="200px"></canvas>
body {
    background-color: #fff;
}
</style>
<script type="text/javascript">
    window.addEventListener('load',function() {
    var scripts = document.body.getElementsByTagName('script');
    var canvases = document.body.getElementsByTagName('canvas');
    new Processing(canvases[0],scripts[0].text);
}, false);
// Here prevent javascript in body from throwing error
</script>
<style>