From 73a55a71c58cfd4625fdf546a6542e81346b40f1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fernando=20Garc=C3=ADa=20Li=C3=B1=C3=A1n?=
 <fernandogarcialinan@gmail.com>
Date: Wed, 31 Jan 2024 00:24:01 +0100
Subject: [PATCH] HDR: Implement a logarithmic depth buffer

---
 Compositor/HDR/hdr.xml                   |  6 +-
 Effects/HDR/atmos-aerial-perspective.eff |  1 +
 Effects/HDR/gbuffer-debug-depth.eff      |  1 -
 Effects/HDR/gtao.eff                     |  1 +
 Effects/HDR/shading-opaque.eff           |  1 +
 Effects/HDR/water-shading.eff            |  1 +
 Effects/chrome.eff                       |  9 +--
 Effects/cloud-impostor.eff               | 10 +--
 Effects/cloud-noctilucent.eff            | 10 +--
 Effects/cloud-static.eff                 | 10 +--
 Effects/cloud.eff                        | 10 +--
 Effects/lfeat.eff                        |  9 +--
 Effects/model-combined-transparent.eff   |  8 +--
 Effects/model-combined.eff               |  9 +--
 Effects/model-default.eff                |  9 +--
 Effects/model-pbr-transparent.eff        |  8 +--
 Effects/model-pbr.eff                    |  9 +--
 Effects/model-transparent.eff            |  8 +--
 Effects/model-wingflex.eff               | 13 ++--
 Effects/runway.eff                       |  9 +--
 Effects/skydome.eff                      |  8 +--
 Effects/terrain-default.eff              | 14 ++--
 Effects/text-default.eff                 |  8 +--
 Effects/tree.eff                         |  9 +--
 Effects/water.eff                        |  9 +--
 Effects/ws30.eff                         |  9 +--
 Shaders/HDR/3dcloud.frag                 |  5 ++
 Shaders/HDR/3dcloud.vert                 |  5 ++
 Shaders/HDR/cloud_static.vert            |  5 ++
 Shaders/HDR/debug_gbuffer_depth.frag     |  6 +-
 Shaders/HDR/gtao.frag                    | 12 ++--
 Shaders/HDR/logarithmic_depth.glsl       | 83 ++++++++++++++++++++++++
 Shaders/HDR/model_chrome.frag            | 10 ++-
 Shaders/HDR/model_chrome.vert            | 11 +++-
 Shaders/HDR/model_combined.frag          |  4 ++
 Shaders/HDR/model_combined.vert          |  5 ++
 Shaders/HDR/model_default.frag           |  4 ++
 Shaders/HDR/model_default.vert           |  5 ++
 Shaders/HDR/model_pbr.frag               |  4 ++
 Shaders/HDR/model_pbr.vert               |  5 ++
 Shaders/HDR/model_pbr_transparent.frag   |  4 ++
 Shaders/HDR/model_pbr_transparent.vert   |  4 ++
 Shaders/HDR/model_transparent.frag       | 28 ++++----
 Shaders/HDR/model_transparent.vert       | 34 ++++++----
 Shaders/HDR/pos_from_depth.glsl          | 31 +++------
 Shaders/HDR/shadows.glsl                 |  7 +-
 Shaders/HDR/terrain_default.frag         |  4 ++
 Shaders/HDR/terrain_default.vert         |  5 ++
 Shaders/HDR/terrain_lfeat.frag           |  4 ++
 Shaders/HDR/terrain_lfeat.vert           |  5 ++
 Shaders/HDR/terrain_runway.frag          |  4 ++
 Shaders/HDR/terrain_runway.vert          |  5 ++
 Shaders/HDR/text.frag                    |  4 ++
 Shaders/HDR/text.vert                    |  4 ++
 Shaders/HDR/tree.frag                    |  4 ++
 Shaders/HDR/tree.vert                    |  4 ++
 Shaders/HDR/water.frag                   |  5 ++
 Shaders/HDR/water.vert                   |  5 ++
 58 files changed, 375 insertions(+), 149 deletions(-)
 create mode 100644 Shaders/HDR/logarithmic_depth.glsl

diff --git a/Compositor/HDR/hdr.xml b/Compositor/HDR/hdr.xml
index 8c899bf1c..5113d0c43 100644
--- a/Compositor/HDR/hdr.xml
+++ b/Compositor/HDR/hdr.xml
@@ -15,7 +15,7 @@
       : G-Buffer 1 (RGBA8)     :             Base Color           : Metallic    :
       : G-Buffer 2 (RGBA8)     :     Material specific params     : Occlusion   :
       : G-Buffer 3 (R11G11B10) :             Emission             :      -      :
-      : Depth/Stencil          :       DEPTH32F_STENCIL8 (Reversed depth)       :
+      : Depth/Stencil          :      DEPTH24_STENCIL8 (Logarithmic depth)      :
       :........................:............:.........:...........:.............:
 
       Notes:
@@ -64,7 +64,7 @@
     <type>2d</type>
     <width>screen</width>
     <height>screen</height>
-    <format>depth32f-stencil8</format>
+    <format>depth24-stencil8</format>
   </buffer>
 
   <!-- HDR shading result -->
@@ -632,7 +632,7 @@
     <type>scene</type>
     <effect-scheme>hdr-geometry</effect-scheme>
     <clear-mask>depth stencil</clear-mask>
-    <clear-depth>0.0</clear-depth>
+    <clear-depth>1.0</clear-depth>
     <cull-mask>0xfffff7ff</cull-mask>
     <clustered-shading>
       <tile-size>128</tile-size>
diff --git a/Effects/HDR/atmos-aerial-perspective.eff b/Effects/HDR/atmos-aerial-perspective.eff
index eea58cc36..4e784c42a 100644
--- a/Effects/HDR/atmos-aerial-perspective.eff
+++ b/Effects/HDR/atmos-aerial-perspective.eff
@@ -52,6 +52,7 @@
         <vertex-shader>Shaders/HDR/quad.vert</vertex-shader>
         <fragment-shader>Shaders/HDR/atmos_aerial_perspective.frag</fragment-shader>
         <fragment-shader>Shaders/HDR/math.glsl</fragment-shader>
+        <fragment-shader>Shaders/HDR/logarithmic_depth.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/pos_from_depth.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/atmos.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/atmos_spectral.glsl</fragment-shader>
diff --git a/Effects/HDR/gbuffer-debug-depth.eff b/Effects/HDR/gbuffer-debug-depth.eff
index 44ae61554..e6978e4dc 100644
--- a/Effects/HDR/gbuffer-debug-depth.eff
+++ b/Effects/HDR/gbuffer-debug-depth.eff
@@ -6,7 +6,6 @@
       <program>
         <vertex-shader>Shaders/HDR/quad_matrix.vert</vertex-shader>
         <fragment-shader>Shaders/HDR/debug_gbuffer_depth.frag</fragment-shader>
-        <fragment-shader>Shaders/HDR/pos_from_depth.glsl</fragment-shader>
       </program>
       <uniform>
         <name>depth_tex</name>
diff --git a/Effects/HDR/gtao.eff b/Effects/HDR/gtao.eff
index e0e65f148..00440b00a 100644
--- a/Effects/HDR/gtao.eff
+++ b/Effects/HDR/gtao.eff
@@ -17,6 +17,7 @@
         <fragment-shader>Shaders/HDR/gtao.frag</fragment-shader>
         <fragment-shader>Shaders/HDR/math.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/normal_encoding.glsl</fragment-shader>
+        <fragment-shader>Shaders/HDR/logarithmic_depth.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/pos_from_depth.glsl</fragment-shader>
       </program>
       <uniform>
diff --git a/Effects/HDR/shading-opaque.eff b/Effects/HDR/shading-opaque.eff
index 8f4b13378..9cf9bfd48 100644
--- a/Effects/HDR/shading-opaque.eff
+++ b/Effects/HDR/shading-opaque.eff
@@ -61,6 +61,7 @@
         <fragment-shader>Shaders/HDR/shading_opaque.frag</fragment-shader>
         <fragment-shader>Shaders/HDR/gbuffer_unpack.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/normal_encoding.glsl</fragment-shader>
+        <fragment-shader>Shaders/HDR/logarithmic_depth.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/pos_from_depth.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/math.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/shading_opaque.glsl</fragment-shader>
diff --git a/Effects/HDR/water-shading.eff b/Effects/HDR/water-shading.eff
index e7dc3bf90..0d2614544 100644
--- a/Effects/HDR/water-shading.eff
+++ b/Effects/HDR/water-shading.eff
@@ -18,6 +18,7 @@
         <fragment-shader>Shaders/HDR/water_shading.frag</fragment-shader>
         <fragment-shader>Shaders/HDR/math.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/normal_encoding.glsl</fragment-shader>
+        <fragment-shader>Shaders/HDR/logarithmic_depth.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/pos_from_depth.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/sun.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/aerial_perspective.glsl</fragment-shader>
diff --git a/Effects/chrome.eff b/Effects/chrome.eff
index cdd2d8552..841550301 100644
--- a/Effects/chrome.eff
+++ b/Effects/chrome.eff
@@ -68,11 +68,10 @@
   <technique n="109">
     <scheme>hdr-geometry</scheme>
     <pass>
-      <!-- Reverse floating point depth buffer -->
       <depth>
-        <function>gequal</function>
-        <near>1.0</near>
-        <far>0.0</far>
+        <enabled>true</enabled>
+        <function>less</function>
+        <write-mask>true</write-mask>
       </depth>
       <stencil>
         <function>always</function>
@@ -84,7 +83,9 @@
       <cull-face><use>cull-face</use></cull-face>
       <program>
         <vertex-shader>Shaders/HDR/model_chrome.vert</vertex-shader>
+        <vertex-shader>Shaders/HDR/logarithmic_depth.glsl</vertex-shader>
         <fragment-shader>Shaders/HDR/model_chrome.frag</fragment-shader>
+        <fragment-shader>Shaders/HDR/logarithmic_depth.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/gbuffer_pack.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/normal_encoding.glsl</fragment-shader>
       </program>
diff --git a/Effects/cloud-impostor.eff b/Effects/cloud-impostor.eff
index 90293f610..9a8149791 100644
--- a/Effects/cloud-impostor.eff
+++ b/Effects/cloud-impostor.eff
@@ -288,11 +288,9 @@
   <technique n="129">
     <scheme>hdr-forward</scheme>
     <pass>
-      <!-- Reverse floating point depth buffer -->
       <depth>
-        <function>gequal</function>
-        <near>1.0</near>
-        <far>0.0</far>
+        <enabled>true</enabled>
+        <function>less</function>
         <write-mask>false</write-mask>
       </depth>
       <texture-unit>
@@ -307,11 +305,13 @@
       <program>
         <vertex-shader>Shaders/HDR/cloud_static.vert</vertex-shader>
         <vertex-shader>Shaders/HDR/cloud_static_common.vert</vertex-shader>
+        <vertex-shader>Shaders/HDR/logarithmic_depth.glsl</vertex-shader>
         <vertex-shader>Shaders/HDR/sun.glsl</vertex-shader>
         <vertex-shader>Shaders/HDR/aerial_perspective.glsl</vertex-shader>
         <vertex-shader>Shaders/HDR/atmos_spectral.glsl</vertex-shader>
         <fragment-shader>Shaders/HDR/3dcloud.frag</fragment-shader>
         <fragment-shader>Shaders/HDR/3dcloud_common.frag</fragment-shader>
+        <fragment-shader>Shaders/HDR/logarithmic_depth.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/aerial_perspective.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/exposure.glsl</fragment-shader>
       </program>
@@ -350,6 +350,8 @@
     <scheme>hdr-envmap</scheme>
     <pass>
       <depth>
+        <enabled>true</enabled>
+        <function>less</function>
         <write-mask>false</write-mask>
       </depth>
       <texture-unit>
diff --git a/Effects/cloud-noctilucent.eff b/Effects/cloud-noctilucent.eff
index b40427558..32370604d 100644
--- a/Effects/cloud-noctilucent.eff
+++ b/Effects/cloud-noctilucent.eff
@@ -208,11 +208,9 @@
   <technique n="129">
     <scheme>hdr-forward</scheme>
     <pass>
-      <!-- Reverse floating point depth buffer -->
       <depth>
-        <function>gequal</function>
-        <near>1.0</near>
-        <far>0.0</far>
+        <enabled>true</enabled>
+        <function>less</function>
         <write-mask>false</write-mask>
       </depth>
       <texture-unit>
@@ -227,11 +225,13 @@
       <program>
         <vertex-shader>Shaders/HDR/cloud_static.vert</vertex-shader>
         <vertex-shader>Shaders/HDR/cloud_static_common.vert</vertex-shader>
+        <vertex-shader>Shaders/HDR/logarithmic_depth.glsl</vertex-shader>
         <vertex-shader>Shaders/HDR/sun.glsl</vertex-shader>
         <vertex-shader>Shaders/HDR/aerial_perspective.glsl</vertex-shader>
         <vertex-shader>Shaders/HDR/atmos_spectral.glsl</vertex-shader>
         <fragment-shader>Shaders/HDR/3dcloud.frag</fragment-shader>
         <fragment-shader>Shaders/HDR/3dcloud_common.frag</fragment-shader>
+        <fragment-shader>Shaders/HDR/logarithmic_depth.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/aerial_perspective.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/exposure.glsl</fragment-shader>
       </program>
@@ -270,6 +270,8 @@
     <scheme>hdr-envmap</scheme>
     <pass>
       <depth>
+        <enabled>true</enabled>
+        <function>less</function>
         <write-mask>false</write-mask>
       </depth>
       <texture-unit>
diff --git a/Effects/cloud-static.eff b/Effects/cloud-static.eff
index 5f79c2c6a..ba667503f 100644
--- a/Effects/cloud-static.eff
+++ b/Effects/cloud-static.eff
@@ -416,11 +416,9 @@
   <technique n="129">
     <scheme>hdr-forward</scheme>
     <pass>
-      <!-- Reverse floating point depth buffer -->
       <depth>
-        <function>gequal</function>
-        <near>1.0</near>
-        <far>0.0</far>
+        <enabled>true</enabled>
+        <function>less</function>
         <write-mask>false</write-mask>
       </depth>
       <texture-unit>
@@ -435,11 +433,13 @@
       <program>
         <vertex-shader>Shaders/HDR/cloud_static.vert</vertex-shader>
         <vertex-shader>Shaders/HDR/cloud_static_common.vert</vertex-shader>
+        <vertex-shader>Shaders/HDR/logarithmic_depth.glsl</vertex-shader>
         <vertex-shader>Shaders/HDR/sun.glsl</vertex-shader>
         <vertex-shader>Shaders/HDR/aerial_perspective.glsl</vertex-shader>
         <vertex-shader>Shaders/HDR/atmos_spectral.glsl</vertex-shader>
         <fragment-shader>Shaders/HDR/3dcloud.frag</fragment-shader>
         <fragment-shader>Shaders/HDR/3dcloud_common.frag</fragment-shader>
+        <fragment-shader>Shaders/HDR/logarithmic_depth.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/aerial_perspective.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/exposure.glsl</fragment-shader>
       </program>
@@ -478,6 +478,8 @@
     <scheme>hdr-envmap</scheme>
     <pass>
       <depth>
+        <enabled>true</enabled>
+        <function>less</function>
         <write-mask>false</write-mask>
       </depth>
       <texture-unit>
diff --git a/Effects/cloud.eff b/Effects/cloud.eff
index 92f92d496..5d97883d4 100644
--- a/Effects/cloud.eff
+++ b/Effects/cloud.eff
@@ -529,11 +529,9 @@
   <technique n="129">
     <scheme>hdr-forward</scheme>
     <pass>
-      <!-- Reverse floating point depth buffer -->
       <depth>
-        <function>gequal</function>
-        <near>1.0</near>
-        <far>0.0</far>
+        <enabled>true</enabled>
+        <function>less</function>
         <write-mask>false</write-mask>
       </depth>
       <texture-unit>
@@ -548,11 +546,13 @@
       <program>
         <vertex-shader>Shaders/HDR/3dcloud.vert</vertex-shader>
         <vertex-shader>Shaders/HDR/3dcloud_common.vert</vertex-shader>
+        <vertex-shader>Shaders/HDR/logarithmic_depth.glsl</vertex-shader>
         <vertex-shader>Shaders/HDR/sun.glsl</vertex-shader>
         <vertex-shader>Shaders/HDR/aerial_perspective.glsl</vertex-shader>
         <vertex-shader>Shaders/HDR/atmos_spectral.glsl</vertex-shader>
         <fragment-shader>Shaders/HDR/3dcloud.frag</fragment-shader>
         <fragment-shader>Shaders/HDR/3dcloud_common.frag</fragment-shader>
+        <fragment-shader>Shaders/HDR/logarithmic_depth.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/aerial_perspective.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/exposure.glsl</fragment-shader>
         <attribute>
@@ -609,6 +609,8 @@
     <scheme>hdr-envmap</scheme>
     <pass>
       <depth>
+        <enabled>true</enabled>
+        <function>less</function>
         <write-mask>false</write-mask>
       </depth>
       <texture-unit>
diff --git a/Effects/lfeat.eff b/Effects/lfeat.eff
index 22ea567b0..84c55e3ec 100644
--- a/Effects/lfeat.eff
+++ b/Effects/lfeat.eff
@@ -97,11 +97,10 @@
   <technique n="107">
     <scheme>hdr-geometry</scheme>
     <pass>
-      <!-- Reverse floating point depth buffer -->
       <depth>
-        <function>gequal</function>
-        <near>1.0</near>
-        <far>0.0</far>
+        <enabled>true</enabled>
+        <function>less</function>
+        <write-mask>true</write-mask>
       </depth>
       <stencil>
         <function>always</function>
@@ -121,7 +120,9 @@
       <cull-face>back</cull-face>
       <program>
         <vertex-shader>Shaders/HDR/terrain_lfeat.vert</vertex-shader>
+        <vertex-shader>Shaders/HDR/logarithmic_depth.glsl</vertex-shader>
         <fragment-shader>Shaders/HDR/terrain_lfeat.frag</fragment-shader>
+        <fragment-shader>Shaders/HDR/logarithmic_depth.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/gbuffer_pack.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/normal_encoding.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/color.glsl</fragment-shader>
diff --git a/Effects/model-combined-transparent.eff b/Effects/model-combined-transparent.eff
index 13b59d881..cb0fbf27a 100644
--- a/Effects/model-combined-transparent.eff
+++ b/Effects/model-combined-transparent.eff
@@ -52,11 +52,9 @@ It's kept for backwards compatibility and should not be used on new projects.
   <technique n="127">
     <scheme>hdr-forward</scheme>
     <pass>
-      <!-- Reverse floating point depth buffer -->
       <depth>
-        <function>gequal</function>
-        <near>1.0</near>
-        <far>0.0</far>
+        <enabled>true</enabled>
+        <function>less</function>
         <write-mask>false</write-mask>
       </depth>
       <texture-unit>
@@ -83,10 +81,12 @@ It's kept for backwards compatibility and should not be used on new projects.
       <cull-face><use>cull-face</use></cull-face>
       <program>
         <vertex-shader>Shaders/HDR/model_transparent.vert</vertex-shader>
+        <vertex-shader>Shaders/HDR/logarithmic_depth.glsl</vertex-shader>
         <vertex-shader>Shaders/HDR/aerial_perspective.glsl</vertex-shader>
         <fragment-shader>Shaders/HDR/model_transparent.frag</fragment-shader>
         <fragment-shader>Shaders/HDR/color.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/math.glsl</fragment-shader>
+        <fragment-shader>Shaders/HDR/logarithmic_depth.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/shading_transparent.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/surface.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/ibl.glsl</fragment-shader>
diff --git a/Effects/model-combined.eff b/Effects/model-combined.eff
index b71fb4b53..dc4fe3385 100644
--- a/Effects/model-combined.eff
+++ b/Effects/model-combined.eff
@@ -1313,11 +1313,10 @@ please see Docs/README.model-combined.eff for documentation
         <technique n="108">
           <scheme>hdr-geometry</scheme>
           <pass>
-            <!-- Reverse floating point depth buffer -->
             <depth>
-              <function>gequal</function>
-              <near>1.0</near>
-              <far>0.0</far>
+              <enabled>true</enabled>
+              <function>less</function>
+              <write-mask>true</write-mask>
             </depth>
             <stencil>
               <function>always</function>
@@ -1343,7 +1342,9 @@ please see Docs/README.model-combined.eff for documentation
             <cull-face>back</cull-face>
             <program>
               <vertex-shader>Shaders/HDR/model_combined.vert</vertex-shader>
+              <vertex-shader>Shaders/HDR/logarithmic_depth.glsl</vertex-shader>
               <fragment-shader>Shaders/HDR/model_combined.frag</fragment-shader>
+              <fragment-shader>Shaders/HDR/logarithmic_depth.glsl</fragment-shader>
               <fragment-shader>Shaders/HDR/gbuffer_pack.glsl</fragment-shader>
               <fragment-shader>Shaders/HDR/normal_encoding.glsl</fragment-shader>
               <fragment-shader>Shaders/HDR/normalmap.glsl</fragment-shader>
diff --git a/Effects/model-default.eff b/Effects/model-default.eff
index d30161014..973ba3fba 100644
--- a/Effects/model-default.eff
+++ b/Effects/model-default.eff
@@ -646,11 +646,10 @@
   <technique n="109">
     <scheme>hdr-geometry</scheme>
     <pass>
-      <!-- Reverse floating point depth buffer -->
       <depth>
-        <function>gequal</function>
-        <near>1.0</near>
-        <far>0.0</far>
+        <enabled>true</enabled>
+        <function>less</function>
+        <write-mask>true</write-mask>
       </depth>
       <stencil>
         <function>always</function>
@@ -670,7 +669,9 @@
       <cull-face><use>cull-face</use></cull-face>
       <program>
         <vertex-shader>Shaders/HDR/model_default.vert</vertex-shader>
+        <vertex-shader>Shaders/HDR/logarithmic_depth.glsl</vertex-shader>
         <fragment-shader>Shaders/HDR/model_default.frag</fragment-shader>
+        <fragment-shader>Shaders/HDR/logarithmic_depth.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/gbuffer_pack.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/normal_encoding.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/color.glsl</fragment-shader>
diff --git a/Effects/model-pbr-transparent.eff b/Effects/model-pbr-transparent.eff
index c20e108f0..d52cbf426 100644
--- a/Effects/model-pbr-transparent.eff
+++ b/Effects/model-pbr-transparent.eff
@@ -54,11 +54,9 @@
   <technique n="128">
     <scheme>hdr-forward</scheme>
     <pass>
-      <!-- Reverse floating point depth buffer -->
       <depth>
-        <function>gequal</function>
-        <near>1.0</near>
-        <far>0.0</far>
+        <enabled>true</enabled>
+        <function>less</function>
         <write-mask>false</write-mask>
       </depth>
       <texture-unit>
@@ -112,11 +110,13 @@
       <cull-face><use>cull-face</use></cull-face>
       <program>
         <vertex-shader>Shaders/HDR/model_pbr_transparent.vert</vertex-shader>
+        <vertex-shader>Shaders/HDR/logarithmic_depth.glsl</vertex-shader>
         <vertex-shader>Shaders/HDR/aerial_perspective.glsl</vertex-shader>
         <fragment-shader>Shaders/HDR/model_pbr_transparent.frag</fragment-shader>
         <fragment-shader>Shaders/HDR/normalmap.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/color.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/math.glsl</fragment-shader>
+        <fragment-shader>Shaders/HDR/logarithmic_depth.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/shading_transparent.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/surface.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/ibl.glsl</fragment-shader>
diff --git a/Effects/model-pbr.eff b/Effects/model-pbr.eff
index 71d3bf352..eead751cf 100644
--- a/Effects/model-pbr.eff
+++ b/Effects/model-pbr.eff
@@ -33,11 +33,10 @@
   <technique n="109">
     <scheme>hdr-geometry</scheme>
     <pass>
-      <!-- Reverse floating point depth buffer -->
       <depth>
-        <function>gequal</function>
-        <near>1.0</near>
-        <far>0.0</far>
+        <enabled>true</enabled>
+        <function>less</function>
+        <write-mask>true</write-mask>
       </depth>
       <stencil>
         <function>always</function>
@@ -85,7 +84,9 @@
       <cull-face><use>cull-face</use></cull-face>
       <program>
         <vertex-shader>Shaders/HDR/model_pbr.vert</vertex-shader>
+        <vertex-shader>Shaders/HDR/logarithmic_depth.glsl</vertex-shader>
         <fragment-shader>Shaders/HDR/model_pbr.frag</fragment-shader>
+        <fragment-shader>Shaders/HDR/logarithmic_depth.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/gbuffer_pack.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/normal_encoding.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/normalmap.glsl</fragment-shader>
diff --git a/Effects/model-transparent.eff b/Effects/model-transparent.eff
index b8276545d..54f6ddb2e 100644
--- a/Effects/model-transparent.eff
+++ b/Effects/model-transparent.eff
@@ -48,11 +48,9 @@
   <technique n="128">
     <scheme>hdr-forward</scheme>
     <pass>
-      <!-- Reverse floating point depth buffer -->
       <depth>
-        <function>gequal</function>
-        <near>1.0</near>
-        <far>0.0</far>
+        <enabled>true</enabled>
+        <function>less</function>
         <write-mask>false</write-mask>
       </depth>
       <texture-unit>
@@ -79,10 +77,12 @@
       <cull-face><use>cull-face</use></cull-face>
       <program>
         <vertex-shader>Shaders/HDR/model_transparent.vert</vertex-shader>
+        <vertex-shader>Shaders/HDR/logarithmic_depth.glsl</vertex-shader>
         <vertex-shader>Shaders/HDR/aerial_perspective.glsl</vertex-shader>
         <fragment-shader>Shaders/HDR/model_transparent.frag</fragment-shader>
         <fragment-shader>Shaders/HDR/color.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/math.glsl</fragment-shader>
+        <fragment-shader>Shaders/HDR/logarithmic_depth.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/shading_transparent.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/surface.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/ibl.glsl</fragment-shader>
diff --git a/Effects/model-wingflex.eff b/Effects/model-wingflex.eff
index b76830b67..8cf2cd8a8 100644
--- a/Effects/model-wingflex.eff
+++ b/Effects/model-wingflex.eff
@@ -1412,12 +1412,11 @@
     <technique n="108">
         <scheme>hdr-geometry</scheme>
         <pass>
-            <!-- Reverse floating point depth buffer -->
-            <depth>
-				<function>gequal</function>
-				<near>1.0</near>
-				<far>0.0</far>
-            </depth>
+			<depth>
+				<enabled>true</enabled>
+				<function>less</function>
+				<write-mask>true</write-mask>
+			</depth>
             <stencil>
 				<function>always</function>
 				<value>8</value>
@@ -1442,7 +1441,9 @@
             <cull-face>back</cull-face>
             <program>
 				<vertex-shader>Shaders/HDR/model_combined.vert</vertex-shader>
+				<vertex-shader>Shaders/HDR/logarithmic_depth.glsl</vertex-shader>
 				<fragment-shader>Shaders/HDR/model_combined.frag</fragment-shader>
+				<fragment-shader>Shaders/HDR/logarithmic_depth.glsl</fragment-shader>
 				<fragment-shader>Shaders/HDR/gbuffer_pack.glsl</fragment-shader>
 				<fragment-shader>Shaders/HDR/normal_encoding.glsl</fragment-shader>
 				<fragment-shader>Shaders/HDR/normalmap.glsl</fragment-shader>
diff --git a/Effects/runway.eff b/Effects/runway.eff
index fc1f5d4ab..e2646752f 100644
--- a/Effects/runway.eff
+++ b/Effects/runway.eff
@@ -890,11 +890,10 @@
   <technique n="108">
     <scheme>hdr-geometry</scheme>
     <pass>
-      <!-- Reverse floating point depth buffer -->
       <depth>
-        <function>gequal</function>
-        <near>1.0</near>
-        <far>0.0</far>
+        <enabled>true</enabled>
+        <function>less</function>
+        <write-mask>true</write-mask>
       </depth>
       <stencil>
         <function>always</function>
@@ -926,7 +925,9 @@
       <cull-face>back</cull-face>
       <program>
         <vertex-shader>Shaders/HDR/terrain_runway.vert</vertex-shader>
+        <vertex-shader>Shaders/HDR/logarithmic_depth.glsl</vertex-shader>
         <fragment-shader>Shaders/HDR/terrain_runway.frag</fragment-shader>
+        <fragment-shader>Shaders/HDR/logarithmic_depth.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/gbuffer_pack.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/normal_encoding.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/normalmap.glsl</fragment-shader>
diff --git a/Effects/skydome.eff b/Effects/skydome.eff
index 75bbded4e..a811f41d4 100644
--- a/Effects/skydome.eff
+++ b/Effects/skydome.eff
@@ -307,11 +307,9 @@
   <technique n="129">
     <scheme>hdr-forward</scheme>
     <pass>
-      <!-- Reverse floating point depth buffer -->
       <depth>
-        <function>greater</function>
-        <near>1.0</near>
-        <far>0.0</far>
+        <enabled>true</enabled>
+        <function>less</function>
         <write-mask>false</write-mask>
       </depth>
       <cull-face>back</cull-face>
@@ -354,6 +352,8 @@
     <scheme>hdr-envmap</scheme>
     <pass>
       <depth>
+        <enabled>true</enabled>
+        <function>less</function>
         <write-mask>false</write-mask>
       </depth>
       <cull-face>back</cull-face>
diff --git a/Effects/terrain-default.eff b/Effects/terrain-default.eff
index 2112663c0..bd5b5cd9d 100644
--- a/Effects/terrain-default.eff
+++ b/Effects/terrain-default.eff
@@ -1715,11 +1715,10 @@
   <technique n="109">
     <scheme>hdr-geometry</scheme>
     <pass>
-      <!-- Reverse floating point depth buffer -->
       <depth>
-        <function>gequal</function>
-        <near>1.0</near>
-        <far>0.0</far>
+        <enabled>true</enabled>
+        <function>less</function>
+        <write-mask>true</write-mask>
       </depth>
       <stencil>
         <function>always</function>
@@ -1739,7 +1738,9 @@
       <cull-face>back</cull-face>
       <program>
         <vertex-shader>Shaders/HDR/terrain_default.vert</vertex-shader>
+        <vertex-shader>Shaders/HDR/logarithmic_depth.glsl</vertex-shader>
         <fragment-shader>Shaders/HDR/terrain_default.frag</fragment-shader>
+        <fragment-shader>Shaders/HDR/logarithmic_depth.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/gbuffer_pack.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/normal_encoding.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/color.glsl</fragment-shader>
@@ -1761,6 +1762,11 @@
   <technique n="139">
     <scheme>hdr-envmap</scheme>
     <pass>
+      <depth>
+        <enabled>true</enabled>
+        <function>less</function>
+        <write-mask>true</write-mask>
+      </depth>
       <texture-unit>
         <unit>0</unit>
         <type><use>texture[0]/type</use></type>
diff --git a/Effects/text-default.eff b/Effects/text-default.eff
index 7091b648b..0f8afdfb7 100644
--- a/Effects/text-default.eff
+++ b/Effects/text-default.eff
@@ -60,11 +60,9 @@
   <technique n="129">
     <scheme>hdr-forward</scheme>
     <pass>
-      <!-- Reverse floating point depth buffer -->
       <depth>
-        <function>gequal</function>
-        <near>1.0</near>
-        <far>0.0</far>
+        <enabled>true</enabled>
+        <function>less</function>
         <write-mask>false</write-mask>
       </depth>
       <blend>1</blend>
@@ -72,10 +70,12 @@
       <cull-face>back</cull-face>
       <program>
         <vertex-shader>Shaders/HDR/text.vert</vertex-shader>
+        <vertex-shader>Shaders/HDR/logarithmic_depth.glsl</vertex-shader>
         <vertex-shader>Shaders/HDR/aerial_perspective.glsl</vertex-shader>
         <fragment-shader>Shaders/HDR/text.frag</fragment-shader>
         <fragment-shader>Shaders/HDR/color.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/math.glsl</fragment-shader>
+        <fragment-shader>Shaders/HDR/logarithmic_depth.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/shading_transparent.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/surface.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/ibl.glsl</fragment-shader>
diff --git a/Effects/tree.eff b/Effects/tree.eff
index c70424c00..6982d18cc 100644
--- a/Effects/tree.eff
+++ b/Effects/tree.eff
@@ -1880,11 +1880,10 @@
       <property>/sim/rendering/random-vegetation</property>
     </predicate>
     <pass>
-      <!-- Reverse floating point depth buffer -->
       <depth>
-        <function>gequal</function>
-        <near>1.0</near>
-        <far>0.0</far>
+        <enabled>true</enabled>
+        <function>less</function>
+        <write-mask>true</write-mask>
       </depth>
       <stencil>
         <function>always</function>
@@ -1905,7 +1904,9 @@
       <program>
         <vertex-shader>Shaders/HDR/tree.vert</vertex-shader>
         <vertex-shader>Shaders/HDR/noise.glsl</vertex-shader>
+        <vertex-shader>Shaders/HDR/logarithmic_depth.glsl</vertex-shader>
         <fragment-shader>Shaders/HDR/tree.frag</fragment-shader>
+        <fragment-shader>Shaders/HDR/logarithmic_depth.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/gbuffer_pack.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/normal_encoding.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/color.glsl</fragment-shader>
diff --git a/Effects/water.eff b/Effects/water.eff
index a9909a05a..9e6abdc5f 100644
--- a/Effects/water.eff
+++ b/Effects/water.eff
@@ -1496,11 +1496,10 @@
     <technique n="108">
         <scheme>hdr-geometry</scheme>
         <pass>
-            <!-- Reverse floating point depth buffer -->
             <depth>
-                <function>gequal</function>
-                <near>1.0</near>
-                <far>0.0</far>
+                <enabled>true</enabled>
+                <function>less</function>
+                <write-mask>true</write-mask>
             </depth>
             <stencil>
                 <function>always</function>
@@ -1551,7 +1550,9 @@
             </texture-unit>
             <program>
                 <vertex-shader>Shaders/HDR/water.vert</vertex-shader>
+                <vertex-shader>Shaders/HDR/logarithmic_depth.glsl</vertex-shader>
                 <fragment-shader>Shaders/HDR/water.frag</fragment-shader>
+                <fragment-shader>Shaders/HDR/logarithmic_depth.glsl</fragment-shader>
                 <fragment-shader>Shaders/HDR/normal_encoding.glsl</fragment-shader>
                 <fragment-shader>Shaders/HDR/normalmap.glsl</fragment-shader>
                 <fragment-shader>Shaders/HDR/color.glsl</fragment-shader>
diff --git a/Effects/ws30.eff b/Effects/ws30.eff
index d9f12225c..be5f2f8bd 100644
--- a/Effects/ws30.eff
+++ b/Effects/ws30.eff
@@ -1877,11 +1877,10 @@
   <technique n="109">
     <scheme>hdr-geometry</scheme>
     <pass>
-      <!-- Reverse floating point depth buffer -->
       <depth>
-        <function>gequal</function>
-        <near>1.0</near>
-        <far>0.0</far>
+        <enabled>true</enabled>
+        <function>less</function>
+        <write-mask>true</write-mask>
       </depth>
       <stencil>
         <function>always</function>
@@ -1949,7 +1948,9 @@
       <cull-face>back</cull-face>
       <program>
         <vertex-shader>Shaders/HDR/terrain_default.vert</vertex-shader>
+        <vertex-shader>Shaders/HDR/logarithmic_depth.glsl</vertex-shader>
         <fragment-shader>Shaders/HDR/ws30.frag</fragment-shader>
+        <fragment-shader>Shaders/HDR/logarithmic_depth.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/gbuffer_pack.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/normal_encoding.glsl</fragment-shader>
         <fragment-shader>Shaders/HDR/color.glsl</fragment-shader>
diff --git a/Shaders/HDR/3dcloud.frag b/Shaders/HDR/3dcloud.frag
index 4c15ee3a1..134329baa 100644
--- a/Shaders/HDR/3dcloud.frag
+++ b/Shaders/HDR/3dcloud.frag
@@ -2,10 +2,14 @@
 
 layout(location = 0) out vec4 fragColor;
 
+in float flogz;
+
 // 3dcloud_common.frag
 vec4 cloud_common_frag();
 // exposure.glsl
 vec3 apply_exposure(vec3 color);
+// logarithmic_depth.glsl
+float logdepth_encode(float z);
 
 void main()
 {
@@ -16,4 +20,5 @@ void main()
     color.rgb = apply_exposure(color.rgb);
 
     fragColor = color;
+    gl_FragDepth = logdepth_encode(flogz);
 }
diff --git a/Shaders/HDR/3dcloud.vert b/Shaders/HDR/3dcloud.vert
index 3921ddb53..91850f869 100644
--- a/Shaders/HDR/3dcloud.vert
+++ b/Shaders/HDR/3dcloud.vert
@@ -1,17 +1,22 @@
 #version 330 core
 
+out float flogz;
 out vec4 ap_color;
 
 // 3dcloud_common.vert
 void cloud_common_vert(out vec4 vs_pos, out vec4 ws_pos);
 // aerial_perspective.glsl
 vec4 get_aerial_perspective(vec2 coord, float depth);
+// logarithmic_depth.glsl
+float logdepth_prepare_vs_depth(float z);
 
 void main()
 {
     vec4 vs_pos, ws_pos;
     cloud_common_vert(vs_pos, ws_pos);
 
+    flogz = logdepth_prepare_vs_depth(gl_Position.w);
+
     // Perspective division and scale to [0, 1] to get the screen position
     // of the vertex.
     vec2 coord = (gl_Position.xy / gl_Position.w) * 0.5 + 0.5;
diff --git a/Shaders/HDR/cloud_static.vert b/Shaders/HDR/cloud_static.vert
index dd7af6a8d..71e2c30c9 100644
--- a/Shaders/HDR/cloud_static.vert
+++ b/Shaders/HDR/cloud_static.vert
@@ -1,17 +1,22 @@
 #version 330 core
 
+out float flogz;
 out vec4 ap_color;
 
 // cloud_static_common.vert
 void cloud_static_common_vert(out vec4 vs_pos, out vec4 ws_pos);
 // aerial_perspective.glsl
 vec4 get_aerial_perspective(vec2 coord, float depth);
+// logarithmic_depth.glsl
+float logdepth_prepare_vs_depth(float z);
 
 void main()
 {
     vec4 vs_pos, ws_pos;
     cloud_static_common_vert(vs_pos, ws_pos);
 
+    flogz = logdepth_prepare_vs_depth(gl_Position.w);
+
     // Perspective division and scale to [0, 1] to get the screen position
     // of the vertex.
     vec2 coord = (gl_Position.xy / gl_Position.w) * 0.5 + 0.5;
diff --git a/Shaders/HDR/debug_gbuffer_depth.frag b/Shaders/HDR/debug_gbuffer_depth.frag
index 40faa2b0a..3b096d0b3 100644
--- a/Shaders/HDR/debug_gbuffer_depth.frag
+++ b/Shaders/HDR/debug_gbuffer_depth.frag
@@ -6,11 +6,9 @@ in vec2 texcoord;
 
 uniform sampler2D depth_tex;
 
-// pos_from_depth.glsl
-float linearize_depth(float depth);
-
 void main()
 {
     float depth = texture(depth_tex, texcoord).r;
-    fragColor = vec4(vec3(linearize_depth(depth)), 1.0);
+    // Display depth as is, no linearization
+    fragColor = vec4(vec3(depth), 1.0);
 }
diff --git a/Shaders/HDR/gtao.frag b/Shaders/HDR/gtao.frag
index 7a703453e..fe99732a7 100644
--- a/Shaders/HDR/gtao.frag
+++ b/Shaders/HDR/gtao.frag
@@ -37,9 +37,9 @@ void main()
 {
     float depth = textureLod(depth_tex, texcoord, 0.0).r;
     // Ignore the background
-    if (depth == 0.0) {
-        fragColor = 0.0;
-        discard;
+    if (depth == 1.0) {
+        fragColor = 1.0;
+        return;
     }
     // Slightly push the depth towards the camera to avoid imprecision artifacts
     depth = clamp(depth * 1.00001, 0.0, 1.0);
@@ -64,7 +64,7 @@ void main()
     // 1 / tan(fovy / 2), so we can use that directly.
     // z_distance is the distance from the camera to the fragment, which is
     // just the positive z component of the view space fragment position.
-	float radius_pixels = world_radius * (fg_ProjectionMatrix[1][1] / abs(P.z))
+    float radius_pixels = world_radius * (fg_ProjectionMatrix[1][1] / abs(P.z))
         * fg_Viewport.w * 0.5;
 
     float visibility = 0.0;
@@ -95,7 +95,7 @@ void main()
 
             vec2 s_texcoord1 = texcoord - s_offset;
             float s_depth1 = textureLod(depth_tex, s_texcoord1, 0.0).r;
-            if (s_depth1 == 0.0) {
+            if (s_depth1 == 1.0) {
                 // Skip background
                 continue;
             }
@@ -103,7 +103,7 @@ void main()
 
             vec2 s_texcoord2 = texcoord + s_offset;
             float s_depth2 = textureLod(depth_tex, s_texcoord2, 0.0).r;
-            if (s_depth2 == 0.0) {
+            if (s_depth2 == 1.0) {
                 // Skip background
                 continue;
             }
diff --git a/Shaders/HDR/logarithmic_depth.glsl b/Shaders/HDR/logarithmic_depth.glsl
new file mode 100644
index 000000000..b02f1a8da
--- /dev/null
+++ b/Shaders/HDR/logarithmic_depth.glsl
@@ -0,0 +1,83 @@
+/*
+ * Logarithmic depth buffer utility functions
+ *
+ * The HDR pipeline uses a logarithmic depth buffer to avoid Z-fighting and
+ * depth precision issues. This method is compatible with all OpenGL 3.3
+ * hardware since it does not require any fancy depth reversal tricks.
+ *
+ * The main disadvantage is that we lose the early depth test optimization. This
+ * is not a problem for us because we use deferred rendering, so the fragment
+ * shaders that run on the actual geometry are very lightweight.
+ *
+ * Sources:
+ * https://outerra.blogspot.com/2009/08/logarithmic-z-buffer.html
+ * https://outerra.blogspot.com/2012/11/maximizing-depth-buffer-range-and.html
+ * https://outerra.blogspot.com/2013/07/logarithmic-depth-buffer-optimizations.html
+ * https://io7m.github.io/r2/documentation/p2s24.xhtml
+ */
+#version 330 core
+
+uniform float fg_Fcoef;
+uniform vec2 fg_NearFar;
+
+/*
+ * Prepare a view space depth value for encoding. Normal usage involves calling
+ * this function in the vertex shader, after writing to gl_Position. The z value
+ * corresponds to gl_Position.w (if using perspective projection), or the
+ * negated view space depth.
+ * See logdepth_encode().
+ */
+float logdepth_prepare_vs_depth(float z)
+{
+    return 1.0 + z;
+}
+
+/*
+ * Encodes a given depth value obtained with logdepth_prepare_vs_depth() into
+ * logarithmic depth. The result is used in the fragment shader to write to
+ * gl_FragDepth.
+ */
+float logdepth_encode(float z)
+{
+    float half_fcoef = fg_Fcoef * 0.5;
+    float clamped_z = max(1e-6, z);
+    return log2(clamped_z) * half_fcoef;
+}
+
+/*
+ * This is an alternative way of encoding a depth value obtained with
+ * logdepth_prepare_vs_depth() into logarithmic depth in the vertex shader
+ * without writing to gl_FragDepth in the fragment shader. The result
+ * corresponds to gl_Position.z
+ *
+ * The disadvantage is that depth will not be interpolated in a
+ * perspectively-correct way, but it will work okay for very finely tessellated
+ * geometry.
+ */
+float logdepth_encode_no_perspective(float z)
+{
+    float clamped_z = max(1e-6, z);
+    return log2(clamped_z) * fg_Fcoef - 1.0;
+}
+
+/*
+ * Decode a view space depth value that was encoded with the functions above.
+ * z corresponds to the [0,1] depth buffer value.
+ * NOTE: The resulting depth value is positive, so it must be negated to yield
+ *       a conventional negative view space depth value.
+ */
+float logdepth_decode(float z)
+{
+    float half_fcoef = fg_Fcoef * 0.5;
+    float exponent = z / half_fcoef;
+    return pow(2.0, exponent) - 1.0;
+}
+
+/*
+ * Same as logdepth_decode(), but returns the normalized view-space depth
+ * in the [0,1] range.
+ */
+float logdepth_decode_normalized(float z)
+{
+    return logdepth_decode(z) / fg_NearFar.y;
+}
diff --git a/Shaders/HDR/model_chrome.frag b/Shaders/HDR/model_chrome.frag
index a4acd8223..e66d390b0 100644
--- a/Shaders/HDR/model_chrome.frag
+++ b/Shaders/HDR/model_chrome.frag
@@ -1,6 +1,9 @@
 #version 330 core
 
-in vec3 vertex_normal;
+in VS_OUT {
+    float flogz;
+    vec3 vertex_normal;
+} fs_in;
 
 const float CHROME_METALLIC  = 1.0;
 const float CHROME_ROUGHNESS = 0.1;
@@ -8,9 +11,12 @@ const float CHROME_ROUGHNESS = 0.1;
 // gbuffer_pack.glsl
 void gbuffer_pack(vec3 normal, vec3 base_color, float metallic, float roughness,
                   float occlusion, vec3 emissive, uint mat_id);
+// logarithmic_depth.glsl
+float logdepth_encode(float z);
 
 void main()
 {
-    vec3 N = normalize(vertex_normal);
+    vec3 N = normalize(fs_in.vertex_normal);
     gbuffer_pack(N, vec3(1.0), CHROME_METALLIC, CHROME_ROUGHNESS, 1.0, vec3(0.0), 3u);
+    gl_FragDepth = logdepth_encode(fs_in.flogz);
 }
diff --git a/Shaders/HDR/model_chrome.vert b/Shaders/HDR/model_chrome.vert
index f71083afd..9ae2e8d19 100644
--- a/Shaders/HDR/model_chrome.vert
+++ b/Shaders/HDR/model_chrome.vert
@@ -3,13 +3,20 @@
 layout(location = 0) in vec4 pos;
 layout(location = 1) in vec3 normal;
 
-out vec3 vertex_normal;
+out VS_OUT {
+    float flogz;
+    vec3 vertex_normal;
+} vs_out;
 
 uniform mat4 osg_ModelViewProjectionMatrix;
 uniform mat3 osg_NormalMatrix;
 
+// logarithmic_depth.glsl
+float logdepth_prepare_vs_depth(float z);
+
 void main()
 {
     gl_Position = osg_ModelViewProjectionMatrix * pos;
-    vertex_normal = osg_NormalMatrix * normal;
+    vs_out.flogz = logdepth_prepare_vs_depth(gl_Position.w);
+    vs_out.vertex_normal = osg_NormalMatrix * normal;
 }
diff --git a/Shaders/HDR/model_combined.frag b/Shaders/HDR/model_combined.frag
index 10b67b5a7..3c9507b16 100644
--- a/Shaders/HDR/model_combined.frag
+++ b/Shaders/HDR/model_combined.frag
@@ -1,6 +1,7 @@
 #version 330 core
 
 in VS_OUT {
+    float flogz;
     vec2 texcoord;
     vec3 vertex_normal;
     vec3 view_vector;
@@ -20,6 +21,8 @@ void gbuffer_pack(vec3 normal, vec3 base_color, float metallic, float roughness,
 vec3 eotf_inverse_sRGB(vec3 srgb);
 // normalmap.glsl
 vec3 perturb_normal(vec3 N, vec3 V, vec2 texcoord);
+// logarithmic_depth.glsl
+float logdepth_encode(float z);
 
 void main()
 {
@@ -32,4 +35,5 @@ void main()
     }
 
     gbuffer_pack(N, color, metallic, roughness, 1.0, vec3(0.0), 3u);
+    gl_FragDepth = logdepth_encode(fs_in.flogz);
 }
diff --git a/Shaders/HDR/model_combined.vert b/Shaders/HDR/model_combined.vert
index 4e7979198..de251c697 100644
--- a/Shaders/HDR/model_combined.vert
+++ b/Shaders/HDR/model_combined.vert
@@ -5,6 +5,7 @@ layout(location = 1) in vec3 normal;
 layout(location = 3) in vec4 multitexcoord0;
 
 out VS_OUT {
+    float flogz;
     vec2 texcoord;
     vec3 vertex_normal;
     vec3 view_vector;
@@ -17,9 +18,13 @@ uniform mat4 osg_ModelViewProjectionMatrix;
 uniform mat3 osg_NormalMatrix;
 uniform mat4 fg_TextureMatrix;
 
+// logarithmic_depth.glsl
+float logdepth_prepare_vs_depth(float z);
+
 void main()
 {
     gl_Position = osg_ModelViewProjectionMatrix * pos;
+    vs_out.flogz = logdepth_prepare_vs_depth(gl_Position.w);
     vs_out.texcoord = vec2(fg_TextureMatrix * multitexcoord0);
     vs_out.vertex_normal = osg_NormalMatrix * normal;
     vs_out.view_vector = (osg_ModelViewMatrix * pos).xyz;
diff --git a/Shaders/HDR/model_default.frag b/Shaders/HDR/model_default.frag
index e3aec1b61..7dad78562 100644
--- a/Shaders/HDR/model_default.frag
+++ b/Shaders/HDR/model_default.frag
@@ -1,6 +1,7 @@
 #version 330 core
 
 in VS_OUT {
+    float flogz;
     vec2 texcoord;
     vec3 vertex_normal;
     vec4 material_color;
@@ -16,6 +17,8 @@ void gbuffer_pack(vec3 normal, vec3 base_color, float metallic, float roughness,
                   float occlusion, vec3 emissive, uint mat_id);
 // color.glsl
 vec3 eotf_inverse_sRGB(vec3 srgb);
+// logarithmic_depth.glsl
+float logdepth_encode(float z);
 
 void main()
 {
@@ -25,4 +28,5 @@ void main()
     vec3 N = normalize(fs_in.vertex_normal);
 
     gbuffer_pack(N, color, DEFAULT_METALLIC, DEFAULT_ROUGHNESS, 1.0, vec3(0.0), 3u);
+    gl_FragDepth = logdepth_encode(fs_in.flogz);
 }
diff --git a/Shaders/HDR/model_default.vert b/Shaders/HDR/model_default.vert
index ca43babdc..2d9e26458 100644
--- a/Shaders/HDR/model_default.vert
+++ b/Shaders/HDR/model_default.vert
@@ -10,6 +10,7 @@ layout(location = 2) in vec4 vertex_color;
 layout(location = 3) in vec4 multitexcoord0;
 
 out VS_OUT {
+    float flogz;
     vec2 texcoord;
     vec3 vertex_normal;
     vec4 material_color;
@@ -22,9 +23,13 @@ uniform mat4 osg_ModelViewProjectionMatrix;
 uniform mat3 osg_NormalMatrix;
 uniform mat4 fg_TextureMatrix;
 
+// logarithmic_depth.glsl
+float logdepth_prepare_vs_depth(float z);
+
 void main()
 {
     gl_Position = osg_ModelViewProjectionMatrix * pos;
+    vs_out.flogz = logdepth_prepare_vs_depth(gl_Position.w);
     vs_out.texcoord = vec2(fg_TextureMatrix * multitexcoord0);
     vs_out.vertex_normal = osg_NormalMatrix * normal;
 
diff --git a/Shaders/HDR/model_pbr.frag b/Shaders/HDR/model_pbr.frag
index 2e4050ca5..84c96b9d8 100644
--- a/Shaders/HDR/model_pbr.frag
+++ b/Shaders/HDR/model_pbr.frag
@@ -1,6 +1,7 @@
 #version 330 core
 
 in VS_OUT {
+    float flogz;
     vec2 texcoord;
     vec3 vertex_normal;
     vec3 view_vector;
@@ -22,6 +23,8 @@ void gbuffer_pack(vec3 normal, vec3 base_color, float metallic, float roughness,
 vec3 eotf_inverse_sRGB(vec3 srgb);
 // normalmap.glsl
 vec3 perturb_normal(vec3 N, vec3 V, vec2 texcoord);
+// logarithmic_depth.glsl
+float logdepth_encode(float z);
 
 void main()
 {
@@ -38,4 +41,5 @@ void main()
     N = perturb_normal(N, fs_in.view_vector, fs_in.texcoord);
 
     gbuffer_pack(N, base_color, metallic, roughness, occlusion, emissive, 3u);
+    gl_FragDepth = logdepth_encode(fs_in.flogz);
 }
diff --git a/Shaders/HDR/model_pbr.vert b/Shaders/HDR/model_pbr.vert
index cd9c15007..5a5b23bc0 100644
--- a/Shaders/HDR/model_pbr.vert
+++ b/Shaders/HDR/model_pbr.vert
@@ -5,6 +5,7 @@ layout(location = 1) in vec3 normal;
 layout(location = 3) in vec4 multitexcoord0;
 
 out VS_OUT {
+    float flogz;
     vec2 texcoord;
     vec3 vertex_normal;
     vec3 view_vector;
@@ -17,9 +18,13 @@ uniform mat4 osg_ModelViewProjectionMatrix;
 uniform mat3 osg_NormalMatrix;
 uniform mat4 fg_TextureMatrix;
 
+// logarithmic_depth.glsl
+float logdepth_prepare_vs_depth(float z);
+
 void main()
 {
     gl_Position = osg_ModelViewProjectionMatrix * pos;
+    vs_out.flogz = logdepth_prepare_vs_depth(gl_Position.w);
     vs_out.texcoord = vec2(fg_TextureMatrix * multitexcoord0);
     if (flip_vertically)
         vs_out.texcoord.y = 1.0 - vs_out.texcoord.y;
diff --git a/Shaders/HDR/model_pbr_transparent.frag b/Shaders/HDR/model_pbr_transparent.frag
index 379b3c03c..637935e9b 100644
--- a/Shaders/HDR/model_pbr_transparent.frag
+++ b/Shaders/HDR/model_pbr_transparent.frag
@@ -3,6 +3,7 @@
 layout(location = 0) out vec4 fragColor;
 
 in VS_OUT {
+    float flogz;
     vec2 texcoord;
     vec3 vertex_normal;
     vec3 view_vector;
@@ -32,6 +33,8 @@ vec3 eval_lights_transparent(
     mat4 view_matrix_inverse);
 // normalmap.glsl
 vec3 perturb_normal(vec3 N, vec3 V, vec2 texcoord);
+// logarithmic_depth.glsl
+float logdepth_encode(float z);
 
 void main()
 {
@@ -58,4 +61,5 @@ void main()
         fs_in.view_vector, N, V, uv, fs_in.ap_color, osg_ViewMatrixInverse);
 
     fragColor = vec4(color, base_color.a);
+    gl_FragDepth = logdepth_encode(fs_in.flogz);
 }
diff --git a/Shaders/HDR/model_pbr_transparent.vert b/Shaders/HDR/model_pbr_transparent.vert
index 6d9546be1..a254a81b7 100644
--- a/Shaders/HDR/model_pbr_transparent.vert
+++ b/Shaders/HDR/model_pbr_transparent.vert
@@ -5,6 +5,7 @@ layout(location = 1) in vec3 normal;
 layout(location = 3) in vec4 multitexcoord0;
 
 out VS_OUT {
+    float flogz;
     vec2 texcoord;
     vec3 vertex_normal;
     vec3 view_vector;
@@ -20,10 +21,13 @@ uniform mat4 fg_TextureMatrix;
 
 // aerial_perspective.glsl
 vec4 get_aerial_perspective(vec2 coord, float depth);
+// logarithmic_depth.glsl
+float logdepth_prepare_vs_depth(float z);
 
 void main()
 {
     gl_Position = osg_ModelViewProjectionMatrix * pos;
+    vs_out.flogz = logdepth_prepare_vs_depth(gl_Position.w);
     vs_out.texcoord = vec2(fg_TextureMatrix * multitexcoord0);
     if (flip_vertically)
         vs_out.texcoord.y = 1.0 - vs_out.texcoord.y;
diff --git a/Shaders/HDR/model_transparent.frag b/Shaders/HDR/model_transparent.frag
index 2ee6cad55..487d71919 100644
--- a/Shaders/HDR/model_transparent.frag
+++ b/Shaders/HDR/model_transparent.frag
@@ -2,11 +2,14 @@
 
 layout(location = 0) out vec4 fragColor;
 
-in vec3 vN;
-in vec3 vP;
-in vec2 texcoord;
-in vec4 material_color;
-in vec4 ap_color;
+in VS_OUT {
+    float flogz;
+    vec2 texcoord;
+    vec3 vertex_normal;
+    vec3 view_vector;
+    vec4 material_color;
+    vec4 ap_color;
+} fs_in;
 
 uniform sampler2D color_tex;
 
@@ -23,20 +26,23 @@ vec3 eval_lights_transparent(
     vec3 base_color, float metallic, float roughness, float occlusion,
     vec3 emissive, vec3 P, vec3 N, vec3 V, vec2 uv, vec4 ap,
     mat4 view_matrix_inverse);
+// logarithmic_depth.glsl
+float logdepth_encode(float z);
 
 void main()
 {
-    vec4 texel = texture(color_tex, texcoord);
-    vec3 base_color = eotf_inverse_sRGB(texel.rgb) * material_color.rgb;
-    float alpha = material_color.a * texel.a;
+    vec4 texel = texture(color_tex, fs_in.texcoord);
+    vec3 base_color = eotf_inverse_sRGB(texel.rgb) * fs_in.material_color.rgb;
+    float alpha = fs_in.material_color.a * texel.a;
 
-    vec3 N = normalize(vN);
-    vec3 V = normalize(-vP);
+    vec3 N = normalize(fs_in.vertex_normal);
+    vec3 V = normalize(-fs_in.view_vector);
     vec2 uv = (gl_FragCoord.xy - fg_Viewport.xy) / fg_Viewport.zw;
 
     vec3 color = eval_lights_transparent(
         base_color, TRANSPARENT_METALLIC, TRANSPARENT_ROUGHNESS, 1.0, vec3(0.0),
-        vP, N, V, uv, ap_color, osg_ViewMatrixInverse);
+        fs_in.view_vector, N, V, uv, fs_in.ap_color, osg_ViewMatrixInverse);
 
     fragColor = vec4(color, alpha);
+    gl_FragDepth = logdepth_encode(fs_in.flogz);
 }
diff --git a/Shaders/HDR/model_transparent.vert b/Shaders/HDR/model_transparent.vert
index dec5e6032..4f3b97cae 100644
--- a/Shaders/HDR/model_transparent.vert
+++ b/Shaders/HDR/model_transparent.vert
@@ -9,11 +9,14 @@ layout(location = 1) in vec3 normal;
 layout(location = 2) in vec4 vertex_color;
 layout(location = 3) in vec4 multitexcoord0;
 
-out vec3 vN;
-out vec3 vP;
-out vec2 texcoord;
-out vec4 material_color;
-out vec4 ap_color;
+out VS_OUT {
+    float flogz;
+    vec2 texcoord;
+    vec3 vertex_normal;
+    vec3 view_vector;
+    vec4 material_color;
+    vec4 ap_color;
+} vs_out;
 
 uniform int color_mode;
 uniform vec4 material_diffuse;
@@ -25,28 +28,31 @@ uniform mat4 fg_TextureMatrix;
 
 // aerial_perspective.glsl
 vec4 get_aerial_perspective(vec2 coord, float depth);
+// logarithmic_depth.glsl
+float logdepth_prepare_vs_depth(float z);
 
 void main()
 {
     gl_Position = osg_ModelViewProjectionMatrix * pos;
-    vN = osg_NormalMatrix * normal;
-    vP = (osg_ModelViewMatrix * pos).xyz;
-    texcoord = vec2(fg_TextureMatrix * multitexcoord0);
+    vs_out.flogz = logdepth_prepare_vs_depth(gl_Position.w);
+    vs_out.vertex_normal = osg_NormalMatrix * normal;
+    vs_out.view_vector = (osg_ModelViewMatrix * pos).xyz;
+    vs_out.texcoord = vec2(fg_TextureMatrix * multitexcoord0);
 
     // Legacy material handling
     if (color_mode == MODE_DIFFUSE)
-        material_color = vertex_color;
+        vs_out.material_color = vertex_color;
     else if (color_mode == MODE_AMBIENT_AND_DIFFUSE)
-        material_color = vertex_color;
+        vs_out.material_color = vertex_color;
     else
-        material_color = material_diffuse;
+        vs_out.material_color = material_diffuse;
     // Super hack: if diffuse material alpha is less than 1, assume a
     // transparency animation is at work
     if (material_diffuse.a < 1.0)
-        material_color.a = material_diffuse.a;
+        vs_out.material_color.a = material_diffuse.a;
     else
-        material_color.a = vertex_color.a;
+        vs_out.material_color.a = vertex_color.a;
 
     vec2 coord = (gl_Position.xy / gl_Position.w) * 0.5 + 0.5;
-    ap_color = get_aerial_perspective(coord, length(vP));
+    vs_out.ap_color = get_aerial_perspective(coord, length(vs_out.view_vector));
 }
diff --git a/Shaders/HDR/pos_from_depth.glsl b/Shaders/HDR/pos_from_depth.glsl
index bfd209963..8984c80d4 100644
--- a/Shaders/HDR/pos_from_depth.glsl
+++ b/Shaders/HDR/pos_from_depth.glsl
@@ -6,6 +6,11 @@ uniform vec2 fg_NearFar;
 uniform mat4 fg_ViewMatrixInverse;
 uniform mat4 fg_ProjectionMatrixInverse;
 
+uniform vec2 fg_FOVScale;
+
+// logarithmic_depth.glsl
+float logdepth_decode(float z);
+
 /*
  * Reconstruct the view space position from the depth buffer. Mostly used by
  * fullscreen post-processing shaders.
@@ -13,22 +18,12 @@ uniform mat4 fg_ProjectionMatrixInverse;
  * Given a 2D screen UV in the range [0,1] and a depth value from the depth
  * buffer, also in the [0,1] range, return the view space position.
  */
-vec3 get_view_space_from_depth(vec2 uv, float depth, mat4 proj_matrix_inverse)
-{
-    /*
-     * We are using a reversed depth buffer. 1.0 corresponds to the near plane
-     * and 0.0 to the far plane. We convert this back to NDC space by doing
-     * 1.0 - depth          to undo the depth reversal
-     * 2.0 * depth - 1.0    to transform it to NDC space [-1,1]
-     */
-    vec4 ndc_p = vec4(uv * 2.0 - 1.0, 1.0 - depth * 2.0, 1.0);
-    vec4 vs_p = proj_matrix_inverse * ndc_p;
-    return vs_p.xyz / vs_p.w;
-}
-
 vec3 get_view_space_from_depth(vec2 uv, float depth)
 {
-    return get_view_space_from_depth(uv, depth, fg_ProjectionMatrixInverse);
+    float vs_depth = logdepth_decode(depth);
+    vec2 half_ndc_pos = vec2(0.5) - uv;
+    vec3 vs_pos = vec3(half_ndc_pos * fg_FOVScale * (-vs_depth), -vs_depth);
+    return vs_pos;
 }
 
 vec3 get_view_space_from_depth(vec2 uv)
@@ -46,11 +41,3 @@ vec3 get_world_space_from_depth(vec2 uv)
 {
     return get_world_space_from_depth(uv, texture(depth_tex, uv).r);
 }
-
-float linearize_depth(float depth)
-{
-    // Undo the depth reversal
-    float z = 1.0 - depth;
-    return 2.0 * fg_NearFar.x
-        / (fg_NearFar.y + fg_NearFar.x - z * (fg_NearFar.y - fg_NearFar.x));
-}
diff --git a/Shaders/HDR/shadows.glsl b/Shaders/HDR/shadows.glsl
index eb504eeb2..101553c9d 100644
--- a/Shaders/HDR/shadows.glsl
+++ b/Shaders/HDR/shadows.glsl
@@ -27,6 +27,8 @@ const vec2 UV_FACTOR = vec2(0.5, 0.5);
 // math.glsl
 float saturate(float x);
 float interleaved_gradient_noise(vec2 uv);
+// logarithmic_depth.glsl
+float logdepth_decode_normalized(float z);
 
 float sample_shadow_map(vec2 coord, vec2 offset, float depth)
 {
@@ -164,8 +166,9 @@ float get_contact_shadow(vec3 P, vec3 L, mat4 projection_matrix)
         float t = (float(i) + dither) * dt;
         vec3 x_t = ray_start + ray_dir * t;
 
-        // Sample the depth buffer. It's reversed, so invert it
-        float z = 1.0 - texture(depth_tex, x_t.xy).r;
+        // Sample the depth buffer
+        float z = texture(depth_tex, x_t.xy).r;
+        z = logdepth_decode_normalized(z);
         // Depth difference between the current ray sample depth and the actual
         // camera depth contained in the depth buffer.
         float dz = x_t.z - z - sss_depth_bias;
diff --git a/Shaders/HDR/terrain_default.frag b/Shaders/HDR/terrain_default.frag
index 939567282..200860dfb 100644
--- a/Shaders/HDR/terrain_default.frag
+++ b/Shaders/HDR/terrain_default.frag
@@ -1,6 +1,7 @@
 #version 330 core
 
 in VS_OUT {
+    float flogz;
     vec2 texcoord;
     vec2 orthophoto_texcoord;
     vec3 vertex_normal;
@@ -19,6 +20,8 @@ void gbuffer_pack(vec3 normal, vec3 base_color, float metallic, float roughness,
                   float occlusion, vec3 emissive, uint mat_id);
 // color.glsl
 vec3 eotf_inverse_sRGB(vec3 srgb);
+// logarithmic_depth.glsl
+float logdepth_encode(float z);
 
 void main()
 {
@@ -35,4 +38,5 @@ void main()
     vec3 N = normalize(fs_in.vertex_normal);
 
     gbuffer_pack(N, color, TERRAIN_METALLIC, TERRAIN_ROUGHNESS, 1.0, vec3(0.0), 3u);
+    gl_FragDepth = logdepth_encode(fs_in.flogz);
 }
diff --git a/Shaders/HDR/terrain_default.vert b/Shaders/HDR/terrain_default.vert
index c3968027a..d2accdbbe 100644
--- a/Shaders/HDR/terrain_default.vert
+++ b/Shaders/HDR/terrain_default.vert
@@ -6,6 +6,7 @@ layout(location = 3) in vec4 multitexcoord0;
 layout(location = 5) in vec4 multitexcoord2;
 
 out VS_OUT {
+    float flogz;
     vec2 texcoord;
     vec2 orthophoto_texcoord;
     vec3 vertex_normal;
@@ -14,9 +15,13 @@ out VS_OUT {
 uniform mat4 osg_ModelViewProjectionMatrix;
 uniform mat3 osg_NormalMatrix;
 
+// logarithmic_depth.glsl
+float logdepth_prepare_vs_depth(float z);
+
 void main()
 {
     gl_Position = osg_ModelViewProjectionMatrix * pos;
+    vs_out.flogz = logdepth_prepare_vs_depth(gl_Position.w);
     vs_out.texcoord = multitexcoord0.st;
     vs_out.orthophoto_texcoord = multitexcoord2.st;
     vs_out.vertex_normal = osg_NormalMatrix * normal;
diff --git a/Shaders/HDR/terrain_lfeat.frag b/Shaders/HDR/terrain_lfeat.frag
index 24b958630..026345dc0 100644
--- a/Shaders/HDR/terrain_lfeat.frag
+++ b/Shaders/HDR/terrain_lfeat.frag
@@ -1,6 +1,7 @@
 #version 330 core
 
 in VS_OUT {
+    float flogz;
     vec2 texcoord;
     vec3 vertex_normal;
 } fs_in;
@@ -12,6 +13,8 @@ void gbuffer_pack(vec3 normal, vec3 base_color, float metallic, float roughness,
                   float occlusion, vec3 emissive, uint mat_id);
 // color.glsl
 vec3 eotf_inverse_sRGB(vec3 srgb);
+// logarithmic_depth.glsl
+float logdepth_encode(float z);
 
 void main()
 {
@@ -24,4 +27,5 @@ void main()
     vec3 N = normalize(fs_in.vertex_normal);
 
     gbuffer_pack(N, color, 0.0, 0.9, 1.0, vec3(0.0), 3u);
+    gl_FragDepth = logdepth_encode(fs_in.flogz);
 }
diff --git a/Shaders/HDR/terrain_lfeat.vert b/Shaders/HDR/terrain_lfeat.vert
index 0a1cf10d1..5166ef0b9 100644
--- a/Shaders/HDR/terrain_lfeat.vert
+++ b/Shaders/HDR/terrain_lfeat.vert
@@ -5,6 +5,7 @@ layout(location = 1) in vec3 normal;
 layout(location = 3) in vec4 multitexcoord0;
 
 out VS_OUT {
+    float flogz;
     vec2 texcoord;
     vec3 vertex_normal;
 } vs_out;
@@ -12,12 +13,16 @@ out VS_OUT {
 uniform mat4 osg_ModelViewProjectionMatrix;
 uniform mat3 osg_NormalMatrix;
 
+// logarithmic_depth.glsl
+float logdepth_prepare_vs_depth(float z);
+
 void main()
 {
     vec4 raised_pos = pos;
     raised_pos.z += 0.05;
 
     gl_Position = osg_ModelViewProjectionMatrix * raised_pos;
+    vs_out.flogz = logdepth_prepare_vs_depth(gl_Position.w);
     vs_out.texcoord = multitexcoord0.st;
     vs_out.vertex_normal = osg_NormalMatrix * normal;
 }
diff --git a/Shaders/HDR/terrain_runway.frag b/Shaders/HDR/terrain_runway.frag
index 71f76c385..1e09cc99f 100644
--- a/Shaders/HDR/terrain_runway.frag
+++ b/Shaders/HDR/terrain_runway.frag
@@ -1,6 +1,7 @@
 #version 330 core
 
 in VS_OUT {
+    float flogz;
     vec2 texcoord;
     vec3 vertex_normal;
     vec3 view_vector;
@@ -19,6 +20,8 @@ void gbuffer_pack(vec3 normal, vec3 base_color, float metallic, float roughness,
 vec3 eotf_inverse_sRGB(vec3 srgb);
 // normalmap.glsl
 vec3 perturb_normal(vec3 N, vec3 V, vec2 texcoord);
+// logarithmic_depth.glsl
+float logdepth_encode(float z);
 
 void main()
 {
@@ -39,4 +42,5 @@ void main()
     float roughness = mix(0.94, 0.98, mix_factor);
 
     gbuffer_pack(N, color, 0.0, roughness, 1.0, vec3(0.0), 3u);
+    gl_FragDepth = logdepth_encode(fs_in.flogz);
 }
diff --git a/Shaders/HDR/terrain_runway.vert b/Shaders/HDR/terrain_runway.vert
index e82736c46..7b81c07a8 100644
--- a/Shaders/HDR/terrain_runway.vert
+++ b/Shaders/HDR/terrain_runway.vert
@@ -5,6 +5,7 @@ layout(location = 1) in vec3 normal;
 layout(location = 3) in vec4 multitexcoord0;
 
 out VS_OUT {
+    float flogz;
     vec2 texcoord;
     vec3 vertex_normal;
     vec3 view_vector;
@@ -15,9 +16,13 @@ uniform mat4 osg_ModelViewMatrix;
 uniform mat4 osg_ModelViewProjectionMatrix;
 uniform mat3 osg_NormalMatrix;
 
+// logarithmic_depth.glsl
+float logdepth_prepare_vs_depth(float z);
+
 void main()
 {
     gl_Position = osg_ModelViewProjectionMatrix * pos;
+    vs_out.flogz = logdepth_prepare_vs_depth(gl_Position.w);
     vs_out.texcoord = multitexcoord0.st;
     vs_out.vertex_normal = osg_NormalMatrix * normal;
     vs_out.view_vector = (osg_ModelViewMatrix * pos).xyz;
diff --git a/Shaders/HDR/text.frag b/Shaders/HDR/text.frag
index be3733225..d435eb0cf 100644
--- a/Shaders/HDR/text.frag
+++ b/Shaders/HDR/text.frag
@@ -3,6 +3,7 @@
 layout(location = 0) out vec4 fragColor;
 
 in VS_OUT {
+    float flogz;
     vec2 texcoord;
     vec3 vertex_normal;
     vec3 view_vector;
@@ -27,6 +28,8 @@ vec3 eval_lights_transparent(
     vec3 base_color, float metallic, float roughness, float occlusion,
     vec3 emissive, vec3 P, vec3 N, vec3 V, vec2 uv, vec4 ap,
     mat4 view_matrix_inverse);
+// logarithmic_depth.glsl
+float logdepth_encode(float z);
 
 void main()
 {
@@ -41,4 +44,5 @@ void main()
         fs_in.view_vector, N, V, uv, fs_in.ap_color, osg_ViewMatrixInverse);
 
     fragColor = vec4(color, alpha);
+    gl_FragDepth = logdepth_encode(fs_in.flogz);
 }
diff --git a/Shaders/HDR/text.vert b/Shaders/HDR/text.vert
index 87c61389f..7ae9f0ee9 100644
--- a/Shaders/HDR/text.vert
+++ b/Shaders/HDR/text.vert
@@ -5,6 +5,7 @@ layout(location = 1) in vec3 normal;
 layout(location = 3) in vec4 multitexcoord0;
 
 out VS_OUT {
+    float flogz;
     vec2 texcoord;
     vec3 vertex_normal;
     vec3 view_vector;
@@ -18,10 +19,13 @@ uniform mat4 fg_TextureMatrix;
 
 // aerial_perspective.glsl
 vec4 get_aerial_perspective(vec2 coord, float depth);
+// logarithmic_depth.glsl
+float logdepth_prepare_vs_depth(float z);
 
 void main()
 {
     gl_Position = osg_ModelViewProjectionMatrix * pos;
+    vs_out.flogz = logdepth_prepare_vs_depth(gl_Position.w);
     vs_out.texcoord = vec2(fg_TextureMatrix * multitexcoord0);
     vs_out.vertex_normal = osg_NormalMatrix * normal;
     vs_out.view_vector = (osg_ModelViewMatrix * pos).xyz;
diff --git a/Shaders/HDR/tree.frag b/Shaders/HDR/tree.frag
index c37c32303..2b3563ee1 100644
--- a/Shaders/HDR/tree.frag
+++ b/Shaders/HDR/tree.frag
@@ -1,6 +1,7 @@
 #version 330 core
 
 in VS_OUT {
+    float flogz;
     vec2 texcoord;
     vec3 vertex_normal;
     float autumn_flag;
@@ -15,6 +16,8 @@ void gbuffer_pack(vec3 normal, vec3 base_color, float metallic, float roughness,
                   float occlusion, vec3 emissive, uint mat_id);
 // color.glsl
 vec3 eotf_inverse_sRGB(vec3 srgb);
+// logarithmic_depth.glsl
+float logdepth_encode(float z);
 
 void main()
 {
@@ -33,4 +36,5 @@ void main()
     vec3 N = normalize(fs_in.vertex_normal);
 
     gbuffer_pack(N, color, 0.0, 1.0, 1.0, vec3(0.0), 3u);
+    gl_FragDepth = logdepth_encode(fs_in.flogz);
 }
diff --git a/Shaders/HDR/tree.vert b/Shaders/HDR/tree.vert
index b79057dc5..31457eec2 100644
--- a/Shaders/HDR/tree.vert
+++ b/Shaders/HDR/tree.vert
@@ -7,6 +7,7 @@ layout(location = 3) in vec4 multitexcoord0;
 layout(location = 12) in float fogcoord;
 
 out VS_OUT {
+    float flogz;
     vec2 texcoord;
     vec3 vertex_normal;
     float autumn_flag;
@@ -25,6 +26,8 @@ uniform mat4 osg_ModelViewProjectionMatrix;
 
 // noise.glsl
 float voronoi_noise_2d(vec2 coord, float wavelength, float xrand, float yrand);
+// logarithmic_depth.glsl
+float logdepth_prepare_vs_depth(float z);
 
 void main()
 {
@@ -67,6 +70,7 @@ void main()
 
     position = position + vertex_color.xyz;
     gl_Position = osg_ModelViewProjectionMatrix * vec4(position, 1.0);
+    vs_out.flogz = logdepth_prepare_vs_depth(gl_Position.w);
 
     vec3 view_vector = (osg_ModelViewMatrix * vec4(position, 1.0)).xyz;
     vs_out.vertex_normal = normalize(-view_vector);
diff --git a/Shaders/HDR/water.frag b/Shaders/HDR/water.frag
index f6f09bad8..420d772dc 100644
--- a/Shaders/HDR/water.frag
+++ b/Shaders/HDR/water.frag
@@ -4,6 +4,7 @@ layout(location = 0) out vec4 out_gbuffer0;
 layout(location = 1) out vec4 out_gbuffer1;
 
 in VS_OUT {
+    float flogz;
     vec2 water_texcoord;
     vec2 topo_texcoord;
     vec3 vertex_normal;
@@ -29,6 +30,8 @@ vec2 encode_normal(vec3 n);
 vec3 eotf_inverse_sRGB(vec3 srgb);
 // normalmap.glsl
 mat3 cotangent_frame(vec3 N, vec3 p, vec2 uv);
+// logarithmic_depth.glsl
+float logdepth_encode(float z);
 
 void get_rotation_matrix(float angle, out mat2 rotmat)
 {
@@ -63,4 +66,6 @@ void main()
 
     out_gbuffer0.rg  = encode_normal(N);
     out_gbuffer1.rgb = floor_color;
+
+    gl_FragDepth = logdepth_encode(fs_in.flogz);
 }
diff --git a/Shaders/HDR/water.vert b/Shaders/HDR/water.vert
index 8390efa1b..2bd9c633e 100644
--- a/Shaders/HDR/water.vert
+++ b/Shaders/HDR/water.vert
@@ -4,6 +4,7 @@ layout(location = 0) in vec4 pos;
 layout(location = 3) in vec4 multiTexCoord0;
 
 out VS_OUT {
+    float flogz;
     vec2 water_texcoord;
     vec2 topo_texcoord;
     vec3 vertex_normal;
@@ -22,6 +23,9 @@ const float squash = 0.9966471893352525192801545;
 const float latAdjust = 0.9999074159800018; //geotiff source for the depth map
 const float lonAdjust = 0.9999537058469516; //actual extents: +-180.008333333333326/+-90.008333333333340
 
+// logarithmic_depth.glsl
+float logdepth_prepare_vs_depth(float z);
+
 void get_rotation_matrix(float angle, out mat4 rotmat)
 {
     rotmat = mat4(cos(angle), -sin(angle), 0.0, 0.0,
@@ -71,6 +75,7 @@ vec2 get_topo_coords(vec3 rawPos)
 void main()
 {
     gl_Position = osg_ModelViewProjectionMatrix * pos;
+    vs_out.flogz = logdepth_prepare_vs_depth(gl_Position.w);
     vs_out.water_texcoord = multiTexCoord0.st;
     vs_out.vertex_normal = osg_NormalMatrix * vec3(0.0, 0.0, 1.0);
     vs_out.view_vector = (osg_ModelViewMatrix * pos).xyz;