diff --git a/modules/gfx/src/CMakeLists.txt b/modules/gfx/src/CMakeLists.txt
index 8de2ae86c0fec224a64a4e8fc7e65a2dc0c8e1ea..1e17c9008ebd4a3711bc1302735237528d28df59 100644
--- a/modules/gfx/src/CMakeLists.txt
+++ b/modules/gfx/src/CMakeLists.txt
@@ -192,6 +192,8 @@ if (USE_SHADER)
   message("Compiling with Shader Support")
   list(APPEND OST_GFX_SOURCES shader.cc)
   list(APPEND OST_GFX_HEADERS shader.hh)
+  list(APPEND OST_GFX_SOURCES impl/scene_fx.cc)
+  list(APPEND OST_GFX_IMPL_HEADERS scene_fx.hh)
   if (NOT APPLE)
     set(OST_GLEW_HEADERS
        glew.h
@@ -240,8 +242,9 @@ if (USE_SHADER)
     shader/fast_sphere_vs.glsl
     shader/fast_sphere_fs.glsl
     shader/outline_vs.glsl
-    shader/convolute1_vs.glsl
+    shader/quadpp_vs.glsl
     shader/convolute1_fs.glsl
+    shader/amboccl_fs.glsl
   )
   copy_if_different("./" "${SHARED_DATA_PATH}/shader" "${SHADER_FILES}" 
                     "SHADER_TARGETS" ost_gfx)  
diff --git a/modules/gfx/src/impl/scene_fx.cc b/modules/gfx/src/impl/scene_fx.cc
new file mode 100644
index 0000000000000000000000000000000000000000..7e6d8033f1521e0b37273c3a4d03bdb0502185b7
--- /dev/null
+++ b/modules/gfx/src/impl/scene_fx.cc
@@ -0,0 +1,259 @@
+#include "scene_fx.hh"
+
+#include <ost/gfx/gfx_node.hh>
+#include <ost/gfx/shader.hh>
+#include <ost/gfx/scene.hh>
+
+namespace ost { namespace gfx { namespace impl {
+
+void prep_shadow_map(Scene& scene, GLuint texunit, GLuint texid, uint quality)
+{
+  GLint smap_size=256 << quality;
+
+  // modelview transform for the lightsource pov
+  mol::Transform ltrans(scene.GetTransform());
+  ltrans.SetRot(scene.GetLightRot()*scene.GetTransform().GetRot());
+
+  // calculate encompassing box for ortho projection
+  geom::AlignedCuboid bb=scene.GetBoundingBox(ltrans);
+  geom::Vec3 tmin=bb.GetMin();
+  geom::Vec3 tmax=bb.GetMax();
+
+  // render pass 1 - without shadows
+
+  // turn shadowing off for subsequent rendering
+  Shader::Instance().SetShadowMapping(false,0);
+
+  // save overall gl settings
+  glPushAttrib(GL_VIEWPORT_BIT | GL_ENABLE_BIT);
+  // maximize rendering for depth-only information
+  glDisable(GL_LIGHTING);
+  glDisable(GL_FOG);
+  glDisable(GL_COLOR_MATERIAL);
+  glDisable(GL_NORMALIZE);
+  glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
+
+  // render scene with only depth components
+  // seen from the light's perspective
+  glViewport(0,0,smap_size,smap_size);
+  glClear(GL_DEPTH_BUFFER_BIT);
+
+  glMatrixMode(GL_PROJECTION);
+  glPushMatrix();
+  glLoadIdentity();
+  glOrtho(tmin[0],tmax[0],tmin[1],tmax[1],-tmax[2],-tmin[2]);
+  //glFrustum(tmin[0],tmax[0],tmin[1],tmax[1],-tmax[2],-tmin[2]);
+  float glpmat[16];
+  glGetv(GL_PROJECTION_MATRIX, glpmat);
+  geom::Mat4 pmat(Transpose(geom::Mat4(glpmat)));
+
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+  glLoadIdentity();
+  glMultMatrix(ltrans.GetTransposedMatrix().Data());
+
+  // only render non-transparent objects for the shadow map
+  scene.GetRootNode()->RenderGL(DEPTH_RENDER_PASS);
+
+  // now get the shadow map
+  glActiveTexture(GL_TEXTURE0+texunit);
+  glBindTexture(GL_TEXTURE_2D, texid);
+
+  glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT,
+                   0,0, smap_size,smap_size, 0);
+
+  // all of the following texture and shader params need to be moved
+  // to a one-time initialization place
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+  //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+  //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+
+  // assign tex unit 0 to shadow map
+  Shader::Instance().SetShadowMapping(true,texunit);
+
+  // restore settings
+  glPopMatrix();
+  glMatrixMode(GL_PROJECTION);
+  glPopMatrix();
+  glMatrixMode(GL_MODELVIEW);
+
+  glPopAttrib();
+  glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
+
+  glEnable(GL_TEXTURE_2D);
+
+  // set up appropriate texture matrix
+  geom::Mat4 bias(0.5,0.0,0.0,0.5,
+                  0.0,0.5,0.0,0.5,
+                  0.0,0.0,0.5,0.5,
+                  0.0,0.0,0.0,1.0);
+  
+  geom::Mat4 texm = bias*pmat*ltrans.GetMatrix();
+
+  glMatrixMode(GL_TEXTURE);
+  // make explicit object instead of temporary to avoid potential crash with Data()
+  geom::Mat4 ttmp=Transpose(texm);
+  glLoadMatrix(ttmp.Data());
+  glMatrixMode(GL_MODELVIEW);
+}
+
+void prep_amb_occlusion(Scene& scene, GLuint texunit, GLuint texid)
+{
+}
+
+void prep_depth_darkening(Scene& scene, GLuint texunit, GLuint texid)
+{
+  Viewport vp=scene.GetViewport();
+  prep_depth_map(scene,vp.width/2,vp.height/2,texunit,texid);
+
+  // kernel is static for now, inside the convolution shader
+
+  // now convolute the depth map with the kernel
+  Shader::Instance().PushProgram();
+  Shader::Instance().Activate("convolute1");
+  GLuint cpr=Shader::Instance().GetCurrentProgram();
+  // assign tex units
+  glUniform1i(glGetUniformLocation(cpr,"data"),1);
+  glUniform1i(glGetUniformLocation(cpr,"vp_width"),vp.width/2);
+  glUniform1i(glGetUniformLocation(cpr,"vp_height"),vp.height/2);
+
+  // set up viewport filling quad to run the fragment shader
+  draw_screen_quad(vp.width/2,vp.height/2,texunit, texid);
+
+  Shader::Instance().PopProgram();
+
+  // mode 1, tex unit 1
+  Shader::Instance().SetDepthMapping(1,texunit);
+}
+
+void prep_depth_map(Scene& scene, unsigned int width, unsigned int height,GLuint texunit, GLuint texid)
+{
+  // render pass 1 - without shadows
+  Shader::Instance().SetShadowMapping(false,0);
+  // save overall gl settings
+  glPushAttrib(GL_ENABLE_BIT | GL_VIEWPORT_BIT | GL_COLOR_BUFFER_BIT);
+  // maximize rendering for depth-only information
+  glDisable(GL_LIGHTING);
+  glDisable(GL_FOG);
+  glDisable(GL_COLOR_MATERIAL);
+  glDisable(GL_NORMALIZE);
+  glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
+
+  // render scene with only depth components
+  glClear(GL_DEPTH_BUFFER_BIT);
+  glViewport(0,0,width,height);
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+  glLoadIdentity();
+  glMultMatrix(scene.GetTransform().GetTransposedMatrix().Data());
+  scene.GetRootNode()->RenderGL(DEPTH_RENDER_PASS);
+
+  // now get the depth map
+  glActiveTexture(texunit);
+  glBindTexture(GL_TEXTURE_2D, texid);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+  glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 0,0, width, height, 0);
+
+  // restore settings
+  glMatrixMode(GL_PROJECTION);
+  glPopMatrix();
+  glMatrixMode(GL_MODELVIEW);
+  glPopMatrix();
+  glPopAttrib();
+  glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
+}
+
+void draw_screen_quad(unsigned int w, unsigned int h, GLuint gltex, GLuint tex_id) 
+{
+  glPushAttrib(GL_ENABLE_BIT | GL_VIEWPORT_BIT | GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_FOG_BIT);
+  
+  // setup
+  glDisable(GL_DEPTH_TEST);
+  glDisable(GL_LIGHTING);
+  glDisable(GL_COLOR_MATERIAL);
+  glDisable(GL_FOG);
+  glDisable(GL_CULL_FACE);
+  glDisable(GL_BLEND);
+  glDisable(GL_LINE_SMOOTH);
+  glDisable(GL_POINT_SMOOTH);
+  glClear(GL_COLOR_BUFFER_BIT);
+  glViewport(0,0,w,h);
+  glMatrixMode(GL_PROJECTION);
+  glPushMatrix();
+  glLoadIdentity();
+  glOrtho(0,1,0,1,-1,1);
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+  glLoadIdentity();
+  
+  // draw
+  glColor3f(1.0,0.0,1.0);
+  glBegin(GL_QUADS);
+  glTexCoord2f(0.0,0.0);
+  glVertex2f(0.0,0.0);
+  glTexCoord2f(0.0,1.0);
+  glVertex2f(0.0,1.0);
+  glTexCoord2f(1.0,1.0);
+  glVertex2f(1.0,1.0);
+  glTexCoord2f(1.0,0.0);
+  glVertex2f(1.0,0.0);
+  glEnd();
+  
+  // grab the result
+  glEnable(GL_TEXTURE_2D);
+  glActiveTexture(gltex);
+  glBindTexture(GL_TEXTURE_2D, tex_id);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+  glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0,0, w, h, 0);
+  
+  // restore settings
+  glMatrixMode(GL_PROJECTION);
+  glPopMatrix();
+  glMatrixMode(GL_MODELVIEW);
+  glPopMatrix();
+  glPopAttrib();
+}
+
+// this debug code draws the given texture across the complete screen
+void draw_debug_tex(unsigned int w, unsigned int h, GLuint texid)
+{
+  glPushAttrib(GL_ALL_ATTRIB_BITS);
+  Shader::Instance().PushProgram();
+  
+  Shader::Instance().Activate("");
+  glViewport(0,0,w,h);
+  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+  glMatrixMode(GL_PROJECTION);
+  glLoadIdentity();
+  glOrtho(0,1,0,1,-1,1);
+  glMatrixMode(GL_MODELVIEW);
+  glLoadIdentity();
+  glColor3f(1.0,0.0,1.0);
+  glEnable(GL_TEXTURE_2D);
+  glActiveTexture(GL_TEXTURE0);
+  glBindTexture(GL_TEXTURE_2D, texid);
+  glBegin(GL_QUADS);
+  glTexCoord2f(0.0,0.0);
+  glVertex2f(0.01,0.01);
+  glTexCoord2f(0.0,1.0);
+  glVertex2f(0.01,0.99);
+  glTexCoord2f(1.0,1.0);
+  glVertex2f(0.99,0.99);
+  glTexCoord2f(1.0,0.0);
+  glVertex2f(0.99,0.01);
+  glEnd();
+  glPopAttrib();
+  Shader::Instance().PopProgram();
+}
+
+
+}}} // ns
diff --git a/modules/gfx/src/impl/scene_fx.hh b/modules/gfx/src/impl/scene_fx.hh
new file mode 100644
index 0000000000000000000000000000000000000000..5c407e8be1899f99ec99a810e58de347471422f1
--- /dev/null
+++ b/modules/gfx/src/impl/scene_fx.hh
@@ -0,0 +1,45 @@
+//------------------------------------------------------------------------------
+// This file is part of the OpenStructure project <www.openstructure.org>
+//
+// Copyright (C) 2008-2010 by the OpenStructure authors
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3.0 of the License, or (at your option)
+// any later version.
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//------------------------------------------------------------------------------
+#ifndef OST_SCENE_FX_HH
+#define OST_SCENE_FX_HH
+
+#include <ost/gfx/gl_helper.hh>
+
+/*
+  low level code for scene shading effects
+
+  Author: Ansgar Philippsen
+*/
+
+namespace ost { namespace gfx { 
+
+class Scene;
+
+namespace impl {
+
+void prep_shadow_map(Scene& scene, GLuint texunit, GLuint texid, uint quality);
+void prep_depth_darkening(Scene& scene, GLuint texunit, GLuint texid);
+void prep_amb_occlusion(Scene& scene, GLuint texunit, GLuint texid);
+void prep_depth_map(Scene& scene, uint, uint, GLuint texunit, GLuint texid);
+void draw_screen_quad(unsigned int w, unsigned int h, GLuint texunit, GLuint texid);
+void draw_debug_tex(unsigned int w, unsigned int h, GLuint texid);
+
+}}} // ns
+
+#endif
diff --git a/modules/gfx/src/scene.cc b/modules/gfx/src/scene.cc
index 181120438e325e610919e2c1d19ea0729f444b65..5a8222295e22f6336f574ba2e526071706d0422d 100644
--- a/modules/gfx/src/scene.cc
+++ b/modules/gfx/src/scene.cc
@@ -54,6 +54,7 @@
 
 #if OST_SHADER_SUPPORT_ENABLED
 # include "shader.hh"
+# include "impl/scene_fx.hh"
 #endif
 
 using boost::bind;
@@ -112,6 +113,7 @@ Scene::Scene():
   shadow_quality_(1),
   shadow_tex_id_(),
   depth_dark_flag_(false),
+  amb_occl_flag_(false),
   depth_tex_id_(),
   kernel_tex_id_(),
   scene_tex_id_(),
@@ -186,6 +188,13 @@ void Scene::SetDepthDarkening(bool f)
   RequestRedraw();
 }
 
+void Scene::SetAmbientOcclusion(bool f)
+{
+  amb_occl_flag_=f;
+  // the redraw routine will deal with the Shader
+  RequestRedraw();
+}
+
 
 void Scene::SetShadingMode(const std::string& smode)
 {
@@ -498,13 +507,18 @@ void Scene::RenderGL()
   if(auto_autoslab_) Autoslab(false, false);
 
   #if OST_SHADER_SUPPORT_ENABLED
+  if(amb_occl_flag_) {
+    impl::prep_amb_occlusion(*this,GL_TEXTURE1, depth_tex_id_);
+  } else {
+    Shader::Instance().SetOcclusionMapping(0,0);
+  }
   if(depth_dark_flag_) {
-    prep_depth_darkening();
+    impl::prep_depth_darkening(*this,GL_TEXTURE1, depth_tex_id_);
   } else {
     Shader::Instance().SetDepthMapping(0,0);
   }
   if(shadow_flag_) {
-    prep_shadow_map();
+    impl::prep_shadow_map(*this,GL_TEXTURE0,shadow_tex_id_,shadow_quality_);
   } else {
     Shader::Instance().SetShadowMapping(0,0);
   }
@@ -1571,268 +1585,6 @@ void Scene::update_fog()
   glFogf(GL_FOG_END,zfar_+ffar_);
 }
 
-namespace {
-
-  void draw_screen_quad(unsigned int w, unsigned int h, GLuint gltex, GLuint tex_id)
-  {
-    glPushAttrib(GL_ENABLE_BIT | GL_VIEWPORT_BIT | GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_FOG_BIT);
-
-    // setup
-    glDisable(GL_DEPTH_TEST);
-    glDisable(GL_LIGHTING);
-    glDisable(GL_COLOR_MATERIAL);
-    glDisable(GL_FOG);
-    glDisable(GL_CULL_FACE);
-    glDisable(GL_BLEND);
-    glDisable(GL_LINE_SMOOTH);
-    glDisable(GL_POINT_SMOOTH);
-    glClear(GL_COLOR_BUFFER_BIT);
-    glViewport(0,0,w,h);
-    glMatrixMode(GL_PROJECTION);
-    glPushMatrix();
-    glLoadIdentity();
-    glOrtho(0,1,0,1,-1,1);
-    glMatrixMode(GL_MODELVIEW);
-    glPushMatrix();
-    glLoadIdentity();
-
-    // draw
-    glColor3f(1.0,0.0,1.0);
-    glBegin(GL_QUADS);
-    glTexCoord2f(0.0,0.0);
-    glVertex2f(0.0,0.0);
-    glTexCoord2f(0.0,1.0);
-    glVertex2f(0.0,1.0);
-    glTexCoord2f(1.0,1.0);
-    glVertex2f(1.0,1.0);
-    glTexCoord2f(1.0,0.0);
-    glVertex2f(1.0,0.0);
-    glEnd();
-  
-    // grab the result
-    glEnable(GL_TEXTURE_2D);
-    glActiveTexture(gltex);
-    glBindTexture(GL_TEXTURE_2D, tex_id);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
-    glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0,0, w, h, 0);
-
-    // restore settings
-    glMatrixMode(GL_PROJECTION);
-    glPopMatrix();
-    glMatrixMode(GL_MODELVIEW);
-    glPopMatrix();
-    glPopAttrib();
-  }
-
-  // this debug code draws the given texture across the complete screen
-  void draw_debug_tex(unsigned int w, unsigned int h, GLuint tex_id)
-  {
-    glPushAttrib(GL_ALL_ATTRIB_BITS);
-    Shader::Instance().PushProgram();
-
-    Shader::Instance().Activate("");
-    glViewport(0,0,w,h);
-    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-    glMatrixMode(GL_PROJECTION);
-    glLoadIdentity();
-    glOrtho(0,1,0,1,-1,1);
-    glMatrixMode(GL_MODELVIEW);
-    glLoadIdentity();
-    glColor3f(1.0,0.0,1.0);
-    glEnable(GL_TEXTURE_2D);
-    glActiveTexture(GL_TEXTURE0);
-    glBindTexture(GL_TEXTURE_2D, tex_id);
-    glBegin(GL_QUADS);
-    glTexCoord2f(0.0,0.0);
-    glVertex2f(0.01,0.01);
-    glTexCoord2f(0.0,1.0);
-    glVertex2f(0.01,0.99);
-    glTexCoord2f(1.0,1.0);
-    glVertex2f(0.99,0.99);
-    glTexCoord2f(1.0,0.0);
-    glVertex2f(0.99,0.01);
-    glEnd();
-    glPopAttrib();
-    Shader::Instance().PopProgram();
-  }
-}
-
-void Scene::prep_shadow_map()
-{
-#if OST_SHADER_SUPPORT_ENABLED
-  GLint smap_size=256 << shadow_quality_;
-
-  // modelview transform for the lightsource pov
-  mol::Transform ltrans(transform_);
-  ltrans.SetRot(light_rot_*transform_.GetRot());
-
-  // calculate encompassing box for ortho projection
-  geom::AlignedCuboid bb=this->GetBoundingBox(ltrans);
-  const Vec3& tmin=bb.GetMin();
-  const Vec3& tmax=bb.GetMax();
-
-  // render pass 1 - without shadows
-
-  // turn shadowing off for subsequent rendering
-  Shader::Instance().SetShadowMapping(false,0);
-
-  // save overall gl settings
-  glPushAttrib(GL_VIEWPORT_BIT | GL_ENABLE_BIT);
-  // maximize rendering for depth-only information
-  glDisable(GL_LIGHTING);
-  glDisable(GL_FOG);
-  glDisable(GL_COLOR_MATERIAL);
-  glDisable(GL_NORMALIZE);
-  glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
-
-  // render scene with only depth components
-  // seen from the light's perspective
-  glViewport(0,0,smap_size,smap_size);
-  glClear(GL_DEPTH_BUFFER_BIT);
-
-  glMatrixMode(GL_PROJECTION);
-  glPushMatrix();
-  glLoadIdentity();
-  glOrtho(tmin[0],tmax[0],tmin[1],tmax[1],-tmax[2],-tmin[2]);
-  //glFrustum(tmin[0],tmax[0],tmin[1],tmax[1],-tmax[2],-tmin[2]);
-  float glpmat[16];
-  glGetv(GL_PROJECTION_MATRIX, glpmat);
-  Mat4 pmat(Transpose(Mat4(glpmat)));
-
-  glMatrixMode(GL_MODELVIEW);
-  glPushMatrix();
-  glLoadIdentity();
-  glMultMatrix(ltrans.GetTransposedMatrix().Data());
-
-  // only render non-transparent objects for the shadow map
-  root_node_->RenderGL(DEPTH_RENDER_PASS);
-
-  // now get the shadow map
-  glActiveTexture(GL_TEXTURE0);
-  glBindTexture(GL_TEXTURE_2D, shadow_tex_id_);
-
-  glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT,
-                   0,0, smap_size,smap_size, 0);
-
-  // all of the following texture and shader params need to be moved
-  // to a one-time initialization place
-  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-  //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-  //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
-  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
-
-  // assign tex unit 0 to shadow map
-  Shader::Instance().SetShadowMapping(true,0);
-
-  // restore settings
-  glPopMatrix();
-  glMatrixMode(GL_PROJECTION);
-  glPopMatrix();
-  glMatrixMode(GL_MODELVIEW);
-
-  glPopAttrib();
-  glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
-
-  glEnable(GL_TEXTURE_2D);
-
-  // set up appropriate texture matrix
-  Mat4 bias(0.5,0.0,0.0,0.5,
-                  0.0,0.5,0.0,0.5,
-                  0.0,0.0,0.5,0.5,
-                  0.0,0.0,0.0,1.0);
-
-  Mat4 texm = bias*pmat*ltrans.GetMatrix();
-
-  glMatrixMode(GL_TEXTURE);
-  // make explicit object instead of temporary to avoid potential crash with Data()
-  Mat4 ttmp=Transpose(texm);
-  glLoadMatrix(ttmp.Data());
-  glMatrixMode(GL_MODELVIEW);
-#endif
-}
-
-void Scene::prep_depth_darkening()
-{
-#if OST_SHADER_SUPPORT_ENABLED
-  prep_depth_map(vp_width_/2,vp_height_/2);
-  // in unit 1, bound to depth_tex_id_
-
-  // kernel is static for now, inside the convolution shader
-
-  // now convolute the depth map with the kernel
-  Shader::Instance().PushProgram();
-  Shader::Instance().Activate("convolute1");
-  GLuint cpr=Shader::Instance().GetCurrentProgram();
-  // assign tex units
-  glUniform1i(glGetUniformLocation(cpr,"data"),1);
-  glUniform1i(glGetUniformLocation(cpr,"vp_width"),vp_width_/2);
-  glUniform1i(glGetUniformLocation(cpr,"vp_height"),vp_height_/2);
-
-  // set up viewport filling quad to run the fragment shader
-  draw_screen_quad(vp_width_/2,vp_height_/2,GL_TEXTURE1, depth_tex_id_);
-
-  Shader::Instance().PopProgram();
-
-  // mode 1, tex unit 1
-  Shader::Instance().SetDepthMapping(1,1);
-
-#endif
-}
-
-// returns the depth map in texture 1
-// bound to depth_tex_id_
-void Scene::prep_depth_map(unsigned int w, unsigned int h)
-{
-#if OST_SHADER_SUPPORT_ENABLED
-  unsigned int vp_width2=w;
-  unsigned int vp_height2=h;
-
-  // render pass 1 - without shadows
-  Shader::Instance().SetShadowMapping(false,0);
-  // save overall gl settings
-  glPushAttrib(GL_ENABLE_BIT);
-  // maximize rendering for depth-only information
-  glDisable(GL_LIGHTING);
-  glDisable(GL_FOG);
-  glDisable(GL_COLOR_MATERIAL);
-  glDisable(GL_NORMALIZE);
-  glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
-
-  // render scene with only depth components
-  glClear(GL_DEPTH_BUFFER_BIT);
-  glViewport(0,0,vp_width2,vp_height2);
-  glMatrixMode(GL_MODELVIEW);
-  glPushMatrix();
-  glLoadIdentity();
-  glMultMatrix(transform_.GetTransposedMatrix().Data());
-  root_node_->RenderGL(DEPTH_RENDER_PASS);
-
-  // now get the depth map
-  glActiveTexture(GL_TEXTURE1);
-  glBindTexture(GL_TEXTURE_2D, depth_tex_id_);
-  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
-  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
-  glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT,
-                   0,0, vp_width2, vp_height2, 0);
-
-  // restore settings
-  glMatrixMode(GL_PROJECTION);
-  glPopMatrix();
-  glMatrixMode(GL_MODELVIEW);
-  glPopMatrix();
-  glPopAttrib();
-  glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
-  glViewport(0,0,vp_width_,vp_height_);
-
-#endif
-}
 
 namespace {
 class DirtyAll: public GfxNodeVisitor
diff --git a/modules/gfx/src/scene.hh b/modules/gfx/src/scene.hh
index 142b4c94278a6c05270bd1aae6618c5f9576bb7c..f35920a8377550b1ab4050560682188f94c63735 100644
--- a/modules/gfx/src/scene.hh
+++ b/modules/gfx/src/scene.hh
@@ -112,6 +112,8 @@ class DLLEXPORT_OST_GFX Scene {
   void SetShadowQuality(int q);
 
   void SetDepthDarkening(bool f);
+
+  void SetAmbientOcclusion(bool f);
   
   /// \brief select shading mode
   /// one of fallback, basic, default, hf, toon1, toon2
@@ -356,6 +358,9 @@ class DLLEXPORT_OST_GFX Scene {
 
   void RenderText(const TextPrim& t);
 
+  geom::Vec3 GetLightDir() const {return light_dir_;}
+  geom::Mat3 GetLightRot() const {return light_rot_;}
+
 protected:
   friend class GfxObj; 
   friend class GfxNode;
@@ -408,6 +413,7 @@ private:
   int shadow_quality_;
   GLuint shadow_tex_id_;
   bool depth_dark_flag_;
+  bool amb_occl_flag_;
   GLuint depth_tex_id_;
   GLuint kernel_tex_id_;
   GLuint scene_tex_id_;
@@ -437,9 +443,6 @@ private:
   void set_near(float n);
   void set_far(float f);
   void update_fog();
-  void prep_shadow_map();
-  void prep_depth_darkening();
-  void prep_depth_map(uint,uint);
   void flag_all_dirty();
   void prep_glyphs();
   void prep_blur();
diff --git a/modules/gfx/src/shader.cc b/modules/gfx/src/shader.cc
index 982306a52484825899df521514863cc6ebc67d76..a3940c457238f78f00e543fda7b7620162643f04 100644
--- a/modules/gfx/src/shader.cc
+++ b/modules/gfx/src/shader.cc
@@ -148,8 +148,9 @@ void Shader::Setup()
     {"fast_sphere_vs.glsl", GL_VERTEX_SHADER},
     {"fast_sphere_fs.glsl", GL_FRAGMENT_SHADER},
     {"outline_vs.glsl", GL_VERTEX_SHADER},
-    {"convolute1_vs.glsl", GL_VERTEX_SHADER},
-    {"convolute1_fs.glsl", GL_FRAGMENT_SHADER}
+    {"quadpp_vs.glsl", GL_VERTEX_SHADER},
+    {"convolute1_fs.glsl", GL_FRAGMENT_SHADER},
+    {"amboccl_fs.glsl", GL_FRAGMENT_SHADER}
     //////////////////////////////////////////////////////////////////
   };
 
@@ -252,11 +253,18 @@ void Shader::Setup()
   }
   // convolute1 shader
   shader_program_list.clear();
-  shader_program_list.push_back(shader_code_map_["convolute1_vs.glsl"]);
+  shader_program_list.push_back(shader_code_map_["quadpp.glsl"]);
   shader_program_list.push_back(shader_code_map_["convolute1_fs.glsl"]);
   if(link_shader(shader_program_list,"convolute1",shader_program_id)) {
     shader_program_map_["convolute1"]=shader_program_id;
   }
+  // amb occl shader
+  shader_program_list.clear();
+  shader_program_list.push_back(shader_code_map_["quadpp.glsl"]);
+  shader_program_list.push_back(shader_code_map_["amboccl_fs.glsl"]);
+  if(link_shader(shader_program_list,"amboccl",shader_program_id)) {
+    shader_program_map_["amboccl"]=shader_program_id;
+  }
 
   valid_=true;
 }
@@ -328,6 +336,15 @@ void Shader::SetShadowMapping(bool flag, GLuint texid)
   UpdateState();
 }
 
+void Shader::SetOcclusionMapping(bool flag, GLuint texid)
+{
+  occl_flag_=flag;
+  if(flag) {
+    occl_map_id_=texid;
+  }
+  UpdateState();
+}
+
 void Shader::SetDepthMapping(int mode, GLuint texid)
 {
   depth_mode_=mode;
diff --git a/modules/gfx/src/shader.hh b/modules/gfx/src/shader.hh
index 32ea8d1297e719070c71314a4c4ec2fe288c848d..b8938108f433527bd33eeb6fa5a2f63414f6fc77 100644
--- a/modules/gfx/src/shader.hh
+++ b/modules/gfx/src/shader.hh
@@ -55,6 +55,7 @@ public:
 
   void SetShadowMapping(bool flag, GLuint texid);
   void SetDepthMapping(int mode, GLuint texid);
+  void SetOcclusionMapping(bool flag, GLuint texid);
   
 private:
   Shader();
@@ -67,6 +68,8 @@ private:
   GLuint shadow_map_id_;
   int depth_mode_;
   GLuint depth_map_id_;
+  bool occl_flag_;
+  GLuint occl_map_id_;
 
   std::stack<String> program_stack_;
 
diff --git a/modules/gfx/src/shader/amboccl_fs.glsl b/modules/gfx/src/shader/amboccl_fs.glsl
new file mode 100644
index 0000000000000000000000000000000000000000..44ad2220da64942e6d16e90396f36855bde2ec7e
--- /dev/null
+++ b/modules/gfx/src/shader/amboccl_fs.glsl
@@ -0,0 +1,6 @@
+uniform sampler2D data;
+
+void main()
+{
+  gl_FragColor=texture2D(data,gl_TexCoord[0].xy);
+}
diff --git a/modules/gfx/src/shader/convolute1_vs.glsl b/modules/gfx/src/shader/quadpp_vs.glsl
similarity index 100%
rename from modules/gfx/src/shader/convolute1_vs.glsl
rename to modules/gfx/src/shader/quadpp_vs.glsl