Paltoquet
Paltoquet

Reputation: 1234

Project Points on near plane using NDC space

I have severals pairs of points in world space each pair have a different depth. I want to project those points on the near plane of the view frustrum, then recompute their new world position.

note: I want to keep the perspective effect

To do so, I convert the point's location in NDC space. I think that each pair of points on NDC space with the same z value lie on the same plane, parallel to the view direction. So if I set their z value to -1, they should lie on the near plane.

Now that I have thoose new NDC locations I need their world position, I lost the w component by changing the depth, I need to recompute it.

I found this link: unproject ndc

which said that:

wclip * inverse(mvp) * vec4(ndc.xyz, 1.0f) = 1.0f
wclip = 1.0f / (inverse(mvp) * vec4(ndc.xyz, 1.0f))

my full code:

glm::vec4 homogeneousClipSpaceLeft  = mvp * leftAnchor;
glm::vec4 homogeneousClipSpaceRight = mvp * rightAnchor;

glm::vec3 ndc_left  = homogeneousClipSpaceLeft.xyz() / homogeneousClipSpaceLeft.w;
glm::vec3 ndc_right = homogeneousClipSpaceRight.xyz() / homogeneousClipSpaceRight.w;

ndc_left.z  = -1.0f;
ndc_right.z = -1.0f;

float clipWLeft  = (1.0f / (inverseMVP * glm::vec4(ndc_left, 1.0f)).w);
float clipWRight = (1.0f / (inverseMVP * glm::vec4(ndc_right, 1.0f)).w);

glm::vec3 worldPositionLeft  = clipWLeft * inverseMVP * (glm::vec4(ndc_left, 1.0f));
glm::vec3 worldPositionRight = clipWRight * inverseMVP * (glm::vec4(ndc_right, 1.0f));

It should work in practice but i get weird result, I start with 2 points in world space:

left world position:  -116.463 15.6386 -167.327
right world position: 271.014 15.6386 -167.327
left NDC position: -0.59719 0.0790622 -1
right NDC position: 0.722784 0.0790622 -1
final left position:  31.4092 -9.22973 1251.16
final right position: 31.6823 -9.22981 1251.17
mvp
4.83644 0 0 0
0 4.51071 0 0
0 0 -1.0002 -1
-284.584 41.706 1250.66 1252.41

Am I doing something wrong ?

Would you recommend this way to project pair of points to the near plane, with perspective ?

Upvotes: 1

Views: 964

Answers (1)

Rabbid76
Rabbid76

Reputation: 210877

If glm::vec3 ndc_left and glm::vec3 ndc_right are normalized device coordiantes, then the following projects the coordinates to the near plane in normaized device space:

ndc_left.z  = -1.0f;
ndc_right.z = -1.0f;

If you want to get the model positon of a point in normalized device space in Cartesian coordinates, then you have to transform the point by the invers model view projection matrix and to devide the x, y and z component by the w component of the result. Not the transfomation by inverseMVP gives a Homogeneous coordinate:

glm::vec4 wlh = inverseMVP * glm::vec4(ndc_left, 1.0f);
glm::vec4 wrh = inverseMVP * glm::vec4(ndc_right, 1.0f);

glm::vec3 worldPositionLeft  = glm::vec3( wlh.x, wlh.y, wlh.z ) / wlh.w;
glm::vec3 worldPositionRight = glm::vec3( wrh.x, wrh.y, wrh.z ) / wrh.w;


Note, that the OpenGL Mathematics (GLM) library provides operations vor "unproject". See glm::unProject.

Upvotes: 1

Related Questions