Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Z value always 1 or -1 when using `glm::perspective`

I'm trying to teach myself the ways for 3D programming with OpenGL, however I am struggling with some things, especially projection matrices.

I defined some vertices for a cube and successfully handed them to my graphics processor. The cube goes from xyz -0.5 to xyz 0.5 respectively, which gets rendered fine.

To move it into my world coordinate system, I am using this model matrix:

auto model = glm::mat4(
    glm::vec4(1, 0, 0, 0),
    glm::vec4(0, 1, 0, 0),
    glm::vec4(0, 0, 1, 0),
    glm::vec4(0, 0, 0, 1)
);
model = glm::translate(model, glm::vec3(0.f, 0.f, 495.f));
model = glm::scale(model, glm::vec3(100.f, 100.f, 100.f));

This successfully moves my cube to (-50, -50, 445) -> (50, 50, 545) so its now centered in the 200x200x1000 world coordinates I defined for myself.

My camera / view matrix is

auto view = glm::lookAt(
    glm::vec3(0.f, 0.f, 5.f),
    glm::vec3(0.f, 0.f, 0.f),
    glm::vec3(0.f, 1.f, 0.f)
);

which moves the cube slightly closer, changing the z coordinate to 440 and 540 respectively. I don't understand why this is happening but I guess it has something to do with glm expecting a right hand coordinate system while I am working with a left handed one? While this is not why I am posting this question, I would be happy if someone would clear it up for me.

Now to my actual problem: I am trying to make use of glm::perspective. I call it like this:

auto perspective = glm::perspective(glm::radians(55.f), 1.f, 0.f, 1000.f);

If I'm not mistaken, at a z value of 440 I can expect the clipping area to go from roughly -229 to 229, so I would expect that bottom right cube vertex at (-50,-50) is visible. I calculated this by drawing the frustum in 2D, when I noticed that I should be able to calculate the height of any distance to the camera using tan(alpha / 2) * distToCamera = maxVisibleCoordinate (working with a 1:1 aspect ratio). Is this a correct assumption? Here is my terrible drawing, maybe you can tell that I have a wrong understanding of something with it:

I hope you can see what I was trying to do

In the final step I am trying to get all this together in my vertex shader using

gl_Position = projection * view * model * vec4(pos.x, pos.y, pos.z, 1.0);

which yields a perfectly reasonable result for the x and y value but the z value is always -1 which is, as far as I know, just right for not being displayed.

For my front-bottom-left vertex of the cube (-0.5, -0.5, -0.5) the result is (-96.04, -96.04, -440, -440), normalized to (-0.218, -0.218, -1).

For my back-top-right vertex of the cube (0.5, 0.5, 0.5) the result is (96.04, 96.04, -550, -550), normalized to (0.218, 0.218, -1).

What am I getting wrong, that my z value is lost and just set to -1 instead? When playing around with the camera position, the best I can get is getting it to 1, which also results in an empty window and is definitely not what I would expect.

like image 319
Link64 Avatar asked Jan 25 '23 18:01

Link64


1 Answers

A projection matrix is like this:

enter image description here

In the picture, f is for zfar and n is for znear.

As you can see, if you put znear = 0, the term at the 4th column become zero, which is incorrect. Also, -(f+n)/(f-n) = -1, which is incorrect too.

So, the conclusion is, znear cannot be zero. It is usually a small value, for example, 0.1

like image 81
Amadeus Avatar answered Jan 31 '23 23:01

Amadeus