I've noted that if in the perspective camera I put near plane to a low number like 0.000001 and far plane to 1000 my render has some problems, like strange depth artifacts (see images below) or division by zero during the unprojection procedure.

I'm not very skilled in math but there should be something strange because if I put near plane at 0.1 everything is working as expected.

Is there any mathematical limitation to the near plane value I'm not aware of?

I'm on WebGL with JavaScript (I'm not using Three.js; my question is related to the math, not to a particular framework). If it matters, I'm using Float32Array to store matrices, and I'm using those libraries to do the math:

In particular the division by zero happens here:

function project (out, vec, m) {
  var x = vec[0],
    y = vec[1],
    z = vec[2],
    a00 = m[0], a01 = m[1], a02 = m[2], a03 = m[3],
    a10 = m[4], a11 = m[5], a12 = m[6], a13 = m[7],
    a20 = m[8], a21 = m[9], a22 = m[10], a23 = m[11],
    a30 = m[12], a31 = m[13], a32 = m[14], a33 = m[15]

  var lw = 1 / (x * a03 + y * a13 + z * a23 + a33)

  out[0] = (x * a00 + y * a10 + z * a20 + a30) * lw
  out[1] = (x * a01 + y * a11 + z * a21 + a31) * lw
  out[2] = (x * a02 + y * a12 + z * a22 + a32) * lw
  return out

enter image description here enter image description here


1 Answer 1


The GPU uses more bits to store distances closer to the camera than ones farther, and this becomes worse the closer you set the near plane to 0. With a near plane of 0.01 the error between the stored distance and actual distance at 1000 units becomes 100 unit.

What happens basically is that different distances start to have the same value in the depfh buffer, so the GPU can't decide which one goes on top, and z-fighting happens.

You should always set the near plane to the largest value you're comfortable with.

  • \$\begingroup\$ Ok clear thankes @bálint But how to explain the unproject thing? it is nothing related with the gpu, I'm doing the apply of the inverse projection * view in the cpu \$\endgroup\$
    – nkint
    Jun 1, 2017 at 14:18
  • \$\begingroup\$ @nkint Debug the values of a03, a13, a23, a33, x, y and z, see how it becomes 0. Maybe one of them is undefined or null. \$\endgroup\$
    – Bálint
    Jun 1, 2017 at 14:46
  • \$\begingroup\$ no they are ok - nothing is undefined or null \$\endgroup\$
    – nkint
    Jun 1, 2017 at 14:59
  • \$\begingroup\$ @nkint what did you get when you printed them? \$\endgroup\$
    – Bálint
    Jun 1, 2017 at 15:17

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .