Vulkan View Depth from Faramebuffer Depth

Matthew Wellings 18-Nov-2016

This note gives the mathematical derivation of the equation that recovers view space depth in the fragment shaders of the blog post Depth Peeling Pseudo-Volumetric Rendering.

$\left[\begin{array}{cccc}1& 0& 0& 0\\ 0& -1& 0& 0\\ 0& 0& \frac{1}{2}& \frac{1}{2}\\ 0& 0& 0& 1\end{array}\right]$ $\left[\begin{array}{cccc}\frac{2n}{r-l}& 0& \frac{r+l}{r-l}& 0\\ 0& \frac{2n}{t-b}& \frac{t+b}{t-b}& 0\\ 0& 0& \frac{-\left(f+n\right)}{f-n}& -\frac{2nf}{f-n}\\ 0& 0& -1& 0\end{array}\right]$ = $\left[\begin{array}{cccc}\frac{2n}{r-l}& 0& \frac{r+l}{r-l}& 0\\ 0& \frac{-2n}{t-b}& -\frac{t+b}{t-b}& 0\\ 0& 0& -\frac{2nf}{2\left(f-n\right)}& -\frac{nf}{f-n}\\ 0& 0& -1& 0\end{array}\right]$

This resulting matrix is then effectively pre-multiplied by the view space coordinates to give clip space:
$\left[\begin{array}{c}{x}_{c}\\ {y}_{c}\\ {z}_{c}\\ {w}_{c}\end{array}\right]=\left[\begin{array}{cccc}\frac{2n}{r-l}& 0& \frac{r+l}{r-l}& 0\\ 0& \frac{-2n}{t-b}& -\frac{t+b}{t-b}& 0\\ 0& 0& -\frac{2nf}{2\left(f-n\right)}& -\frac{nf}{f-n}\\ 0& 0& -1& 0\end{array}\right]\left[\begin{array}{c}{x}_{v}\\ {x}_{v}\\ {z}_{v}\\ 1\end{array}\right]$

This leads to the following equations for the view space to homogeneous clip space conversion:
${x}_{c}={x}_{v}\left(\frac{2n}{r-l}\right)+{x}_{v}\left(\frac{r+l}{r-l}\right)$
${y}_{c}={y}_{v}\left(\frac{-2n}{t-b}\right)+{y}_{v}\left(\frac{t+b}{t-b}\right)$
${z}_{c}={z}_{v}\left(-\left(\frac{f+n}{2\left(f-n\right)}\right)-\frac{1}{2}\right)-\frac{nf}{f-n}$
${w}_{c}=-{z}_{v}$

After the conversion to Euclidean NDC space the equation for ${z}_{c}$ becomes:
${z}_{d}=\frac{{z}_{v}}{-{z}_{v}}\left(-\left(\frac{f+n}{2\left(f-n\right)}\right)-\frac{1}{2}\right)-\frac{1}{-{z}_{v}}\frac{nf}{f-n}$
or
${z}_{d}=\frac{f+n}{2\left(f-n\right)}+\frac{1}{2}+\frac{1}{{z}_{v}}\frac{nf}{f-n}$

Then after applying the conversion to window coordinates the transformation remains the same (if you have your minDepth and maxDepth to 0 and 1 respectively):
${z}_{f}=\frac{f+n}{2\left(f-n\right)}+\frac{1}{2}+\frac{1}{{z}_{v}}\frac{nf}{f-n}$

Rearranging for ${z}_{v}$ this becomes:
${z}_{v}={\left({z}_{f}-\left(\frac{f+n}{2\left(f-n\right)}+\frac{1}{2}\right)}{\frac{nf}{f-n}}\right)}^{-1}$

The terms $\frac{f+n}{2\left(f-n\right)}+\frac{1}{2}$ and $\frac{nf}{f-n}$ are both constant within a shader with fixed projection matrix allowing us to simplify the equation to be resolved in the shader by taking $a=\frac{nf}{f-n}$ and $b=\frac{f+n}{2\left(f-n\right)}+\frac{1}{2}$ to give ${z}_{v}=a}{\left({z}_{f}-b\right)}$