diff --git a/modules/gfx/src/impl/scene_fx.cc b/modules/gfx/src/impl/scene_fx.cc
index c1f87182e48c09e4f9102a56904117dac0bfab63..a9ddbc4cd9f8fc7e7d235efae0c8ce390c422d71 100644
--- a/modules/gfx/src/impl/scene_fx.cc
+++ b/modules/gfx/src/impl/scene_fx.cc
@@ -224,6 +224,11 @@ void SceneFX::Preprocess()
   }
 }
 
+bool SceneFX::WillPostprocess() const
+{
+  return shadow_flag || amb_occl_flag || depth_dark_flag || use_beacon;
+}
+
 void SceneFX::Postprocess()
 {
   if(!OST_GL_VERSION_2_0) return;
@@ -235,10 +240,7 @@ void SceneFX::Postprocess()
 #endif
   }
 
-  if(!shadow_flag && !amb_occl_flag && !depth_dark_flag && !use_beacon) {
-    // no postprocessing is needed
-    return;
-  }
+  if(!WillPostprocess()) return;
 
   Viewport vp=Scene::Instance().GetViewport();
 
@@ -329,6 +331,18 @@ void SceneFX::Postprocess()
     glUniform1i(glGetUniformLocation(cpr,"dark_flag"),0);
   }
 
+  GLint fog;
+  glGetIntegerv(GL_FOG,&fog);
+  float znear=Scene::Instance().GetNear();
+  float zfar=Scene::Instance().GetFar();
+  float fnear=znear+Scene::Instance().GetFogNearOffset();
+  float ffar=zfar+Scene::Instance().GetFogFarOffset();
+  glUniform1i(glGetUniformLocation(cpr,"fog_flag"),fog);
+  glUniform1f(glGetUniformLocation(cpr,"depth_near"),znear);
+  glUniform1f(glGetUniformLocation(cpr,"depth_far"),zfar);
+  glUniform1f(glGetUniformLocation(cpr,"fog_far"),ffar);
+  glUniform1f(glGetUniformLocation(cpr,"fog_scale"),1.0f/(ffar-fnear));
+
   if(use_beacon) {
     prep_beacon();
   }
diff --git a/modules/gfx/src/impl/scene_fx.hh b/modules/gfx/src/impl/scene_fx.hh
index 3b8e1fa388b67ea0c51be27676b437875c0e7aa6..ad8d2a787c57a7b4e9eb1433fd5d8e1f4c63d173 100644
--- a/modules/gfx/src/impl/scene_fx.hh
+++ b/modules/gfx/src/impl/scene_fx.hh
@@ -53,6 +53,9 @@ public:
   void Preprocess();
   // assumes scene has been drawn in the active framebuffer
   void Postprocess();
+  
+  // returns true if the post-processing will run
+  bool WillPostprocess() const;
 
   void DrawTex(unsigned int w, unsigned int h, GLuint texid);
 
diff --git a/modules/gfx/src/shader.cc b/modules/gfx/src/shader.cc
index 2a5e91ce25fa41c121ae12ecca5a6a2f08a82e68..3ed15cac334785fbb45e4d1b63fb91d62c70f599 100644
--- a/modules/gfx/src/shader.cc
+++ b/modules/gfx/src/shader.cc
@@ -28,6 +28,7 @@
 #include <ost/platform.hh>
 #include <ost/log.hh>
 
+#include "impl/scene_fx.hh"
 #include "glext_include.hh"
 
 #include "shader.hh"
@@ -366,7 +367,11 @@ void Shader::UpdateState()
     glGetBooleanv(GL_LIGHT_MODEL_TWO_SIDE,&bresult);
     LOG_TRACE("setting two_sided flag to " << bresult);
     glUniform1i(glGetUniformLocation(current_program_,"two_sided_flag"),bresult);
-    glGetIntegerv(GL_FOG,&result);
+    if(impl::SceneFX::Instance().WillPostprocess()) {
+      result=0;
+    } else {
+      glGetIntegerv(GL_FOG,&result);
+    }
     LOG_TRACE("setting fog flag to " << result);
     glUniform1i(glGetUniformLocation(current_program_,"fog_flag"),result);
     glDisable(GL_COLOR_MATERIAL);
diff --git a/modules/gfx/src/shader/scenefx_fs.glsl b/modules/gfx/src/shader/scenefx_fs.glsl
index cb5c2313c77dced05f81fdd4854704ebbb4b9a6c..e328d2d086842e680c79329ab1fdaafd204d9cea 100644
--- a/modules/gfx/src/shader/scenefx_fs.glsl
+++ b/modules/gfx/src/shader/scenefx_fs.glsl
@@ -13,6 +13,11 @@ uniform float occl_mult;
 uniform bool dark_flag;
 uniform sampler2D dark_map;
 uniform float dark_mult;
+uniform bool fog_flag;
+uniform float depth_near;
+uniform float depth_far;
+uniform float fog_far;
+uniform float fog_scale;
 
 // gl_TexCoord[0] comes from scenefx_vs, i.e. from post processing
 
@@ -55,6 +60,15 @@ void main()
   if(dark_flag) {
     dark_factor=max(0.0,1.0-dark_mult*(1.0-texture2D(dark_map,gl_TexCoord[0].xy).r));
   }
-    
-  gl_FragColor.rgb = shadow_factor*occl_factor*dark_factor*scene_color.rgb;
+
+  float fog=1.0;
+  if(fog_flag) {
+    float z = 2.0*depth_near*depth_far/(-(depth*2.0-1.0)*(depth_far-depth_near)+depth_far+depth_near);
+    fog = clamp((fog_far-z) * fog_scale, 0.0, 1.0);
+  }
+
+  gl_FragColor.rgb = mix(gl_Fog.color.rgb, 
+                         shadow_factor*occl_factor*dark_factor*scene_color.rgb,
+                         fog);
 }
+