# Perspective correct interpolation z-buffer

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?

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.
• 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 5:41
• 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 6: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
• 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