diff --git a/modules/gfx/pymod/export_gfx_obj.cc b/modules/gfx/pymod/export_gfx_obj.cc
index 3a0f4d7be36f3a9f0ca0695627264a878847662d..825ac0d91da088b68a540a15d41f12fe46a6ebe8 100644
--- a/modules/gfx/pymod/export_gfx_obj.cc
+++ b/modules/gfx/pymod/export_gfx_obj.cc
@@ -73,12 +73,14 @@ void export_GfxObj()
     .def("SetLineHalo",&GfxObjBase::SetLineHalo)
     .def("Outline",&GfxObjBase::Outline)
     .def("SetOutlineMode",&GfxObjBase::SetOutlineMode)
+    .def("SetOutlineWidth",&GfxObjBase::SetOutlineWidth)
     .def("SetOutlineExpandFactor",&GfxObjBase::SetOutlineExpandFactor)
     .def("SetOutlineExpandColor",&GfxObjBase::SetOutlineExpandColor)
     .def("AmbientOcclusion",&GfxObjBase::AmbientOcclusion)
     .def("SetAmbientLocalWeight",&GfxObjBase::SetAmbientLocalWeight)
     .def("SetAmbientOcclusionWeight",&GfxObjBase::SetAmbientOcclusionWeight)
     .def("SetOpacity",&GfxObjBase::SetOpacity)
+    .def("GetOpacity",&GfxObjBase::GetOpacity)
     .add_property("center", &GfxObjBase::GetCenter)
     COLOR_BY_DEF()
    ;
@@ -95,7 +97,6 @@ void export_GfxObj()
     .def("GetAALines",&GfxObj::GetAALines)
     .def("GetLineWidth",&GfxObj::GetLineWidth)
     .def("GetLineHalo",&GfxObj::GetLineHalo)
-    .def("GetOpacity",&GfxObj::GetOpacity)
     ;
   register_ptr_to_python<GfxObjP>();
 
diff --git a/modules/gfx/pymod/export_scene.cc b/modules/gfx/pymod/export_scene.cc
index d87d76308e6ef66640861dfa4604d27f3e14c6fe..5a1a2057f0ddfdb7a4edbe4d1e855079df9fba61 100644
--- a/modules/gfx/pymod/export_scene.cc
+++ b/modules/gfx/pymod/export_scene.cc
@@ -83,6 +83,7 @@ void export_Scene()
     .def("CenterOn",center_on1)
     .def("CenterOn",center_on2)
     .def("UnProject",  &Scene::UnProject, arg("ignore_vp")=false)
+    .def("Project",  &Scene::Project, arg("ignore_vp")=false)
     .def("InitGL", &Scene::InitGL)
     .def("RenderGL", &Scene::RenderGL)
     .def("Resize", &Scene::Resize)
@@ -116,9 +117,11 @@ void export_Scene()
     .def("BlurSnapshot",&Scene::BlurSnapshot)
     .def("SetShadow",&Scene::SetShadow)
     .def("SetShadowQuality",&Scene::SetShadowQuality)
+    .def("SetDepthDarkening",&Scene::SetDepthDarkening)
     .def("AttachObserver",&Scene::AttachObserver)
     .def("StartOffscreenMode",&Scene::StartOffscreenMode)
     .def("StopOffscreenMode",&Scene::StopOffscreenMode)
+    .def("SetShadingMode",&Scene::SetShadingMode)
     .def("__getitem__",scene_getitem)
     .add_property("bg",
                   &Scene::GetBackground, 
diff --git a/modules/gfx/src/CMakeLists.txt b/modules/gfx/src/CMakeLists.txt
index 1ee9cf86ca56787b6798e3a3a92ec671e2c52de4..8de2ae86c0fec224a64a4e8fc7e65a2dc0c8e1ea 100644
--- a/modules/gfx/src/CMakeLists.txt
+++ b/modules/gfx/src/CMakeLists.txt
@@ -223,12 +223,8 @@ target_link_libraries(ost_gfx ${OPENGL_LIBRARIES} ${PNG_LIBRARIES})
 
 if (USE_SHADER)
   set(SHADER_FILES
-    shader/basic_lf_vs.glsl
-    shader/basic_lf_fs.glsl
-    shader/fraglight_lf_vs.glsl
-    shader/fraglight_lf_fs.glsl
-    shader/basic_lfs_vs.glsl
-    shader/basic_lfs_fs.glsl
+    shader/basic_vs.glsl
+    shader/basic_fs.glsl
     shader/fraglight_vs.glsl
     shader/fraglight_fs.glsl
     shader/basic_hf_vs.glsl
diff --git a/modules/gfx/src/entity.cc b/modules/gfx/src/entity.cc
index b9956105f03267502bf0f068bab6451c71ae8d79..84d0a1bb7ed1f1207f75c7dab3454c0861bc4b22 100644
--- a/modules/gfx/src/entity.cc
+++ b/modules/gfx/src/entity.cc
@@ -71,7 +71,10 @@ Entity::Entity(const String& name,
   sel_(),
   sel_update_(),
   trace_(),
-  opacity_(1.0)
+  opacity_(1.0),
+  blur_(false),
+  blurf1_(1.0),
+  blurf2_(0.8)
 {
   init(RenderMode::SIMPLE);
 }
@@ -86,7 +89,10 @@ Entity::Entity(const String& name,
   sel_(),
   sel_update_(),
   trace_(),
-  opacity_(1.0)
+  opacity_(1.0),
+  blur_(false),
+  blurf1_(1.0),
+  blurf2_(0.8)
 {
   init(m);
 }
@@ -99,7 +105,10 @@ Entity::Entity(const String& name,
   sel_(),
   sel_update_(),
   trace_(),
-  opacity_(1.0)
+  opacity_(1.0),
+  blur_(false),
+  blurf1_(1.0),
+  blurf2_(0.8)
 {
   init(RenderMode::SIMPLE);
 }
@@ -113,7 +122,10 @@ Entity::Entity(const String& name,
   sel_(),
   sel_update_(),
   trace_(),
-  opacity_(1.0)
+  opacity_(1.0),
+  blur_(false),
+  blurf1_(1.0),
+  blurf2_(0.8)
 {
   init(m);
 }
@@ -180,38 +192,29 @@ void Entity::init(RenderMode::Type rm)
   Rebuild();
 }
 
-namespace {
-
-SimpleRenderOptionsPtr get_sro(impl::EntityRenderer* renderer)
-{
-  impl::SimpleRenderer* sr=dynamic_cast<SimpleRenderer*>(renderer);
-  assert(sr);  
-  return dyn_cast<SimpleRenderOptions>(sr->GetOptions());  
-}
-}
 void Entity::SetBlur(bool f)
 {
-  impl::EntityRenderer* renderer=this->GetOrCreateRenderer(RenderMode::SIMPLE);
-  if(!renderer) return;
-  SimpleRenderOptionsPtr sro=get_sro(renderer);
-  sro->SetBlurFlag(f);
+  blur_=f;
 }
 
 void Entity::BlurSnapshot()
 {
-  impl::EntityRenderer* renderer=this->GetOrCreateRenderer(RenderMode::SIMPLE);
-  if(!renderer) return;
-  impl::SimpleRenderer* sr=dynamic_cast<SimpleRenderer*>(renderer);
-  assert(sr);
-  sr->BlurSnapshot();
+  for (RendererMap::iterator i=renderer_.begin(),e=renderer_.end(); i!=e; ++i) {
+    impl::SimpleRenderer* sr = dynamic_cast<impl::SimpleRenderer*>(i->second);
+    if(sr) {
+      DoBlurSnapshot(sr->GetBondEntryList());
+    }
+    impl::LineTraceRenderer* lr = dynamic_cast<impl::LineTraceRenderer*>(i->second);
+    if(lr) {
+      DoBlurSnapshot(lr->GetBondEntryList());
+    }
+  }
 }
 
 void Entity::SetBlurFactors(float bf1,float bf2)
 {
-  impl::EntityRenderer* renderer=this->GetOrCreateRenderer(RenderMode::SIMPLE);
-  if(!renderer) return;
-  SimpleRenderOptionsPtr sro=get_sro(renderer);
-  sro->SetBlurFactors(bf1, bf2);
+  blurf1_=bf1;
+  blurf2_=bf2;
 }
 
 void Entity::Rebuild()
@@ -368,6 +371,16 @@ void Entity::CustomRenderGL(RenderPass pass)
       } else if(pass==GLOW_RENDER_PASS) {
         r->Render(GLOW_RENDER_PASS);
       }
+      if(blur_) {
+        impl::SimpleRenderer* sr = dynamic_cast<impl::SimpleRenderer*>(r);
+        if(sr) {
+          DoRenderBlur(sr->GetBondEntryList(),blurf1_,blurf2_);
+        }
+        impl::LineTraceRenderer* lr = dynamic_cast<impl::LineTraceRenderer*>(r);
+        if(lr) {
+          DoRenderBlur(lr->GetBondEntryList(),blurf1_,blurf2_);
+        }
+      }
     }
   }
 }
@@ -560,6 +573,36 @@ void Entity::SetOpacity(float f)
   Scene::Instance().RequestRedraw();
 }
 
+void Entity::SetOutlineWidth(float f)
+{
+  for (RendererMap::iterator it=renderer_.begin(); it!=renderer_.end(); ++it) {
+    if(it->second->IsEnabled()){
+      it->second->VA().SetOutlineWidth(f);
+    }
+  }
+  Scene::Instance().RequestRedraw();
+}
+
+void Entity::SetOutlineExpandFactor(float f)
+{
+  for (RendererMap::iterator it=renderer_.begin(); it!=renderer_.end(); ++it) {
+    if(it->second->IsEnabled()){
+      it->second->VA().SetOutlineExpandFactor(f);
+    }
+  }
+  Scene::Instance().RequestRedraw();
+}
+
+void Entity::SetOutlineExpandColor(const Color& c)
+{
+  for (RendererMap::iterator it=renderer_.begin(); it!=renderer_.end(); ++it) {
+    if(it->second->IsEnabled()){
+      it->second->VA().SetOutlineExpandColor(c);
+    }
+  }
+  Scene::Instance().RequestRedraw();
+}
+
 void Entity::OnRenderModeChange()
 {
   for (RendererMap::iterator i=renderer_.begin(), 
diff --git a/modules/gfx/src/entity.hh b/modules/gfx/src/entity.hh
index 10930da73d680e19f44eb79844e190ff0a57d93c..d8896375428ffec7f95e3922b073e40a532be064 100644
--- a/modules/gfx/src/entity.hh
+++ b/modules/gfx/src/entity.hh
@@ -142,6 +142,9 @@ public:
 
   virtual void SetOpacity(float f);
   virtual float GetOpacity() const {return opacity_;}
+  virtual void SetOutlineWidth(float f);
+  virtual void SetOutlineExpandFactor(float f);
+  virtual void SetOutlineExpandColor(const Color& c);
 
   /// \brief rebuild graphical object (see ctor comments)
   /*
@@ -299,6 +302,9 @@ private:
   mutable RendererMap renderer_;
 
   float opacity_;
+  bool blur_;
+  float blurf1_;
+  float blurf2_;
 };
 
 
diff --git a/modules/gfx/src/gfx_object.cc b/modules/gfx/src/gfx_object.cc
index c25c34344d7a91ed03f8cc4017b77a4678c4d8f1..645e01708265c2a2a50bafd746643b4953bc469c 100644
--- a/modules/gfx/src/gfx_object.cc
+++ b/modules/gfx/src/gfx_object.cc
@@ -307,14 +307,22 @@ void GfxObj::SetOutlineMode(int m)
   }
 }
 
+void GfxObj::SetOutlineWidth(float f)
+{
+  va_.SetOutlineWidth(f);
+  Scene::Instance().RequestRedraw();
+}
+
 void GfxObj::SetOutlineExpandFactor(float f)
 {
   va_.SetOutlineExpandFactor(f);
+  Scene::Instance().RequestRedraw();
 }
 
 void GfxObj::SetOutlineExpandColor(const Color& c)
 {
   va_.SetOutlineExpandColor(c);
+  Scene::Instance().RequestRedraw();
 }
 
 void GfxObj::AmbientOcclusion(bool f)
diff --git a/modules/gfx/src/gfx_object.hh b/modules/gfx/src/gfx_object.hh
index 878601c809be14c995ce4bcf8230ab918d36ec23..8d004e3cc9d1cabf7bad5e275495b197102a450f 100644
--- a/modules/gfx/src/gfx_object.hh
+++ b/modules/gfx/src/gfx_object.hh
@@ -76,6 +76,7 @@ public:
   virtual void SetLineHalo(float f);
   virtual void Outline(bool f);
   virtual void SetOutlineMode(int m);
+  virtual void SetOutlineWidth(float f);
   virtual void SetOutlineExpandFactor(float f);
   virtual void SetOutlineExpandColor(const Color& c);
   virtual void AmbientOcclusion(bool f);
diff --git a/modules/gfx/src/gfx_object_base.hh b/modules/gfx/src/gfx_object_base.hh
index c18022b47e6d071471bf268395b800abff6ce3a4..0ffb6d94a968bafeaf436aae29dc9351599f89d4 100644
--- a/modules/gfx/src/gfx_object_base.hh
+++ b/modules/gfx/src/gfx_object_base.hh
@@ -91,27 +91,25 @@ class DLLEXPORT_OST_GFX GfxObjBase: public GfxNode
 
   /// \brief turn outline rendering on or off
   virtual void Outline(bool f) = 0;
-
   /// \brief set outline mode
   virtual void SetOutlineMode(int m) = 0;
-  /// \brief set outline tweak factor
+  /// \brief set outline width (modes 1 + 2)
+  virtual void SetOutlineWidth(float f) = 0;
+  /// \brief set outline tweak factor (mode 3)
   virtual void SetOutlineExpandFactor(float f) = 0;
-  /// \brief set outline color
+  /// \brief set outline color (mode 3)
   virtual void SetOutlineExpandColor(const Color& c) = 0;
 
   /// \brief ambient occlusion rendering
   /// results are cached, but may be very slow on first call 
   virtual void AmbientOcclusion(bool f) = 0;
-  
   /// \brief blending weight of local color to fragment color
   virtual void SetAmbientLocalWeight(float w) = 0;
-  
   /// \brief blending weight of occlusion factor
   virtual void SetAmbientOcclusionWeight(float w) = 0;
 
   /// \brief set opacity (1 = no transparency)
   virtual void SetOpacity(float f) = 0;
-
   /// \brief returns a value smaller than 1.0 if transparency is used in this object
   virtual float GetOpacity() const = 0;
 
diff --git a/modules/gfx/src/impl/backbone_trace.cc b/modules/gfx/src/impl/backbone_trace.cc
index 85403263a9b157fc209634078f9be17e8af7f499..32fef42cde9ffb8ae17e306fe9510b934fc00b35 100644
--- a/modules/gfx/src/impl/backbone_trace.cc
+++ b/modules/gfx/src/impl/backbone_trace.cc
@@ -210,7 +210,7 @@ BackboneTrace BackboneTrace::CreateSubset(const mol::EntityView& subview)
     const NodeEntryList& nlist=*nitnit;
     for(NodeEntryList::const_iterator nit=nlist.begin();nit!=nlist.end();++nit) {
       if(subview.FindAtom(nit->atom).IsValid()) {
-	new_nlist.push_back(*nit);
+        new_nlist.push_back(*nit);
       }
     }
     if(!new_nlist.empty()) {
diff --git a/modules/gfx/src/impl/cartoon_renderer.cc b/modules/gfx/src/impl/cartoon_renderer.cc
index 942bff0ab88f8bd60bfa9029e607ffcb8d129ef2..1dd9a8cbfd231cb76e1e241a281db634eb287440 100644
--- a/modules/gfx/src/impl/cartoon_renderer.cc
+++ b/modules/gfx/src/impl/cartoon_renderer.cc
@@ -505,12 +505,45 @@ TraceProfile CartoonRenderer::TransformAndAddProfile(const std::vector<TraceProf
   return tf_prof;
 }
 
+namespace {
+
+  float spread(const geom::Vec3& v1, geom::Vec3& v2, geom::Vec3& v3, geom::Vec3& v4)
+  {
+    return geom::Dot(geom::Normalize(geom::Cross(geom::Normalize(v3-v1),geom::Normalize(v2-v1))),
+                     geom::Normalize(geom::Cross(geom::Normalize(v3-v4),geom::Normalize(v2-v4))));
+  }
+
+}
+
 void CartoonRenderer::AssembleProfile(const TraceProfile& prof1,
                                       const TraceProfile& prof2, 
                                       IndexedVertexArray& va)
 {
-  // determine rotational offset with a heuristic routine
-  int best_off=0;
+  float accum[]={0.0,0.0,0.0,0.0,0.0};
+  for(int i=0;i<prof1.size();++i) {
+    int i1=(i+0)%prof1.size();
+    int i2=(i+1)%prof1.size();
+    geom::Vec3 v1=va.GetVert(prof1[i1].id);
+    geom::Vec3 v2=va.GetVert(prof1[i2].id);
+    for(int k=-2;k<=2;++k) {
+      int i3=(i+k+0+prof1.size())%prof1.size();
+      int i4=(i+k+1+prof1.size())%prof1.size();
+      geom::Vec3 v3=va.GetVert(prof2[i3].id);
+      geom::Vec3 v4=va.GetVert(prof2[i4].id);
+      accum[k+2]+=spread(v1,v2,v3,v4);
+    }
+  }
+
+  float best_spread=accum[0];
+  int best_off=-2;
+  for(int k=-1;k<=2;++k) {
+    if(accum[k+2]<best_spread) {
+      best_spread=accum[k+2];
+      best_off=k;
+    }
+  }
+  best_off=(best_off+prof1.size())%prof1.size();
+
 #if 0
   uint i1=0;
   uint i2=prof1.size()/4;
diff --git a/modules/gfx/src/impl/connect_renderer_base.hh b/modules/gfx/src/impl/connect_renderer_base.hh
index 78b730fc18c5bc56cf5b0edd3a7df89fda2d2d6e..1c88950fff335dc19b90d5b80a6d298f1096ada7 100644
--- a/modules/gfx/src/impl/connect_renderer_base.hh
+++ b/modules/gfx/src/impl/connect_renderer_base.hh
@@ -60,7 +60,7 @@ protected:
   float GetFixedPickRadius() const { return pick_radius_; }
 
 protected:
- float     pick_radius_;
+  float     pick_radius_;
   GfxView  view_;
   GfxView  sel_view_;
 };
diff --git a/modules/gfx/src/impl/entity_detail.cc b/modules/gfx/src/impl/entity_detail.cc
index 399c342c2895134eb6ea850252a817c24bc6f040..c11c6a73c2fac5e5df04a04a640134ed74c4b8bf 100644
--- a/modules/gfx/src/impl/entity_detail.cc
+++ b/modules/gfx/src/impl/entity_detail.cc
@@ -16,19 +16,148 @@
 // along with this library; if not, write to the Free Software Foundation, Inc.,
 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 //------------------------------------------------------------------------------
+
+#include <ost/gfx/gl_helper.hh>
+#include <ost/gfx/scene.hh>
+#include <ost/gfx/color.hh>
+
 #include "entity_detail.hh"
 
+
 namespace ost { 
 
 using namespace mol;
 
 namespace gfx { namespace impl {
 
-  namespace {
+namespace {
+
+static const float default_radius=0.28;
+
+struct BlurQuadEntry
+{
+  float zdist;
+  geom::Vec3 p1,p2,p3,p4;
+  gfx::Color c1,c2,c3,c4;
+};
+
+struct BlurQuadEntryLess
+{
+  bool operator()(const BlurQuadEntry& e1, const BlurQuadEntry& e2)
+  {
+    // provides back-to-front sorting
+    return e1.zdist<e2.zdist;
+  }
+};
+
+} // anon ns
 
-    static const float default_radius=0.28;
+void DoRenderBlur(BondEntryList& bl, float bf1, float bf2)
+{
+  // add blur for this particular orientation!
+  // don't use vertex array, but on-the-fly oriented and z-sorted quads
+  mol::Transform tf = Scene::Instance().GetTransform();
+
+  std::vector<BlurQuadEntry> bql;
+  for (BondEntryList::iterator it=bl.begin(); it!=bl.end();++it) {
+
+    if(!it->atom1 || !it->atom2) continue;
+
+    const geom::Vec3 p0=tf.Apply(it->atom1->atom.GetPos());
+    const geom::Vec3 p2=tf.Apply(it->atom2->atom.GetPos());
+    geom::Vec3 p1=(p0+p2)*0.5;
+
+    const geom::Vec3 q0=tf.Apply(it->pp1);
+    const geom::Vec3 q2=tf.Apply(it->pp2);
+    geom::Vec3 q1=(q0+q2)*0.5;
+
+    float ll0 = geom::Length2(p0-q0);
+    float ll1 = geom::Length2(p1-q1);
+    float ll2 = geom::Length2(p2-q2);
+
+    if(ll0<1e-2 && ll1<1e-2 && ll2<1e-2) continue;
+
+    float x0 = exp(-bf1*ll0);
+    float x1 = exp(-bf1*ll1);
+    float x2 = exp(-bf1*ll2);
+
+    BlurQuadEntry bqe;
+
+    bqe.zdist=0.25*(p0[2]+p2[2]+q0[2]+q2[2]);
+
+    // first half
+    bqe.p1 = p0;
+    bqe.p2 = p1;
+    bqe.p3 = q0;
+    bqe.p4 = q1;
+    bqe.c1 = it->atom1->color;
+    bqe.c2 = it->atom1->color;
+    bqe.c3 = it->atom1->color;
+    bqe.c4 = it->atom1->color;
+    bqe.c1[3] = x0;
+    bqe.c2[3] = x1;
+    bqe.c3[3]=x0*bf2;
+    bqe.c4[3]=x1*bf2;
+
+    bql.push_back(bqe);
+
+    // second half
+    bqe.p1 = p1;
+    bqe.p2 = p2;
+    bqe.p3 = q1;
+    bqe.p4 = q2;
+    bqe.c1 = it->atom2->color;
+    bqe.c2 = it->atom2->color;
+    bqe.c3 = it->atom2->color;
+    bqe.c4 = it->atom2->color;
+    bqe.c1[3] = x1;
+    bqe.c2[3] = x2;
+    bqe.c3[3]=x1*bf2;
+    bqe.c4[3]=x2*bf2;
+
+    bql.push_back(bqe);
+  }
+
+  std::sort(bql.begin(),bql.end(),BlurQuadEntryLess());
+
+  glPushAttrib(GL_ENABLE_BIT | GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_LIGHTING_BIT);
+  glDisable(GL_LIGHTING);
+  glDisable(GL_CULL_FACE);
+  glDepthFunc(GL_LESS);
+  glDepthMask(GL_FALSE);
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+  glLoadIdentity();
+  glBegin(GL_QUADS);
+  glNormal3f(0.0,0.0,0.0);
+  for (std::vector<BlurQuadEntry>::const_iterator it=bql.begin();
+       it!=bql.end();++it) {
+    glColor4fv(it->c1);
+    glVertex3v(it->p1.Data());
+    glColor4fv(it->c2);
+    glVertex3v(it->p2.Data());
+    glColor4fv(it->c4);
+    glVertex3v(it->p4.Data());
+    glColor4fv(it->c3);
+    glVertex3v(it->p3.Data());
+  }
+
+  glEnd();
+  glPopMatrix();
+  glPopAttrib();
+}
 
+void DoBlurSnapshot(BondEntryList& bl)
+{
+  for (BondEntryList::iterator it=bl.begin();
+       it!=bl.end();++it) {
+    if(it->atom1 && it->atom2) {
+      it->pp1=it->atom1->atom.GetPos();
+      it->pp2=it->atom2->atom.GetPos();
+    }
   }
+}
+
 
 void GfxView::Clear() 
 {
diff --git a/modules/gfx/src/impl/entity_detail.hh b/modules/gfx/src/impl/entity_detail.hh
index 0b539993d35a859b64fd2a64ea448c1d07718ddc..36e2d5e5e2ea09b60c48b6a78a432f5fb1774ff7 100644
--- a/modules/gfx/src/impl/entity_detail.hh
+++ b/modules/gfx/src/impl/entity_detail.hh
@@ -70,6 +70,9 @@ struct DLLEXPORT_OST_GFX BondEntry
 
 typedef std::vector<BondEntry> BondEntryList;
 
+void DoRenderBlur(BondEntryList& bl, float bf1, float bf2);
+void DoBlurSnapshot(BondEntryList& bl);
+
 class DLLEXPORT_OST_GFX GfxView {
 public:
   void Clear();
diff --git a/modules/gfx/src/impl/line_trace_renderer.cc b/modules/gfx/src/impl/line_trace_renderer.cc
index efd91670667d0aa5d25db71f2c43aecb965ca623..e8fd9a224c094f144e8cda0ad4b64a6b01e5b98e 100644
--- a/modules/gfx/src/impl/line_trace_renderer.cc
+++ b/modules/gfx/src/impl/line_trace_renderer.cc
@@ -26,10 +26,36 @@
 
 namespace ost { namespace gfx { namespace impl {
 
+namespace {
+
+void add_atom_and_bond(mol::AtomHandle atom1,mol::AtomHandle atom2, AtomEntryMap& amap, BondEntryList& blist)
+{
+  AtomEntry ae1(atom1,0.0,0.0,Color(1,1,1));
+  amap[atom1.GetHashCode()]=ae1;
+  AtomEntry ae2(atom2,0.0,0.0,Color(1,1,1));
+  amap[atom2.GetHashCode()]=ae2;
+  blist.push_back(BondEntry(mol::BondHandle(),0.0f,
+                            &amap[atom1.GetHashCode()],
+                            &amap[atom2.GetHashCode()]));
+}
+
+}
+
+
 LineTraceRenderer::LineTraceRenderer(BackboneTrace* trace): 
-  TraceRendererBase(trace, 1), options_(new LineTraceRenderOptions())
+  TraceRendererBase(trace, 1), 
+  options_(new LineTraceRenderOptions()),
+  amap_(),
+  blist_()
 {
   this->SetName("Fast Trace");
+
+  for (int node_list=0; node_list<trace->GetListCount(); ++node_list) {
+    const NodeEntryList& nl=trace->GetList(node_list);
+    for (unsigned int i=0; i<nl.size()-1;++i) {
+      add_atom_and_bond(nl[i].atom,nl[i+1].atom,amap_,blist_);
+    }
+  }
 }
 
 void LineTraceRenderer::PrepareRendering() 
@@ -61,14 +87,13 @@ void LineTraceRenderer::PrepareRendering(const BackboneTrace& trace_subset,
     va.SetAALines(options_->GetAALines());
     for (int node_list=0; node_list<trace_subset.GetListCount(); ++node_list) {
       const NodeEntryList& nl=trace_subset.GetList(node_list);
-
+      
       if (nl.size()<2) {
-	continue;
+        continue;
       }
 
       VertexID p0=va.Add(nl[0].atom.GetPos(), geom::Vec3(),
-			 is_sel ? sel_clr : nl[0].color1);
-
+                         is_sel ? sel_clr : nl[0].color1);
       for (unsigned int i=1; i<nl.size()-1;++i) {
         const NodeEntry& entry=nl[i];
         VertexID p1 =va.Add(entry.atom.GetPos(), geom::Vec3(), 
@@ -76,9 +101,9 @@ void LineTraceRenderer::PrepareRendering(const BackboneTrace& trace_subset,
         va.AddLine(p0, p1);
         p0=p1;
       }
-      const NodeEntry& entry=nl.back();      
+      const NodeEntry& entry=nl.back();
       VertexID p1 =va.Add(entry.atom.GetPos(), geom::Vec3(), 
-			  is_sel ? sel_clr : entry.color1);
+                          is_sel ? sel_clr : entry.color1);
       va.AddLine(p0, p1);
     }
   }
diff --git a/modules/gfx/src/impl/line_trace_renderer.hh b/modules/gfx/src/impl/line_trace_renderer.hh
index 39f1e0e10a60cdd6a740cb2076a90d7991f3d23c..ce42fc004dd6c70b444c04d7bea50d751dedb330 100644
--- a/modules/gfx/src/impl/line_trace_renderer.hh
+++ b/modules/gfx/src/impl/line_trace_renderer.hh
@@ -53,8 +53,12 @@ public:
 
   virtual ~LineTraceRenderer();
 
+  BondEntryList& GetBondEntryList() {return blist_;}
+
 private:
   LineTraceRenderOptionsPtr  options_;
+  AtomEntryMap amap_;   // for blur rendering
+  BondEntryList blist_; // dito
 };
 
 }}}
diff --git a/modules/gfx/src/impl/simple_renderer.cc b/modules/gfx/src/impl/simple_renderer.cc
index 4e228f0dc06f9e7fee003411bbf02f241de77e26..983ef012d4476adf0857c3a747787dfeccb740cf 100644
--- a/modules/gfx/src/impl/simple_renderer.cc
+++ b/modules/gfx/src/impl/simple_renderer.cc
@@ -30,25 +30,6 @@
 namespace ost { namespace gfx { namespace impl {
 
 
-namespace {
-
-struct BlurQuadEntry
-{
-  float zdist;
-  geom::Vec3 p1,p2,p3,p4;
-  Color c1,c2,c3,c4;
-};
-
-struct BlurQuadEntryLess
-{
-  bool operator()(const BlurQuadEntry& e1, const BlurQuadEntry& e2)
-  {
-    // provides back-to-front sorting
-    return e1.zdist<e2.zdist;
-  }
-};
-
-}
   
 SimpleRenderer::SimpleRenderer(): options_(new SimpleRenderOptions()) 
 {
@@ -200,120 +181,9 @@ void SimpleRenderer::PrepareRendering(GfxView& view, IndexedVertexArray& va)
   }  
 }
 
-void SimpleRenderer::RenderBlur()
-{
-  // add blur for this particular orientation!
-  // don't use vertex array, but on-the-fly oriented and z-sorted quads
-  mol::Transform tf = Scene::Instance().GetTransform();
-
-  std::vector<BlurQuadEntry> bql;
-  const std::pair<Real, Real>& bf=options_->GetBlurFactors();
-  for (BondEntryList::iterator it=view_.bond_list.begin();
-       it!=view_.bond_list.end();++it) {
-
-    const geom::Vec3 p0=tf.Apply(it->bond.GetFirst().GetPos());
-    const geom::Vec3 p2=tf.Apply(it->bond.GetSecond().GetPos());
-    geom::Vec3 p1=(p0+p2)*0.5;
-
-    const geom::Vec3 q0=tf.Apply(it->pp1);
-    const geom::Vec3 q2=tf.Apply(it->pp2);
-    geom::Vec3 q1=(q0+q2)*0.5;
-
-    float ll0 = geom::Length2(p0-q0);
-    float ll1 = geom::Length2(p1-q1);
-    float ll2 = geom::Length2(p2-q2);
-
-    if(ll0<1e-2 && ll1<1e-2 && ll2<1e-2) continue;
-
-    float x0 = exp(-bf.first*ll0);
-    float x1 = exp(-bf.first*ll1);
-    float x2 = exp(-bf.first*ll2);
-
-    BlurQuadEntry bqe;
-
-    bqe.zdist=0.25*(p0[2]+p2[2]+q0[2]+q2[2]);
-
-    // first half
-    bqe.p1 = p0;
-    bqe.p2 = p1;
-    bqe.p3 = q0;
-    bqe.p4 = q1;
-    bqe.c1 = it->atom1->color;
-    bqe.c2 = it->atom1->color;
-    bqe.c3 = it->atom1->color;
-    bqe.c4 = it->atom1->color;
-    bqe.c1[3] = x0;
-    bqe.c2[3] = x1;
-    bqe.c3[3]=x0*bf.second;
-    bqe.c4[3]=x1*bf.second;
-
-    bql.push_back(bqe);
-
-    // first half
-    bqe.p1 = p1;
-    bqe.p2 = p2;
-    bqe.p3 = q1;
-    bqe.p4 = q2;
-    bqe.c1 = it->atom2->color;
-    bqe.c2 = it->atom2->color;
-    bqe.c3 = it->atom2->color;
-    bqe.c4 = it->atom2->color;
-    bqe.c1[3] = x1;
-    bqe.c2[3] = x2;
-    bqe.c3[3]=x1*bf.second;
-    bqe.c4[3]=x2*bf.second;
-
-    bql.push_back(bqe);
-  }
-
-  std::sort(bql.begin(),bql.end(),BlurQuadEntryLess());
-
-  glPushAttrib(GL_ENABLE_BIT | GL_DEPTH_BUFFER_BIT);
-  glDisable(GL_LIGHTING);
-  glDisable(GL_CULL_FACE);
-  glDepthFunc(GL_LESS);
-  glDepthMask(GL_FALSE);
-  glMatrixMode(GL_MODELVIEW);
-  glPushMatrix();
-  glLoadIdentity();
-  glBegin(GL_QUADS);
-  glNormal3f(0.0,0.0,0.0);
-  for (std::vector<BlurQuadEntry>::const_iterator it=bql.begin();
-       it!=bql.end();++it) {
-    glColor4fv(it->c1);
-    glVertex3v(it->p1.Data());
-    glColor4fv(it->c2);
-    glVertex3v(it->p2.Data());
-    glColor4fv(it->c4);
-    glVertex3v(it->p4.Data());
-    glColor4fv(it->c3);
-    glVertex3v(it->p3.Data());
-  }
-
-  glEnd();
-  glPopMatrix();
-  glPopAttrib();
-}
-
-void SimpleRenderer::BlurSnapshot()
+BondEntryList& SimpleRenderer::GetBondEntryList()
 {
-  for (BondEntryList::iterator it=view_.bond_list.begin();
-       it!=view_.bond_list.end();++it) {
-    it->pp1=it->atom1->atom.GetPos();
-    it->pp2=it->atom2->atom.GetPos();
-  }
-}
-void SimpleRenderer::Render(RenderPass pass)
-{
-  ConnectRendererBase::Render(pass);
-  if (pass==STANDARD_RENDER_PASS && options_->GetBlurFlag()) {
-    this->RenderBlur();
-  }
-}
-
-SimpleRenderer::~SimpleRenderer() 
-{
-
+  return view_.bond_list;
 }
 
 void SimpleRenderer::RenderPov(PovState& pov, const std::string& name)
diff --git a/modules/gfx/src/impl/simple_renderer.hh b/modules/gfx/src/impl/simple_renderer.hh
index 78038ffe543780b5d92389866d142c105cbcd8ba..41b801cbd6721d4a57309edf271c80f6d7dbb8e3 100644
--- a/modules/gfx/src/impl/simple_renderer.hh
+++ b/modules/gfx/src/impl/simple_renderer.hh
@@ -43,12 +43,10 @@ public:
   virtual void SetOptions(RenderOptionsPtr& render_options);
   virtual RenderOptionsPtr GetOptions();
   
-  virtual void Render(RenderPass pass);
-  virtual ~SimpleRenderer();
   virtual void RenderPov(PovState& pov, const std::string& name);
-  void BlurSnapshot();
+
+  BondEntryList& GetBondEntryList();
 private:
-  void RenderBlur();
   void PrepareRendering(GfxView& view, IndexedVertexArray& va);
   geom::Vec3 GetDoubleBondPlane(mol::BondHandle b);
   void GetBondPartnerNormal(geom::Vec3& vec, int& n, geom::Vec3& bond_vec,
diff --git a/modules/gfx/src/impl/trace_renderer_base.cc b/modules/gfx/src/impl/trace_renderer_base.cc
index 9231e929c5c791fc823bfbb8afc108b14d32319d..8ccf5e26ee514d6a4dae4d54062b94d765e52598 100644
--- a/modules/gfx/src/impl/trace_renderer_base.cc
+++ b/modules/gfx/src/impl/trace_renderer_base.cc
@@ -72,7 +72,7 @@ inline void apply_color_op(TraceRendererBase* rend, BackboneTrace& trace_subset,
 } //ns
 
 TraceRendererBase::TraceRendererBase(BackboneTrace* trace, int n):
-  trace_(trace), trace_subset_(*trace), sel_subset_()
+  trace_(trace), trace_subset_(), sel_subset_()
 {
 }
 
diff --git a/modules/gfx/src/scene.cc b/modules/gfx/src/scene.cc
index ead1566ffb0621989f3edcf597c2e1ead2cd411b..181120438e325e610919e2c1d19ea0729f444b65 100644
--- a/modules/gfx/src/scene.cc
+++ b/modules/gfx/src/scene.cc
@@ -56,8 +56,6 @@
 # include "shader.hh"
 #endif
 
-//#define DEBUG_SMAP
-
 using boost::bind;
 
 namespace ost {
@@ -113,6 +111,7 @@ Scene::Scene():
   shadow_flag_(false),
   shadow_quality_(1),
   shadow_tex_id_(),
+  depth_dark_flag_(false),
   depth_tex_id_(),
   kernel_tex_id_(),
   scene_tex_id_(),
@@ -168,20 +167,45 @@ Color Scene::GetFogColor() const
 void Scene::SetShadow(bool f)
 {
   shadow_flag_=f;
+  // the redraw routine will deal with the Shader
   RequestRedraw();
 }
 
-bool Scene::GetShadow()
+void Scene::SetShadowQuality(int q)
 {
-  return shadow_flag_;
+  shadow_quality_=std::min(3,std::max(0,q));
+  if(shadow_flag_) {
+    RequestRedraw();
+  }
 }
 
-void Scene::SetShadowQuality(int q)
+void Scene::SetDepthDarkening(bool f)
 {
-  shadow_quality_=std::min(3,std::max(0,q));
+  depth_dark_flag_=f;
+  // the redraw routine will deal with the Shader
   RequestRedraw();
 }
 
+
+void Scene::SetShadingMode(const std::string& smode)
+{
+#if OST_SHADER_SUPPORT_ENABLED
+  if(smode=="fallback") {
+    Shader::Instance().Activate("");
+  } else if(smode=="basic") {
+    Shader::Instance().Activate("basic");
+  } else if(smode=="hf") {
+    Shader::Instance().Activate("hemilight");
+  } else if(smode=="toon1") {
+    Shader::Instance().Activate("toon1");
+  } else if(smode=="toon2") {
+    Shader::Instance().Activate("toon2");
+  } else {
+    Shader::Instance().Activate("fraglight");
+  }
+#endif
+}
+
 namespace {
 
 void set_light_dir(Vec3 ld)
@@ -286,7 +310,7 @@ void Scene::InitGL()
 #if OST_SHADER_SUPPORT_ENABLED
   LOGN_DEBUG("scene: shader setup");
   Shader::Instance().Setup();
-  Shader::Instance().Activate("fraglight");
+  SetShadingMode("default");
 
   glGenTextures(1,&shadow_tex_id_);
   glGenTextures(1,&depth_tex_id_);
@@ -474,12 +498,16 @@ void Scene::RenderGL()
   if(auto_autoslab_) Autoslab(false, false);
 
   #if OST_SHADER_SUPPORT_ENABLED
-    if(shadow_flag_) {
-      prep_shadow_map();
-  #ifdef DEBUG_SMAP
-      return;
-  #endif
-    }
+  if(depth_dark_flag_) {
+    prep_depth_darkening();
+  } else {
+    Shader::Instance().SetDepthMapping(0,0);
+  }
+  if(shadow_flag_) {
+    prep_shadow_map();
+  } else {
+    Shader::Instance().SetShadowMapping(0,0);
+  }
   #endif
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   prep_blur();
@@ -1543,6 +1571,95 @@ 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
@@ -1560,20 +1677,19 @@ void Scene::prep_shadow_map()
   // render pass 1 - without shadows
 
   // turn shadowing off for subsequent rendering
-  glUniform1i(glGetUniformLocation(Shader::Instance().GetCurrentProgram(),
-              "shadow_flag"),0);
+  Shader::Instance().SetShadowMapping(false,0);
+
   // save overall gl settings
   glPushAttrib(GL_VIEWPORT_BIT | GL_ENABLE_BIT);
   // maximize rendering for depth-only information
-#ifndef DEBUG_SMAP
   glDisable(GL_LIGHTING);
   glDisable(GL_FOG);
   glDisable(GL_COLOR_MATERIAL);
   glDisable(GL_NORMALIZE);
   glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
-#endif
 
   // render scene with only depth components
+  // seen from the light's perspective
   glViewport(0,0,smap_size,smap_size);
   glClear(GL_DEPTH_BUFFER_BIT);
 
@@ -1601,7 +1717,6 @@ void Scene::prep_shadow_map()
   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);
@@ -1611,21 +1726,8 @@ void Scene::prep_shadow_map()
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
 
-  GLuint cpr=Shader::Instance().GetCurrentProgram();
-
   // assign tex unit 0 to shadow map
-  glUniform1i(glGetUniformLocation(Shader::Instance().GetCurrentProgram(),"shadow_map"),0);
-  //int depth_bits;
-  //glGetIntegerv(GL_DEPTH_BITS, &depth_bits);
-  //float depth_bias = 1.0/static_cast<float>(1<<depth_bits);
-  glUniform1f(glGetUniformLocation(cpr,"depth_bias"),0.008);
-
-  glUniform1f(glGetUniformLocation(cpr,"epsilon"),0.002);
-
-  glUniform1f(glGetUniformLocation(cpr,"shadow_multiplier"),0.4);
-
-  //
-  //////////////////
+  Shader::Instance().SetShadowMapping(true,0);
 
   // restore settings
   glPopMatrix();
@@ -1638,10 +1740,6 @@ void Scene::prep_shadow_map()
 
   glEnable(GL_TEXTURE_2D);
 
-  // and turn shadowing on for subsequent rendering
-  glUniform1i(glGetUniformLocation(cpr,"shadow_flag"),1);
-
-#ifndef DEBUG_SMAP
   // set up appropriate texture matrix
   Mat4 bias(0.5,0.0,0.0,0.5,
                   0.0,0.5,0.0,0.5,
@@ -1655,45 +1753,47 @@ void Scene::prep_shadow_map()
   Mat4 ttmp=Transpose(texm);
   glLoadMatrix(ttmp.Data());
   glMatrixMode(GL_MODELVIEW);
-#else
-  // this debug code draws the depth map across the screen
-  Shader::Instance().Activate("");
-  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-  glDisable(GL_CULL_FACE);
-  glDisable(GL_LIGHTING);
-  glDisable(GL_FOG);
-  glEnable(GL_TEXTURE_2D);
-  glMatrixMode(GL_PROJECTION);
-  glLoadIdentity();
-  glOrtho(-1,11,-1,11,-1,1);
-  glMatrixMode(GL_MODELVIEW);
-  glLoadIdentity();
-  glColor3f(1.0,1.0,1.0);
-  glBegin(GL_QUADS);
-  glTexCoord2f(0.0,0.0);
-  glVertex2f(0.0,0.0);
-  glTexCoord2f(0.0,1.0);
-  glVertex2f(0.0,10.0);
-  glTexCoord2f(1.0,1.0);
-  glVertex2f(10.0,10.0);
-  glTexCoord2f(1.0,0.0);
-  glVertex2f(10.0,0.0);
-  glEnd();
-  Shader::Instance().Activate("basic_shadow");
 #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
 }
 
-void Scene::prep_depth_map()
+// 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=vp_width_/2;
-  unsigned int vp_height2=vp_height_/2;
+  unsigned int vp_width2=w;
+  unsigned int vp_height2=h;
 
   // render pass 1 - without shadows
-  // turn shadowing off for subsequent rendering
-  glUniform1i(glGetUniformLocation(Shader::Instance().GetCurrentProgram(),
-              "shadow_flag"),0);
+  Shader::Instance().SetShadowMapping(false,0);
   // save overall gl settings
   glPushAttrib(GL_ENABLE_BIT);
   // maximize rendering for depth-only information
@@ -1731,127 +1831,6 @@ void Scene::prep_depth_map()
   glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
   glViewport(0,0,vp_width_,vp_height_);
 
-  // next is the kernel
-  static std::vector<GLfloat> kernel_data;
-  if(kernel_data.empty()) {
-    int kernel_size=2;
-    float sum=0.0;
-    float prec=0.02;
-    float sigma=static_cast<float>(kernel_size)/std::sqrt(-std::log(prec));
-    for( int u=-kernel_size;u<=kernel_size;++u) {
-      for( int v=-kernel_size;v<=kernel_size;++v) {
-	float y=std::exp(static_cast<float>(-u*u-v*v)/(sigma*sigma));
-	if(y>=prec) {
-	  sum+=y;
-	  kernel_data.push_back(static_cast<float>(u));
-	  kernel_data.push_back(static_cast<float>(v));
-	  kernel_data.push_back(y);
-	}
-      }
-    }
-    float ivpw=1.0/static_cast<float>(vp_width2);
-    float ivph=1.0/static_cast<float>(vp_height2);
-    for(unsigned int i=0;i<kernel_data.size();i+=3) {
-      kernel_data[i+0]=(ivpw*kernel_data[i+0])*0.5+0.5;
-      kernel_data[i+1]=(ivph*kernel_data[i+1])*0.5+0.5;
-      kernel_data[i+2]=kernel_data[i+2]/sum;
-    }
-  }
-
-  glEnable(GL_TEXTURE_1D);
-  glActiveTexture(GL_TEXTURE2);
-  glBindTexture(GL_TEXTURE_1D, kernel_tex_id_);
-  glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-  glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-  glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP);
-  glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP);
-  glTexImage1D(GL_TEXTURE_1D,0,GL_RGB,kernel_data.size()/3,0,GL_RGB,GL_FLOAT,&kernel_data[0]);
-
-  // 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,"kernel"),2);
-  glUniform1i(glGetUniformLocation(cpr,"kernel_size"),kernel_data.size());
-  glUniform1i(glGetUniformLocation(cpr,"vp_width"),vp_width_);
-  glUniform1i(glGetUniformLocation(cpr,"vp_height"),vp_height_);
-
-  // set up viewport filling quad to run the fragment shader
-  glPushAttrib(GL_ENABLE_BIT);
-  glDisable(GL_DEPTH_TEST);
-  glClear(GL_COLOR_BUFFER_BIT);
-  glViewport(0,0,vp_width2,vp_height2);
-  glMatrixMode(GL_PROJECTION);
-  glPushMatrix();
-  glLoadIdentity();
-  glOrtho(0,1,0,1,-1,1);
-  glMatrixMode(GL_MODELVIEW);
-  glPushMatrix();
-  glLoadIdentity();
-  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();
-
-  // now grab the result
-  glEnable(GL_TEXTURE_2D);
-  glActiveTexture(GL_TEXTURE0);
-  glBindTexture(GL_TEXTURE_2D, scene_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, vp_width2, vp_height2, 0);
-
-
-#if 1
-  // this debug code draws the depth map across the complete screen
-  //glViewport(0,0,vp_width_,vp_height_);
-  Shader::Instance().Activate("");
-  glViewport(0,0,vp_width_,vp_height_);
-  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, scene_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();
-#endif
-
-  // restore settings
-  Shader::Instance().PopProgram();
-  glMatrixMode(GL_PROJECTION);
-  glPopMatrix();
-  glMatrixMode(GL_MODELVIEW);
-  glPopMatrix();
-  glPopAttrib();
-  glViewport(0,0,vp_width_,vp_height_);
-
-
-
 #endif
 }
 
@@ -1902,14 +1881,6 @@ void Scene::SetTestMode(bool f)
   }
 }
 
-// temporary interface
-void Scene::ActivateShader(const String& name)
-{
-#if OST_SHADER_SUPPORT_ENABLED
-  Shader::Instance().Activate(name);
-#endif
-}
-
 void Scene::prep_glyphs()
 {
   glGenTextures(1,&glyph_tex_id_);
diff --git a/modules/gfx/src/scene.hh b/modules/gfx/src/scene.hh
index 6896d29e7fa6a933485920abeb1865ecf82bcbbd..142b4c94278a6c05270bd1aae6618c5f9576bb7c 100644
--- a/modules/gfx/src/scene.hh
+++ b/modules/gfx/src/scene.hh
@@ -102,15 +102,21 @@ class DLLEXPORT_OST_GFX Scene {
   /// \brief get the fog color
   Color GetFogColor() const;
 
-  /// \brief turn shadow on and off
+  /// \brief turn shadow mapping on and off
   void SetShadow(bool f);
 
-  /// \brief returns true if shadow is on
-  bool GetShadow();
+  /// \brief get shadow mapping status
+  bool GetShadow() const {return shadow_flag_;}
 
   /// \brief shadow quality from 0 (low) to 3 (high), default=1
   void SetShadowQuality(int q);
+
+  void SetDepthDarkening(bool f);
   
+  /// \brief select shading mode
+  /// one of fallback, basic, default, hf, toon1, toon2
+  void SetShadingMode(const std::string& smode);
+
   /// \name clipping planes
   //@{
   /// \brief get near clipping plane
@@ -345,9 +351,6 @@ class DLLEXPORT_OST_GFX Scene {
   /// \brief stops offline rendering in interactive mode
   void StopOffscreenMode();
   
-  // temporary interface
-  void ActivateShader(const String& name);
-
   void SetBlur(uint n);
   void BlurSnapshot();
 
@@ -404,6 +407,7 @@ private:
   bool shadow_flag_;
   int shadow_quality_;
   GLuint shadow_tex_id_;
+  bool depth_dark_flag_;
   GLuint depth_tex_id_;
   GLuint kernel_tex_id_;
   GLuint scene_tex_id_;
@@ -434,7 +438,8 @@ private:
   void set_far(float f);
   void update_fog();
   void prep_shadow_map();
-  void prep_depth_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 cb4af5c5b6cf1b26df661bc6ad7cc65d545d5168..982306a52484825899df521514863cc6ebc67d76 100644
--- a/modules/gfx/src/shader.cc
+++ b/modules/gfx/src/shader.cc
@@ -131,12 +131,8 @@ void Shader::Setup()
     //////////////////////////////////////////////////////////////////
     // this is the master list of all shader code in shader/
 
-    {"basic_lf_vs.glsl", GL_VERTEX_SHADER},
-    {"basic_lf_fs.glsl", GL_FRAGMENT_SHADER},
-    {"fraglight_lf_vs.glsl", GL_VERTEX_SHADER},
-    {"fraglight_lf_fs.glsl", GL_FRAGMENT_SHADER},
-    {"basic_lfs_vs.glsl", GL_VERTEX_SHADER},
-    {"basic_lfs_fs.glsl", GL_FRAGMENT_SHADER},
+    {"basic_vs.glsl", GL_VERTEX_SHADER},
+    {"basic_fs.glsl", GL_FRAGMENT_SHADER},
     {"fraglight_vs.glsl", GL_VERTEX_SHADER},
     {"fraglight_fs.glsl", GL_FRAGMENT_SHADER},
     {"basic_hf_vs.glsl", GL_VERTEX_SHADER},
@@ -186,36 +182,22 @@ void Shader::Setup()
   std::vector<GLuint> shader_program_list;
   GLuint shader_program_id;
   // basic shader
-  shader_program_list.push_back(shader_code_map_["basic_lf_vs.glsl"]);
-  shader_program_list.push_back(shader_code_map_["basic_lf_fs.glsl"]);
+  shader_program_list.push_back(shader_code_map_["basic_vs.glsl"]);
+  shader_program_list.push_back(shader_code_map_["basic_fs.glsl"]);
   if(link_shader(shader_program_list,"basic",shader_program_id)) {
     shader_program_map_["basic"]=shader_program_id;
   }
   // fraglight shader
   shader_program_list.clear();
-  shader_program_list.push_back(shader_code_map_["fraglight_lf_vs.glsl"]);
-  shader_program_list.push_back(shader_code_map_["fraglight_lf_fs.glsl"]);
-  if(link_shader(shader_program_list,"fraglight",shader_program_id)) {
-    shader_program_map_["fraglight"]=shader_program_id;
-  }
-  // basic shadow map shader
-  shader_program_list.clear();
-  shader_program_list.push_back(shader_code_map_["basic_lfs_vs.glsl"]);
-  shader_program_list.push_back(shader_code_map_["basic_lfs_fs.glsl"]);
-  if(link_shader(shader_program_list,"basic_shadow",shader_program_id)) {
-    shader_program_map_["basic_shadow"]=shader_program_id;
-  }
-  // fraglight shader with shadow map
-  shader_program_list.clear();
   shader_program_list.push_back(shader_code_map_["fraglight_vs.glsl"]);
   shader_program_list.push_back(shader_code_map_["fraglight_fs.glsl"]);
-  if(link_shader(shader_program_list,"fraglight_shadow",shader_program_id)) {
-    shader_program_map_["fraglight_shadow"]=shader_program_id;
+  if(link_shader(shader_program_list,"fraglight",shader_program_id)) {
+    shader_program_map_["fraglight"]=shader_program_id;
   }
   // basic hemisphere lighting shader
   shader_program_list.clear();
   shader_program_list.push_back(shader_code_map_["basic_hf_vs.glsl"]);
-  shader_program_list.push_back(shader_code_map_["basic_lf_fs.glsl"]);
+  shader_program_list.push_back(shader_code_map_["basic_fs.glsl"]);
   if(link_shader(shader_program_list,"hemilight",shader_program_id)) {
     shader_program_map_["hemilight"]=shader_program_id;
   }
@@ -230,8 +212,8 @@ void Shader::Setup()
   shader_program_list.clear();
   shader_program_list.push_back(shader_code_map_["toon_vs.glsl"]);
   shader_program_list.push_back(shader_code_map_["toon_fs.glsl"]);
-  if(link_shader(shader_program_list,"toon",shader_program_id)) {
-    shader_program_map_["toon"]=shader_program_id;
+  if(link_shader(shader_program_list,"toon1",shader_program_id)) {
+    shader_program_map_["toon1"]=shader_program_id;
   }
   // toon2 shader
   shader_program_list.clear();
@@ -242,7 +224,7 @@ void Shader::Setup()
   }
   // line shader
   shader_program_list.clear();
-  shader_program_list.push_back(shader_code_map_["basic_lf_vs.glsl"]);
+  shader_program_list.push_back(shader_code_map_["basic_vs.glsl"]);
   shader_program_list.push_back(shader_code_map_["aaline_fs.glsl"]);
   if(link_shader(shader_program_list,"aaline",shader_program_id)) {
     shader_program_map_["aaline"]=shader_program_id;
@@ -264,7 +246,7 @@ void Shader::Setup()
   // outline shader
   shader_program_list.clear();
   shader_program_list.push_back(shader_code_map_["outline_vs.glsl"]);
-  shader_program_list.push_back(shader_code_map_["basic_lf_fs.glsl"]);
+  shader_program_list.push_back(shader_code_map_["basic_fs.glsl"]);
   if(link_shader(shader_program_list,"outline",shader_program_id)) {
     shader_program_map_["outline"]=shader_program_id;
   }
@@ -289,14 +271,6 @@ void Shader::Activate(const String& name)
       current_program_=it->second;
       current_name_=name;
 
-      if(name=="basic_shadow" || name=="fraglight_shadow") {
-    	if(!Scene::Instance().GetShadow())
-          Scene::Instance().SetShadow(true);
-      } else {
-      	if(Scene::Instance().GetShadow())
-          Scene::Instance().SetShadow(false);
-      }
-
       UpdateState();
       return;
 
@@ -345,10 +319,28 @@ void Shader::PopProgram()
   }
 }
 
+void Shader::SetShadowMapping(bool flag, GLuint texid)
+{
+  shadow_flag_=flag;
+  if(flag) {
+    shadow_map_id_=texid;
+  }
+  UpdateState();
+}
+
+void Shader::SetDepthMapping(int mode, GLuint texid)
+{
+  depth_mode_=mode;
+  if(mode>0) {
+    depth_map_id_=texid;
+  }
+  UpdateState();
+}
+
 void Shader::UpdateState()
 {
   if(current_program_!=0) {
-    // update current lighting and fog settings, valid for all shaders
+    // update all settings
     GLint result;
     glGetIntegerv(GL_LIGHTING,&result);
     LOGN_TRACE("setting lighting flag to " << result);
@@ -360,7 +352,25 @@ void Shader::UpdateState()
     glGetIntegerv(GL_FOG,&result);
     LOGN_TRACE("setting fog flag to " << result);
     glUniform1i(glGetUniformLocation(current_program_,"fog_flag"),result);
+    if(shadow_flag_) {
+      LOGN_TRACE("setting shadow flag to 1");
+      glUniform1i(glGetUniformLocation(current_program_,"shadow_flag"),1);
+      glUniform1i(glGetUniformLocation(current_program_,"shadow_map"),shadow_map_id_);
+      glUniform1f(glGetUniformLocation(current_program_,"shadow_depth_bias"),0.008);
+      glUniform1f(glGetUniformLocation(current_program_,"shadow_epsilon"),0.002);
+      glUniform1f(glGetUniformLocation(current_program_,"shadow_multiplier"),0.4);
+    } else {
+      LOGN_TRACE("setting shadow flag to 0");
+      glUniform1i(glGetUniformLocation(current_program_,"shadow_flag"),0);
+    }
+    LOGN_TRACE("setting depth mode to" << depth_mode_);
+    glUniform1i(glGetUniformLocation(current_program_,"depth_mode"),depth_mode_);
+    if(depth_mode_>0) {
+      glUniform1i(glGetUniformLocation(current_program_,"depth_map"),depth_map_id_);
+    }
+
     glDisable(GL_COLOR_MATERIAL);
+
   } else {
     glEnable(GL_COLOR_MATERIAL);
   }
diff --git a/modules/gfx/src/shader.hh b/modules/gfx/src/shader.hh
index 054fdc37e1e98c19f27a6d29a17f20085547b895..32ea8d1297e719070c71314a4c4ec2fe288c848d 100644
--- a/modules/gfx/src/shader.hh
+++ b/modules/gfx/src/shader.hh
@@ -52,6 +52,9 @@ public:
   void PopProgram();
 
   void UpdateState();
+
+  void SetShadowMapping(bool flag, GLuint texid);
+  void SetDepthMapping(int mode, GLuint texid);
   
 private:
   Shader();
@@ -60,6 +63,11 @@ private:
   GLuint current_program_;
   String current_name_;
 
+  bool shadow_flag_;
+  GLuint shadow_map_id_;
+  int depth_mode_;
+  GLuint depth_map_id_;
+
   std::stack<String> program_stack_;
 
   std::map<String,GLuint> shader_code_map_;
diff --git a/modules/gfx/src/shader/basic_lfs_fs.glsl b/modules/gfx/src/shader/basic_fs.glsl
similarity index 86%
rename from modules/gfx/src/shader/basic_lfs_fs.glsl
rename to modules/gfx/src/shader/basic_fs.glsl
index 66d8b04415336972b8553a7146601e67516e6dea..ceda497725ff8666bda220f6ab20e734bb66bae9 100644
--- a/modules/gfx/src/shader/basic_lfs_fs.glsl
+++ b/modules/gfx/src/shader/basic_fs.glsl
@@ -1,14 +1,14 @@
 uniform sampler2D shadow_map;
 uniform bool shadow_flag;
-uniform float depth_bias;
-uniform float epsilon;
+uniform float shadow_depth_bias;
+uniform float shadow_epsilon;
 uniform float shadow_multiplier;
 uniform bool fog_flag;
 
 float CalcShadowFactor(in vec4 coord, in vec2 o)
 {
   // get original depth value of line projected towards light
-  float d = texture2D(shadow_map, coord.xy+o*epsilon).x+depth_bias;
+  float d = texture2D(shadow_map, coord.xy+o*shadow_epsilon).x+shadow_depth_bias;
   return d<=coord.z ? shadow_multiplier : 1.0;
 }
 
diff --git a/modules/gfx/src/shader/basic_lfs_vs.glsl b/modules/gfx/src/shader/basic_vs.glsl
similarity index 100%
rename from modules/gfx/src/shader/basic_lfs_vs.glsl
rename to modules/gfx/src/shader/basic_vs.glsl
diff --git a/modules/gfx/src/shader/fraglight_fs.glsl b/modules/gfx/src/shader/fraglight_fs.glsl
index d4ed6cb6f03e2eda9830169532a02672c10105d1..ac28cee890768a42313d1a3feb297b40a60b6937 100644
--- a/modules/gfx/src/shader/fraglight_fs.glsl
+++ b/modules/gfx/src/shader/fraglight_fs.glsl
@@ -4,11 +4,13 @@ uniform bool fog_flag;
 uniform bool occlusion_flag;
 uniform vec2 ambient_weight;
 varying vec4 ambient_color;
-uniform sampler2D shadow_map;
 uniform bool shadow_flag;
-uniform float depth_bias;
-uniform float epsilon;
+uniform sampler2D shadow_map;
+uniform float shadow_depth_bias;
+uniform float shadow_epsilon;
 uniform float shadow_multiplier;
+uniform sampler2D depth_map;
+uniform int depth_mode;
 
 // copy from basic_fl_vs !
 bool DirectionalLight(in vec3 normal,
@@ -38,7 +40,7 @@ bool DirectionalLight(in vec3 normal,
 float CalcShadowFactor(in vec4 coord, in vec2 o)
 {
   // get original depth value of line projected towards light
-  float d = texture2D(shadow_map, coord.xy+o*epsilon).x+depth_bias;
+  float d = texture2D(shadow_map, coord.xy+o*shadow_epsilon).x+shadow_depth_bias;
   return d<=coord.z ? shadow_multiplier : 1.0;
 }
 
diff --git a/modules/gui/src/gl_canvas.cc b/modules/gui/src/gl_canvas.cc
index 320cc3d0f129f046c9f52aa5ed775cee31a6d7d4..1b953d77ce40e08ac05766da1995fdc9fca9b286 100644
--- a/modules/gui/src/gl_canvas.cc
+++ b/modules/gui/src/gl_canvas.cc
@@ -342,35 +342,31 @@ void GLCanvas::keyPressEvent(QKeyEvent* event)
       this->CopySelectionToClipboard();
       return;
     } else if(event->key()==Qt::Key_1) {
-      gfx::Scene::Instance().ActivateShader("");
+      gfx::Scene::Instance().SetShadingMode("fallback");
       DoRefresh();
       return;
     } else if(event->key()==Qt::Key_2) {
-      gfx::Scene::Instance().ActivateShader("basic");
+      gfx::Scene::Instance().SetShadingMode("basic");
       DoRefresh();
       return;
     } else if(event->key()==Qt::Key_3) {
-      gfx::Scene::Instance().ActivateShader("fraglight");
+      gfx::Scene::Instance().SetShadingMode("default");
       DoRefresh();
       return;
     } else if(event->key()==Qt::Key_4) {
-      gfx::Scene::Instance().ActivateShader("basic_shadow");
+      gfx::Scene::Instance().SetShadingMode("hf");
       DoRefresh();
       return;
     } else if(event->key()==Qt::Key_5) {
-      gfx::Scene::Instance().ActivateShader("fraglight_shadow");
+      gfx::Scene::Instance().SetShadingMode("toon1");
       DoRefresh();
       return;
     } else if(event->key()==Qt::Key_6) {
-      gfx::Scene::Instance().ActivateShader("hemilight");
+      gfx::Scene::Instance().SetShadingMode("toon2");
       DoRefresh();
       return;
-    } else if(event->key()==Qt::Key_7) {
-      gfx::Scene::Instance().ActivateShader("toon");
-      DoRefresh();
-      return;
-    } else if(event->key()==Qt::Key_8) {
-      gfx::Scene::Instance().ActivateShader("toon2");
+    } else if(event->key()==Qt::Key_P) {
+      gfx::Scene::Instance().SetShadow(!gfx::Scene::Instance().GetShadow());
       DoRefresh();
       return;
     }