Problems with projection and\or z-coordinate

I am struggling with some simple and yet hard problem, and need some help…

Trying to render this simple scene.

White rectangle has Z value of 0.001, while green looking triangles have Z value of 0, so if i correctly understood opengl coordinate system white rectangle should be closer to the came than grass.

What i am doing wrong here? If i change the order of object creation, e.g. white rectangle last - everything works correctly, but i assume this kind of things should be handled without manual sorting on GPU itself?

Projection is created like this:

    glm::mat4 projection = glm::perspective(1.f, 1.f, 0.0f, 25.0f);
    glm::mat4 model = glm::mat4(1.0f);

    glm::vec3 cameraPosition = glm::vec3(0, 0.5, 1);
    glm::vec3 cameraLooksAt = glm::vec3(0, 0.5, 0);
    glm::vec3 cameraHead = glm::vec3(0, 1, 0);

    glm::mat4 mvp = projection * glm::lookAt(cameraPosition, cameraLooksAt, cameraHead) * model;

Everything regarding the camera works perfectly, i can rotate it, bring it closer to these objects or even flip, everything works logically to me and correctly, except this z-coordinate situation.

What i am doing wrong?

The near distance cannot be zero. That will usually result in all fragments having the same depth value, rendering depth testing meaningless; the test will either always fail or always pass, depending upon whether you’re using GL_LESS or GL_LEQUAL for the depth comparison function.

In general, the near distance should be as large as you can get away with. The smaller the near distance, the worse the depth resolution for most of the scene. As a fairly accurate approximation, the range of -Z values beyond N times the near distance get 1/N of the depth range. So if you have e.g. zNear=0.01, zFar=100, half the depth values are used for -Z values in the range [0.01, 0.02] and the other half for values in the range [0.02, 100]; similarly, 90% of the depth values are used for -Z values in the range [0.01,0.1] and the other 10% for values in the range [0.1,100]. The larger the near distance, the more even the distribution of depth values and the less likely you are to get “depth-fighting” artefacts.

Thx for answer, as long as depth value is calculated like so Fdepth = z − near / far − near, near with zero will just produce Fdepth equals to division of z and far value which is in my case

  1. for square = 0.001 / 25 = 0,00004
  2. for grass = 0 / 25 = 0

I’ve also changed far to 1 to produce larger fdepth results, but nothing changed =(

Also i am using these for my depth functions:

on window init:

glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);

inside loop:

glClearColor(COLOR_SKY_BLUE);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

Anyway i’ve tried to change all the values, and if z for white square is increasing - object itself is getting bigger, just like it should be, but it anyway draws incorrectly =(

Seems that i am doing something very wrong (

It isn’t. That calculation would be correct for an orthographic projection, but not for perspective. An orthographic projection can have a near distance which is zero or even negative; a perspective projection requires a near distance which is greater than zero.

glm::perspective behaves like gluPerspective (except that the field-of-view angle is in radians).

This gives:

Zclip = Zeye*(N+F)/(N-F)
Wclip = Weye*(2*F*N)/(N-F)
=> Zndc = Zclip/Wclip = -(Weye/Zeye)*(2*F*N)/(N-F)-(N+F)/(N-F)

Note that if N=0, this becomes -0/Zeye-1; Zndc=1 regardless of Zeye (if Zeye=0, Zndc=0/0 which is undefined).

Essentially, if Weye=1 (which is typical) you have Zndc=A-B/Zeye for constants A, B derived from N, F such that Zeye=-N => Zndc=-1 and Zeye=-F => Zndc=1. The relationship between eye-space Z and depth is reciprocal, with a vertical asymptote at Zeye=0. A small near distance results in the graph being dominated by the region close to the asymptote; small values of -Zeye result in large values of -1/Zeye which mean that the scale factor B above has to be small to fit the curve to the [-1,1] range. This results in poor depth resolution for most of the scene. The larger the near distance, the more linear the graph and the more even the depth resolution.

The far distance doesn’t matter much. You can use glm::infinitePerspective to set the far distance to infinity and it won’t have that much effect upon the depth resolution. In my previous post, I said:

If the far plane is at infinity, this “approximation” is exact. For a finite far distance, it’s still a very close approximation.

Thx again, a got it now! Just adjusted z-value for objects, near and far to get it larger than zero - and everything works as a charm !