Reputation: 140
I want to calculate the impact of a mesh on the final render, that is, it's size in the viewport. For this, I try to get the projected position on the screen for each vertex. For example, a point rendered at center of the screen should return (0,0), in the upper right corner of the screen (1,1) and so on.
This is my code, stripped down to it's bare minimum, and based on about every
example code provided for glm::perspective
:
glm::mat4 Projection = glm::perspective(
glm::radians(45.0f),
800.0f/600.0f,
0.1f,
100.0f
);
glm::mat4 View = glm::lookAt(
glm::vec3(-10,0,3),
glm::vec3(0,0,3),
glm::vec3(0,0,1)
);
glm::mat4 MVP = Projection * View * glm::mat4(1.f);
for each (Vertex vert in *verts) {
glm::vec3 vertPos = vert.getPosition();
glm::vec4 screenPos = MVP * glm::vec4(vertPos, 1);
}
At this point I am stuck, since I don't know how to handle the resulting vector. I can't figure out the meaning of it's four values.
In my example setup, the point (-1,-1,2)
(see red circle on first picture) is roughly rendered at pixel (480,380)
.
The screenPos of said point returns (1.81, -2.41, 10.82, 11.0)
(rounded values). I can't proceed with those results as long as I can't understand them. Does anyone know what the x
,y
,z
and w
values say about my point exactly?
I appreciate any help or hint, working too long on this issue.
PS: I know there are a lot of questions covering glm::perspective
, but I don't want
to render the mesh. I don't even want to include GLSL
. It is just about the calculation.
Upvotes: 1
Views: 1089
Reputation: 3043
You can divide screenPos
by it's w
component and you'll get your screen-space coordinates.
screenPos = screenPos / screenPos.w;
This is perspective division. This division transforms camera frustum to a post-projection cube. After it screenPos.xy
will become screen space coordinates and screenPos.z
- normalized depth (0.0 - near plane, 1.0 - far plane, and, btw, it's not linear).
But it'll be correct only for vertices with positive screenPos.w
(i.e. for vertices before camera).
Upvotes: 1