4

While I was deriving expressions for perspective-correct linear interpolation on triangles, I reached the conclusion that the interpolation may be kept linear only if view-space $Z$ is available. However, computing view-space $Z$ requires nonlinear interpolation (it is a rational function based on my results). Is nonlinear interpolation performed in hardware to get perspective correct $Z$, or equivalently linear interpolation is performed on $\frac{1}{Z}$ but a division is required to get view-space $Z$ anyways? As far as I get it there is no way around that - a division is required per-pixel to get perspective-correct Z values - is that correct?

lightxbulb
  • 1,941
  • 1
  • 5
  • 14

1 Answers1

2

Yes, that's correct. Perspective-correct interpolation works by (for some quantity $u$ to be interpolated) calculating $u/z$ and $1/z$ at each vertex, linearly interpolating those values in screen space, then calculating $u = (u/z) / (1/z)$ at each sample point. This is done by the GPU hardware behind the scenes.

Nathan Reed
  • 24,302
  • 2
  • 63
  • 103
  • This seems to require a division/reciprocal for the interpolation of every element of every attribute. Isn't this more expensive at the end of the day, than doing it just for $z$ and then linearly interpolating (without division) the attributes without using any division/reciprocal? – lightxbulb Jul 12 '20 at 05:41
  • Sure, it's more expensive. But without it, you don't get perspective-correct interpolation, and anything with a texture on it will look all kinds of wrong. It's a necessary expense to pay. – Nathan Reed Jul 12 '20 at 05:57
  • I meant that performing the division per pixel attribute is more expensive. You can linearly interpolate $u$ if you know view-space $z$ to get perspective-correct interpolation. Only for view-space $z$ do you require a division. – lightxbulb Jul 12 '20 at 06:38
  • But you can't linearly interpolate $u$ itself; you must interpolate $u/z$, then cancel out the $z$ per pixel. Or it is not perspective-correct. For example, textures will appear to shift and bend over a surface as you move the camera around, if the texture coordinates are not interpolated perspective-correctly. _All_ vertex attributes require perspective correction if the geometry is to look correct. – Nathan Reed Jul 12 '20 at 19:43
  • To put it another way: each attribute needs to interpolate along its own rational function, like $((1-s)u_1 z_1 + s u_2 z_2) / ((1-s)z_1^{-1} + sz_2^{-1})$ (for $s$ a screen-space interpolant). – Nathan Reed Jul 12 '20 at 19:46
  • 1
    Hmm, maybe I see what you mean now. You could calculate $(1-s)z_1^{-1}/((1-s)z_1^{-1} + sz_2^{-1})$ once per pixel (and another one for the other screen-space coordinate), and use those scalars to interpolate each of the attributes. Yeah, that sounds like it works, so maybe that's what they actually do under the hood. I'm not sure how it's implemented exactly. – Nathan Reed Jul 12 '20 at 20:01
  • Yeah, in my result I got that I only need to know perspective-correct $Z$ in view-space, then I can interpolate $u$ linearly in a perspective-correct fashion. I didn't write it out explicitly, but it was clear that it is a linear function. Thank you for confirming that it's supposedly correct. – lightxbulb Jul 12 '20 at 20:10