OK, I'll admit, the math on a perspective projection matrix is quite hairy for me, but I get the general gist of it: morph the object so that it looks... perspective-ish.

But there is one thing which I really don't get it: if I send the textcoord for a vertex to a "smooth out fTexCoord" varying variable, how is that interpolation affected by either the clip space coordinates (x,y,z,w), where w actually has a value !=1 or a naive implementation without the w component? Is the interpolation happening in clip space?

I mean, I understand WHY half a quad texture looks squished at the diagonal if looked from a perspective type of camera, because one triangle is morphed and it's texture coordinates just fill a smaller area than the triangle which is closer to the camera.

What I don't understand is how clip space avoids thats. I mean, isn't the fTexCoord just interpolated based on the distance against the tree verts? And if I can give naive gl_Position values, and OK clip space gl_Position values, and they occupy the same space in... space, how can the perspective correct texture mapping help that?


Perspective-correct interpolation doesn't affect the vertices; it pushes around the stuff between the vertices. Ordinary interpolation is linear in screen space: it treats the triangle as being squashed flat onto the screen, so every pixel represents the same size of UV area, and the UVs for each pixel advance at a constant rate as you move along the triangle from one vertex to another.

This is not what you want because if the triangle is projected from 3D, then pixels on the farther-away parts of the triangle represent a larger UV area than closer pixels, and as you move from one vertex to another the UVs should advance at a nonlinear rate, changing quickly for the closer pixels and more slowly for the farther pixels. See this image:

enter image description here

Note how the vertical grid lines are evenly spaced on the left (the original texture) but not evenly spaced on the right (perspective warp) - their spacing changes from wide to narrow as you move horizontally across the image.

Perspective-correct interpolation takes into account the 3D depth of each vertex of the triangle in order to accomplish this nonlinear interpolation. You might think of it conceptually as interpolating linearly in world space or in clip space (the two are linearly related via the projection matrix, so linear in one is linear in the other). In actual fact, the interpolation is being done by calculating u/w, v/w, and 1/w at each vertex (w being from the vertex's clip-space position), then interpolating those three values linearly in screen space, then calculating u = (u/w) / (1/w) and v = (v/w) / (1/w) at each pixel. If you work out the math, it turns out this is equivalent to interpolating linearly in world space / clip space.

  • \$\begingroup\$ the update u = (u/w)/(1/w) doesn't do anything. If you simplify the right side, you just get the left side. Same for v. \$\endgroup\$ – Arne Oct 22 '15 at 9:59
  • \$\begingroup\$ @Arne The point is that you interpolate u/w and 1/w linearly in screen space, then use them to calculate u per pixel. That's how you get u to be interpolated with perspective correction. \$\endgroup\$ – Nathan Reed Oct 22 '15 at 17:16
  • \$\begingroup\$ ok I found some resources on the internet, and understood this part. It's not that easy to understand and even other sources use the same notation. Still I think you should really concider weather u = (u/w) / (1/w) is what you want to keep in this document. Maybe you want to indicate, that you mean two different u and two different w. \$\endgroup\$ – Arne Oct 22 '15 at 21:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.