<p>Algebraically speaking, it's not too hard to modify <span class="math-container">$d$</span> in order to scale <span class="math-container">$z$</span>. If you want to scale <span class="math-container">$z$</span> by a factor of <span class="math-container">$c$</span>, giving <span class="math-container">$z' = cz$</span>, then
<span class="math-container">$$
\begin{aligned}
d' &amp;= a \frac{1}{z'} + b \\
&amp;= a \frac{1}{cz} + b \\
(d' - b)c &amp;= a \frac{1}{z} \\
&amp;= d - b \\
d' &amp;= \frac{d - b}{c} + b
\end{aligned}
$$</span>
In short, to scale <span class="math-container">$z$</span> by a factor of <span class="math-container">$c$</span>, you would take the depth value and subtract <span class="math-container">$b$</span>, scale by <span class="math-container">$1/c$</span>, then add <span class="math-container">$b$</span> back again.</p>
<p>Note that if you use a projection with reversed Z and an infinite far plane, then <span class="math-container">$b = 0$</span>, which simplifies this to just <span class="math-container">$d' = d/c$</span>.</p>

CC BY-SA 4.0
2021-04-12T13:01:57.103Z
Yeah, that seems to work. Unfortunately it did not solve the shimmering issue, but it seems that the shimmering related to the world position is now fixed and i have another problem elsewhere. I have added a video to the original post with the world position before i added your scaling.
André Ferreira
CC BY-SA 4.0
2021-04-10T17:38:43.773Z
2021-04-10T17:38:43.773Z
Nathan Reed
<p>I am currently porting the atmosphere algorithm used by the UE4 engine to my engine.</p>
<p>As the original algorithm from Bruneton is in Kilometers i had to adapt it to my engine which uses meters. Everything is working and its correctly scaled now but i am having some z precision issues on the horizon when drawing the fog. This, i believe, i due to the following math:</p>
<pre><code>float DepthBufferValue = texture(ViewDepthTexture, depthValueUV).r;
vec3 depthClipSpace = vec3(pixPos / vec2(gResolution) * vec2(2.0f) - vec2(1.0f), DepthBufferValue);
vec4 DepthBufferWorldPos = gInvViewProjMat * vec4(depthClipSpace, 1.0);
DepthBufferWorldPos /= DepthBufferWorldPos.w; // perspective division
DepthBufferWorldPos.xyz *= 0.001; 
</code></pre>
<p>Here, i am basically reading the depth texture, getting the real world position value and scaling it to be in KMs. Due to this scaling (and the inverse multiplication) i am getting some shimmering in the horizon (where the z distance is the greatest)</p>
<p>Since the depth equation is equal to:</p>
<pre><code> d = a * (1/z) + b 
</code></pre>
<p>(with a = near, b = far clip and z the distance from camera) is there any mathematical way to scale the DepthBufferValue to a value where the world position would be in kilometers?</p>
<p>In a more practical way, imagining that we have a World Position of (0, 1000, 0) and that gives us a DepthBufferValue of 0.998, can we scale that 0.998 value to the value that we would obtain if we had used the World Position (0, 1, 0) ? (Assuming of course the same near and far clips)</p>
<p>Many thanks!</p>
<p>Edit:
This is the DepthBufferWorldPos outputed to the screen:</p>
<p><a href="https://www.youtube.com/watch?v=kEaU72NWq8I" rel="nofollow noreferrer">https://www.youtube.com/watch?v=kEaU72NWq8I</a></p>

CC BY-SA 4.0
2021-04-10T14:02:25.493Z
Here is a link to an Nvidia blog on depth precision that might be helpful:https://developer.nvidia.com/content/depth-precision-visualized
pmw1234
<glsl><hlsl><depth-map>
Scale Sampled Depth Value
André Ferreira
# Scale Sampled Depth Value

(Asked by: username_0 on 2021-04-08)

I am currently porting the atmosphere algorithm used by the UE4 engine to my engine.

As the original algorithm from Bruneton is in Kilometers i had to adapt it to my engine which uses meters. Everything is working and its correctly scaled now but i am having some z precision issues on the horizon when drawing the fog. This, i believe, i due to the following math:

```
float DepthBufferValue = texture(ViewDepthTexture, depthValueUV).r;
vec3 depthClipSpace = vec3(pixPos / vec2(gResolution) * vec2(2.0f) - vec2(1.0f), DepthBufferValue);
vec4 DepthBufferWorldPos = gInvViewProjMat * vec4(depthClipSpace, 1.0);
DepthBufferWorldPos /= DepthBufferWorldPos.w; // perspective division
DepthBufferWorldPos.xyz *= 0.001; 

```

Here, i am basically reading the depth texture, getting the real world position value and scaling it to be in KMs. Due to this scaling (and the inverse multiplication) i am getting some shimmering in the horizon (where the z distance is the greatest)

Since the depth equation is equal to:

```
 d = a * (1/z) + b 

```

(with a = near, b = far clip and z the distance from camera) is there any mathematical way to scale the DepthBufferValue to a value where the world position would be in kilometers?

In a more practical way, imagining that we have a World Position of (0, 1000, 0) and that gives us a DepthBufferValue of 0.998, can we scale that 0.998 value to the value that we would obtain if we had used the World Position (0, 1, 0) ? (Assuming of course the same near and far clips)

Many thanks!

Edit:
This is the DepthBufferWorldPos outputed to the screen:

<https://www.youtube.com/watch?v=kEaU72NWq8I>

**Tags:** glsl, hlsl, depth-map

> **Comments:**
> **username_1**: Here is a link to an Nvidia blog on depth precision that might be helpful:https://developer.nvidia.com/content/depth-precision-visualized  

---

## 1 answers

### Answer by username_2 on 2021-04-10. Score: 0 | Accepted answer

Algebraically speaking, it's not too hard to modify $d$ in order to scale $z$. If you want to scale $z$ by a factor of $c$, giving $z' = cz$, then
$$
\begin{aligned}
d' &= a \frac{1}{z'} + b \\
&= a \frac{1}{cz} + b \\
(d' - b)c &= a \frac{1}{z} \\
&= d - b \\
d' &= \frac{d - b}{c} + b
\end{aligned}
$$
In short, to scale $z$ by a factor of $c$, you would take the depth value and subtract $b$, scale by $1/c$, then add $b$ back again.

Note that if you use a projection with reversed Z and an infinite far plane, then $b = 0$, which simplifies this to just $d' = d/c$.

> **Comments:**
> **username_0**: Yeah, that seems to work. Unfortunately it did not solve the shimmering issue, but it seems that the shimmering related to the world position is now fixed and i have another problem elsewhere. I have added a video to the original post with the world position before i added your scaling.  

---

