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

CC BY-SA 4.0
2020-07-12T05:41:52.273Z
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
CC BY-SA 4.0
2020-07-12T05:57:19.397Z
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
CC BY-SA 4.0
2020-07-12T06:38:41.187Z
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
CC BY-SA 4.0
2020-07-12T19:43:05.737Z
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
CC BY-SA 4.0
2020-07-12T19:46:53.673Z
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
CC BY-SA 4.0
2020-07-12T20:01:06.667Z
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
CC BY-SA 4.0
2020-07-12T20:10:25.237Z
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
CC BY-SA 4.0
2020-07-11T17:56:21.870Z
2020-07-11T17:56:21.870Z
Nathan Reed
<p>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 <span class="math-container">$Z$</span> is available. However, computing view-space <span class="math-container">$Z$</span> requires nonlinear interpolation (it is a rational function based on my results). Is nonlinear interpolation performed in hardware to get perspective correct <span class="math-container">$Z$</span>, or equivalently linear interpolation is performed on <span class="math-container">$\frac{1}{Z}$</span> but a division is required to get view-space <span class="math-container">$Z$</span> 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?</p>

<projections><perspective><interpolation><z-buffer>
Perspective correct interpolation z-buffer
lightxbulb
# Perspective correct interpolation z-buffer

(Asked by: username_0 on 2020-07-07)

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?

**Tags:** projections, perspective, interpolation, z-buffer


---

## 1 answers

### Answer by username_1 on 2020-07-11. Score: 5 | Accepted answer

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.

> **Comments:**
> **username_0**: 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?  
> **username_1**: 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.  
> **username_0**: 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.  
> **username_1**: 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.  
> **username_1**: 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).  
> **username_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.  
> **username_0**: 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.  

---

