Creating a Depth Texture

How to 3D

Chapter 13: Shadows

Creating a Depth Texture

We need a place to store the map of depths nearest to the light source. That place is a special texture whose pixel format supports depth values rather than color tuples.

The following JavaScript allocates a blank depth texture using the same routines that we would use to create a color texture:

function reserveDepthTexture(width, height, unit = gl.TEXTURE0) {
  gl.activeTexture(unit);
  const texture = gl.createTexture();
  gl.bindTexture(gl.TEXTURE_2D, texture);
  gl.texImage2D(gl.TEXTURE_2D, 0, gl.DEPTH_COMPONENT32F, width, height, 0, gl.DEPTH_COMPONENT, gl.FLOAT, null);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
  return texture;
}
function reserveDepthTexture(width, height, unit = gl.TEXTURE0) {
  gl.activeTexture(unit);
  const texture = gl.createTexture();
  gl.bindTexture(gl.TEXTURE_2D, texture);
  gl.texImage2D(gl.TEXTURE_2D, 0, gl.DEPTH_COMPONENT32F, width, height, 0, gl.DEPTH_COMPONENT, gl.FLOAT, null);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
  return texture;
}

The pixel format is gl.DEPTH_COMPONENT32F, which means the graphics card will store each texel as a 4-byte float. Normally we only get 1 byte of precision per texture channel. The greater precision will make our shadows smoother.

Sadly, WebGL does not support linear interpolation of depth textures. The filter parameters must be set to gl.NEAREST, which means the shadows will be pixelated. That's bad news.

Unlike the textures we've created in the past, we don't have any depth data to upload. So, the last parameter to texImage2D is null. WebGL allocates the space for the texture in VRAM but does not copy any data into it.

← Shadow MappingFramebuffer Objects →