diff --git a/examples/gfx/ambient_occlusion1.py b/examples/gfx/ambient_occlusion1.py
index afacacc51a8c792cb7de12c8513b3fb4bb28cba1..80b8268aa753dab9d94fbd7fe071fff8770e82f8 100644
--- a/examples/gfx/ambient_occlusion1.py
+++ b/examples/gfx/ambient_occlusion1.py
@@ -5,7 +5,7 @@ scene.Add(gfx.Surface("s",s))
 scene.SetShadingMode("hf")
 
 # add outlines to surface
-scene["s"].Outline(True)
+scene["s"].SetOutline(True)
 scene["s"].SetOutlineMode(3)
 
 # turn on realtime ambient occlusion
diff --git a/modules/gfx/src/CMakeLists.txt b/modules/gfx/src/CMakeLists.txt
index 49dd30b678a5d316efdd2205f93ad76d90a463c9..8630622c35b5b03b808fce8d2e47c02015445a6e 100644
--- a/modules/gfx/src/CMakeLists.txt
+++ b/modules/gfx/src/CMakeLists.txt
@@ -237,8 +237,6 @@ if (USE_SHADER)
     shader/fast_sphere_fs.glsl
     shader/fast_sphere_vs.glsl
     shader/fraglight_fs.glsl
-    shader/fraglight_lf_fs.glsl
-    shader/fraglight_lf_vs.glsl
     shader/fraglight_vs.glsl
     shader/iso_fs.glsl
     shader/iso_vs.glsl
@@ -252,6 +250,7 @@ if (USE_SHADER)
     shader/toon2_fs.glsl
     shader/toon_fs.glsl
     shader/toon_vs.glsl
+    shader/screenblur4_fs.glsl
   )
   copy_if_different("./" "${SHARED_DATA_PATH}/shader" "${SHADER_FILES}" 
                     "SHADER_TARGETS" ost_gfx)  
diff --git a/modules/gfx/src/gl_helper.hh b/modules/gfx/src/gl_helper.hh
index db9c07d9f3dd82d8b806de2bed149ac29a925594..7dc1155da23abf28d16fdb8e50e279b94b3e102b 100644
--- a/modules/gfx/src/gl_helper.hh
+++ b/modules/gfx/src/gl_helper.hh
@@ -112,5 +112,13 @@ inline void glLoadMatrix(double* arr) {
   glLoadMatrixd(arr);
 }
 
+inline void glLoadTransposeMatrix(float* arr) {
+  glLoadTransposeMatrixf(arr);
+}
+
+inline void glLoadTransposeMatrix(double* arr) {
+  glLoadTransposeMatrixd(arr);
+}
+
 
 #endif
diff --git a/modules/gfx/src/impl/scene_fx.cc b/modules/gfx/src/impl/scene_fx.cc
index 16d6c426f5d9a1da5587b1db5c90ca8b29d24028..ae2778d8328e2790e403c6c731787f1dce885631 100644
--- a/modules/gfx/src/impl/scene_fx.cc
+++ b/modules/gfx/src/impl/scene_fx.cc
@@ -293,8 +293,7 @@ void SceneFX::Postprocess()
     glBindTexture(GL_TEXTURE_2D,shadow_tex_id_);
     glMatrixMode(GL_TEXTURE);
     glPushMatrix();
-    geom::Mat4 ttmp=geom::Transpose(shadow_tex_mat_);
-    glLoadMatrix(ttmp.Data());
+    glLoadTransposeMatrix(shadow_tex_mat_.Data());
     glMatrixMode(GL_MODELVIEW);
     glActiveTexture(GL_TEXTURE0);
     glUniform1i(glGetUniformLocation(cpr,"shadow_flag"),1);
@@ -660,8 +659,7 @@ void SceneFX::draw_beacon()
   glBindTexture(GL_TEXTURE_2D,depth_tex_id_);
   glMatrixMode(GL_TEXTURE);
   glPushMatrix();
-  geom::Mat4 ttmp=geom::Transpose(beacon.mat);
-  glLoadMatrix(ttmp.Data());
+  glLoadTransposeMatrix(beacon.mat.Data());
   glActiveTexture(GL_TEXTURE0);
   glUniform1i(glGetUniformLocation(cpr,"depth_map"),1);
   glUniform3f(glGetUniformLocation(cpr,"pos"),beacon.p0[0],beacon.p0[1],beacon.p0[2]);
@@ -713,5 +711,28 @@ void SceneFX::draw_beacon()
   Shader::Instance().PopProgram();
 }
 
+void SceneFX::screenblur4()
+{
+  Viewport vp=Scene::Instance().GetViewport();
+  glBindTexture(GL_TEXTURE_2D, scene_tex_id_);
+  glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, vp.x, vp.y, vp.width, vp.height, 0);
+  glBindTexture(GL_TEXTURE_2D, depth_tex_id_);
+  glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, vp.x, vp.y, vp.width, vp.height, 0);
+  Shader::Instance().PushProgram();
+  Shader::Instance().Activate("screenblur4");
+  GLuint cpr=Shader::Instance().GetCurrentProgram();
+  glActiveTexture(GL_TEXTURE1);
+  glBindTexture(GL_TEXTURE_2D,depth_tex_id_);
+  glActiveTexture(GL_TEXTURE0);
+  glBindTexture(GL_TEXTURE_2D,scene_tex_id_);
+  glUniform1i(glGetUniformLocation(cpr,"scene_map"),0);
+  glUniform1i(glGetUniformLocation(cpr,"depth_map"),1);
+  glUniform2f(glGetUniformLocation(cpr,"i_vp"),
+              1.0/static_cast<float>(vp.width),
+              1.0/static_cast<float>(vp.height));
+  glUniform1f(glGetUniformLocation(cpr,"depth_cutoff"),0.5);
+  draw_screen_quad(vp.width,vp.height);
+  Shader::Instance().PopProgram();
+}
 
 }}} // ns
diff --git a/modules/gfx/src/impl/scene_fx.hh b/modules/gfx/src/impl/scene_fx.hh
index e4def5e09b571a936fd28cda71c3b9ef34493fe9..49961c340139796df3fea2253c1215c1c2c4d8b3 100644
--- a/modules/gfx/src/impl/scene_fx.hh
+++ b/modules/gfx/src/impl/scene_fx.hh
@@ -73,6 +73,7 @@ private:
   SceneFX(const SceneFX&) {}
   SceneFX& operator=(const SceneFX&) {return *this;}
 
+  void screenblur4();
   void prep_shadow_map();
   void prep_depth_darkening();
   void prep_amb_occlusion();
diff --git a/modules/gfx/src/shader.cc b/modules/gfx/src/shader.cc
index 01674489b5d95cb751d6110b900a0361ea7e3de5..81df738587895a1f4c8dad546a78bcea749c441a 100644
--- a/modules/gfx/src/shader.cc
+++ b/modules/gfx/src/shader.cc
@@ -161,7 +161,8 @@ void Shader::Setup()
     {"amboccl_fs.glsl", GL_FRAGMENT_SHADER},
     {"scenefx_vs.glsl", GL_VERTEX_SHADER},
     {"scenefx_fs.glsl", GL_FRAGMENT_SHADER},
-    {"beacon_fs.glsl", GL_FRAGMENT_SHADER}
+    {"beacon_fs.glsl", GL_FRAGMENT_SHADER},
+    {"screenblur4_fs.glsl", GL_FRAGMENT_SHADER}
     //////////////////////////////////////////////////////////////////
   };
 
@@ -297,6 +298,13 @@ void Shader::Setup()
   if(link_shader(shader_program_list,"scenefx",shader_program_id)) {
     shader_program_map_["scenefx"]=shader_program_id;
   }
+  // screen blur shader
+  shader_program_list.clear();
+  shader_program_list.push_back(shader_code_map_["quadpp_vs.glsl"]);
+  shader_program_list.push_back(shader_code_map_["screenblur4_fs.glsl"]);
+  if(link_shader(shader_program_list,"screenblur4",shader_program_id)) {
+    shader_program_map_["screenblur4"]=shader_program_id;
+  }
 
   valid_=true;
 }
diff --git a/modules/gfx/src/shader/amboccl_fs.glsl b/modules/gfx/src/shader/amboccl_fs.glsl
index 894290241609d5d894144bafac56509b0d92fa22..2d7819565c59158fc80272ce19bc059e7dfaeb9f 100644
--- a/modules/gfx/src/shader/amboccl_fs.glsl
+++ b/modules/gfx/src/shader/amboccl_fs.glsl
@@ -6,6 +6,8 @@ uniform vec2 i_vp;
 uniform vec4 abcd;
 uniform int mode;
 
+// gl_TexCoord[0] comes from quadpp_vs, i.e. from post processing
+
 vec3 unproject(in vec3 rpos)
 { 
   vec4 coord = gl_TextureMatrix[0]*vec4(rpos.xy*2.0-1.0,rpos.z*2.0-1.0,1.0);
diff --git a/modules/gfx/src/shader/basic_fs.glsl b/modules/gfx/src/shader/basic_fs.glsl
index e38a3ada59214e98b001815bf6e9a1bc7f6007ac..9856cd3a47445b3ea94d57e9e00ea34c90ec2474 100644
--- a/modules/gfx/src/shader/basic_fs.glsl
+++ b/modules/gfx/src/shader/basic_fs.glsl
@@ -5,6 +5,5 @@ void main()
   float fog = fog_flag ? clamp((gl_Fog.end-gl_FogFragCoord) * gl_Fog.scale, 0.0, 1.0) : 1.0;
   gl_FragColor.rgb = mix(gl_Fog.color.rgb, gl_Color.rgb, fog);
   gl_FragColor.a = gl_Color.a;
-  // gl_FragBuffer[1].rgb=gl_TexCoord[0].stp*0.5+0.5;
 }
 
diff --git a/modules/gfx/src/shader/basic_vs.glsl b/modules/gfx/src/shader/basic_vs.glsl
index 10cdf3a2439b017f7e922544e8f2c558e1038c16..7c1a080f15600d8cc1626d3b38307e9bc61a7969 100644
--- a/modules/gfx/src/shader/basic_vs.glsl
+++ b/modules/gfx/src/shader/basic_vs.glsl
@@ -56,7 +56,7 @@ void main()
   vec4 ec_Pos = gl_ModelViewMatrix* gl_Vertex;
 
   vec3 normal = normalize(gl_NormalMatrix * gl_Normal);
-  gl_TexCoord[0].stp = normal;
+  gl_TexCoord[2].stp = normal;
   
   if(lighting_flag) {
     CalcFrontAndBackColor(normal);
@@ -67,8 +67,5 @@ void main()
 
   // for some reason, the fog and z coordinate are sign toggled...
   gl_FogFragCoord = -ec_Pos.z;
-
-  // shadow map projection coords
-  gl_TexCoord[1] = gl_TextureMatrix[0] * gl_Vertex;
 }
 
diff --git a/modules/gfx/src/shader/beacon_fs.glsl b/modules/gfx/src/shader/beacon_fs.glsl
index c1423640ee10ab4ff9abc34d95c000eb52a45ff6..aa910131fe554bd79338bdf54c4f2e01130501e8 100644
--- a/modules/gfx/src/shader/beacon_fs.glsl
+++ b/modules/gfx/src/shader/beacon_fs.glsl
@@ -4,6 +4,8 @@ uniform float len;
 uniform float rad;
 uniform sampler2D depth_map;
 
+// gl_TexCoord[0] comes from scenefx_vs, i.e. from post processing
+
 void main()
 {
   float depth = texture2D(depth_map,gl_TexCoord[0].xy).r;
diff --git a/modules/gfx/src/shader/convolute1_fs.glsl b/modules/gfx/src/shader/convolute1_fs.glsl
index 3e1564ecd4662ab159ab0006eec6d1e5d2f0c1c1..41d89053d6ad2bc973fc5c0724d5e81109d503c2 100644
--- a/modules/gfx/src/shader/convolute1_fs.glsl
+++ b/modules/gfx/src/shader/convolute1_fs.glsl
@@ -3,6 +3,8 @@ uniform sampler1D kernel;
 uniform float step;
 uniform vec2 i_vp;
 
+// gl_TexCoord[0] comes from quadpp_vs, i.e. from post processing
+
 void main()
 {
   float i;
diff --git a/modules/gfx/src/shader/fast_sphere_fs.glsl b/modules/gfx/src/shader/fast_sphere_fs.glsl
index 0a18ab1ad324f833e92c7be67e4edc2458b9baf7..8832b5e28f850064d68a1082b050ed4ccb88ac04 100644
--- a/modules/gfx/src/shader/fast_sphere_fs.glsl
+++ b/modules/gfx/src/shader/fast_sphere_fs.glsl
@@ -3,6 +3,9 @@ uniform bool two_sided_flag;
 uniform bool fog_flag;
 uniform bool write_normals;
 
+// gl_TexCoord[0] is from gl_MultiTexCoord0, which in turn
+// is custom crafted in the fast sphere prep routine
+
 // copy from basic_fl_vs !
 bool DirectionalLight(in vec3 normal,
                       in float shin,
diff --git a/modules/gfx/src/shader/fraglight_fs.glsl b/modules/gfx/src/shader/fraglight_fs.glsl
index f390283fc59c4f940a4f1203d9f270e043ac01dd..76ff5dfaff9dbef8def110bee406ae67407fedac 100644
--- a/modules/gfx/src/shader/fraglight_fs.glsl
+++ b/modules/gfx/src/shader/fraglight_fs.glsl
@@ -1,11 +1,10 @@
 uniform bool lighting_flag;
 uniform bool two_sided_flag;
 uniform bool fog_flag;
-uniform bool occlusion_flag;
-uniform vec2 ambient_weight;
-varying vec4 ambient_color;
 uniform sampler2D depth_map;
 uniform int depth_mode;
+uniform bool tex_flag;
+uniform sampler2D tex_map;
 
 // copy from basic_fl_vs !
 bool DirectionalLight(in vec3 normal,
@@ -34,29 +33,21 @@ bool DirectionalLight(in vec3 normal,
 void main()
 {
   bool lflag=false;
+
+  vec4 color = gl_Color;
+
+  if(tex_flag) {
+    color.rgb = texture2D(tex_map,gl_TexCoord[0].st).rgb;
+  }
+
   if(lighting_flag) {
-    vec3 normal = normalize(gl_TexCoord[0].stp);
+    vec3 normal = normalize(gl_TexCoord[2].stp);
 
     vec4 amb = vec4(0.0);
     vec4 diff = vec4(0.0);
     vec4 spec = vec4(0.0);
 
-    vec4 color = gl_Color;
-    if(occlusion_flag) {
-      /* 
-        For ambient occlusion and local coloring, two effects are possible. 
-        (1) Blending of the original fragment color and the accumulated
-            color of the neighbouring fragments, by ambient_weight[0].
-        (2) Attenuating the resulting color intensity by the ambient occlusion,
-            modulated by ambient_weight[1]
-        Only the rgb values are affected, fragment opacity is unchanged
-      */
-
-      color.rgb = mix(gl_Color.rgb,ambient_color.rgb,ambient_weight[0]);
-      color.rgb = mix(color.rgb,ambient_color.aaa*color.rgb,ambient_weight[1]);
-    }
-
-    if(DirectionalLight(normal, gl_FrontMaterial.shininess, amb, diff, spec,lflag)) {
+    if(DirectionalLight(normal, gl_FrontMaterial.shininess, amb, diff, spec, lflag)) {
 
       color  = gl_FrontLightModelProduct.sceneColor  +
                (amb  * gl_FrontMaterial.ambient * color) +
@@ -71,15 +62,11 @@ void main()
               (diff * gl_BackMaterial.diffuse * color) +
               (spec * gl_BackMaterial.specular);
     }
-    
-    gl_FragColor = color;
-
-  } else {
-    gl_FragColor = gl_Color;
   }
 
+  gl_FragColor = color;
+
   float fog = fog_flag ? clamp((gl_Fog.end-gl_FogFragCoord) * gl_Fog.scale, 0.0, 1.0) : 1.0;
   gl_FragColor.rgb = mix(gl_Fog.color.rgb, gl_FragColor.rgb, fog);
   gl_FragColor.a = gl_Color.a;
-  //gl_FragBuffer[1].rgb=gl_TexCoord[0].stp*0.5+0.5;
 }
diff --git a/modules/gfx/src/shader/fraglight_lf_fs.glsl b/modules/gfx/src/shader/fraglight_lf_fs.glsl
deleted file mode 100644
index ad34b9f401a65f0b43470b519168f35195477b7f..0000000000000000000000000000000000000000
--- a/modules/gfx/src/shader/fraglight_lf_fs.glsl
+++ /dev/null
@@ -1,80 +0,0 @@
-uniform bool lighting_flag;
-uniform bool two_sided_flag;
-uniform bool fog_flag;
-uniform bool occlusion_flag;
-uniform vec2 ambient_weight;
-varying vec4 ambient_color;
-
-// copy from basic_fl_vs !
-bool DirectionalLight(in vec3 normal,
-                      in float shin,
-                      inout vec4 ambient,
-                      inout vec4 diffuse,
-                      inout vec4 specular)
-{
-  float n_vp = max(0.0, dot(normal, normalize(gl_LightSource[0].position.xyz)));
-
-  float pf = 0.0;
-  if(n_vp>0.0 && shin>0.0) {
-    float n_hv = max(0.0, dot(normal, normalize(gl_LightSource[0].halfVector.xyz)));
-    pf=pow(n_hv, shin);
-  }
-
-  ambient  += gl_LightSource[0].ambient;
-  diffuse  += gl_LightSource[0].diffuse * n_vp;
-  specular += gl_LightSource[0].specular * pf;
-
-  return true;
-}
-
-void main()
-{
-  if(lighting_flag) {
-    vec3 normal = normalize(gl_TexCoord[0].stp);
-
-    vec4 amb = vec4(0.0);
-    vec4 diff = vec4(0.0);
-    vec4 spec = vec4(0.0);
-
-    vec4 color = gl_Color;
-    if(occlusion_flag) {
-      /* 
-        For ambient occlusion and local coloring, two effects are possible. 
-        (1) Blending of the original fragment color and the accumulated
-            color of the neighbouring fragments, by ambient_weight[0].
-        (2) Attenuating the resulting color intensity by the ambient occlusion,
-            modulated by ambient_weight[1]
-        Only the rgb values are affected, fragment opacity is unchanged
-      */
-
-      color.rgb = mix(gl_Color.rgb,ambient_color.rgb,ambient_weight[0]);
-      color.rgb = mix(color.rgb,ambient_color.aaa*color.rgb,ambient_weight[1]);
-    }
-
-    if(DirectionalLight(normal, gl_FrontMaterial.shininess, amb, diff, spec)) {
-
-      color  = gl_FrontLightModelProduct.sceneColor  +
-               (amb  * gl_FrontMaterial.ambient * color) +
-               (diff * gl_FrontMaterial.diffuse * color) +
-               (spec * gl_FrontMaterial.specular);
-    } else {
-      DirectionalLight(-normal, gl_BackMaterial.shininess, amb, diff, spec);
-
-      color = gl_BackLightModelProduct.sceneColor  +
-              (amb  * gl_BackMaterial.ambient * color) +
-              (diff * gl_BackMaterial.diffuse * color) +
-              (spec * gl_BackMaterial.specular);
-    }
-    
-    gl_FragColor = color;
-
-  } else {
-    gl_FragColor = gl_Color;
-  }
-
-  if(fog_flag) {
-    float fog = clamp((gl_Fog.end-gl_FogFragCoord) * gl_Fog.scale, 0.0, 1.0);
-    gl_FragColor.rgb = mix(gl_Fog.color.rgb, gl_FragColor.rgb, fog);
-  }
-  gl_FragColor.a = gl_Color.a;
-}
diff --git a/modules/gfx/src/shader/fraglight_lf_vs.glsl b/modules/gfx/src/shader/fraglight_lf_vs.glsl
deleted file mode 100644
index be5b64918b29e308fa85594f3b3a6f5490cfcc85..0000000000000000000000000000000000000000
--- a/modules/gfx/src/shader/fraglight_lf_vs.glsl
+++ /dev/null
@@ -1,27 +0,0 @@
-uniform bool occlusion_flag;
-varying vec4 ambient_color;
-
-void main()
-{
-  // transformed position
-  gl_Position = ftransform();
-
-  vec4 ec_Pos = gl_ModelViewMatrix* gl_Vertex;
-  // for some reason, the fog and z coordinate are sign toggled...
-  gl_FogFragCoord = -ec_Pos.z;
-
-  vec3 normal = normalize(gl_NormalMatrix * gl_Normal);
-  // since a directional light is used, the position is not needed
-  gl_TexCoord[0].stp=normal;
-
-  if(occlusion_flag) {
-    // ambient occlusion and color terms
-    ambient_color = gl_MultiTexCoord0;
-  } else {
-    ambient_color.rgb = gl_Color;
-    ambient_color.a = 1.0;
-  }
-  gl_FrontColor=gl_Color;
-  gl_BackColor=gl_Color;
-}
-
diff --git a/modules/gfx/src/shader/fraglight_vs.glsl b/modules/gfx/src/shader/fraglight_vs.glsl
index 9b1856d12cd8920f0b87e7306385377f0b6237a4..279016e1443fe061d0636f897d5d8b07829e5a9a 100644
--- a/modules/gfx/src/shader/fraglight_vs.glsl
+++ b/modules/gfx/src/shader/fraglight_vs.glsl
@@ -1,6 +1,3 @@
-uniform bool occlusion_flag;
-varying vec4 ambient_color;
-
 void main()
 {
   // transformed position
@@ -10,20 +7,13 @@ void main()
   // for some reason, the fog and z coordinate are sign toggled...
   gl_FogFragCoord = -ec_Pos.z;
 
-  vec3 normal = normalize(gl_NormalMatrix * gl_Normal);
   // since a directional light is used, the position is not needed
-  gl_TexCoord[0].stp=normal;
+  // and only the normal is passed on
+  gl_TexCoord[2].stp=normalize(gl_NormalMatrix * gl_Normal);
 
-  // shadow map projection coords
-  gl_TexCoord[1] = gl_TextureMatrix[0] * gl_Vertex;
+  // default tex coord
+  gl_TexCoord[0] = gl_MultiTexCoord0;
 
-  if(occlusion_flag) {
-    // ambient occlusion and color terms
-    ambient_color = gl_MultiTexCoord0;
-  } else {
-    ambient_color.rgb = gl_Color.rgb;
-    ambient_color.a = 1.0;
-  }
   gl_FrontColor=gl_Color;
   gl_BackColor=gl_Color;
 }
diff --git a/modules/gfx/src/shader/scenefx_fs.glsl b/modules/gfx/src/shader/scenefx_fs.glsl
index 277647ee47f603fa25782d291142f4ec30463231..cb5c2313c77dced05f81fdd4854704ebbb4b9a6c 100644
--- a/modules/gfx/src/shader/scenefx_fs.glsl
+++ b/modules/gfx/src/shader/scenefx_fs.glsl
@@ -14,6 +14,8 @@ uniform bool dark_flag;
 uniform sampler2D dark_map;
 uniform float dark_mult;
 
+// gl_TexCoord[0] comes from scenefx_vs, i.e. from post processing
+
 float CalcShadowFactor(in vec4 coord, in vec2 o)
 {
   // get original depth value of line projected towards light
diff --git a/modules/gfx/src/shader/scenefx_vs.glsl b/modules/gfx/src/shader/scenefx_vs.glsl
index 6732327afc56aaee4a7fc353ed0c2e26d58c6f5b..043c65d69b2d1a4f96d705cc84d12ba9b847d592 100644
--- a/modules/gfx/src/shader/scenefx_vs.glsl
+++ b/modules/gfx/src/shader/scenefx_vs.glsl
@@ -1,7 +1,6 @@
 void main()
 {    
   gl_Position = ftransform();
-  // relative screen coordinates
   gl_TexCoord[0] = gl_MultiTexCoord0;
 }
 
diff --git a/modules/gfx/src/shader/screenblur4_fs.glsl b/modules/gfx/src/shader/screenblur4_fs.glsl
new file mode 100644
index 0000000000000000000000000000000000000000..9bf2df9e28f57c54a0c49d9e8e48396f38aaad16
--- /dev/null
+++ b/modules/gfx/src/shader/screenblur4_fs.glsl
@@ -0,0 +1,33 @@
+uniform sampler2D scene_map;
+uniform sampler2D depth_map;
+uniform vec2 i_vp;
+uniform float depth_cutoff;
+
+void main()
+{
+  // reference depth
+  float depth = texture2D(depth_map,gl_TexCoord[0].xy).r;
+
+  vec4 scene_color=vec4(0.0,0.0,0.0,0.0);
+
+  int count=0;
+  for(float x=-1.5;x<1.51;x+=1.0) {
+    for(float y=-1.5;y<1.51;y+=1.0) {
+      vec2 p = gl_TexCoord[0].xy+vec2(x*i_vp[0],y*i_vp[1]);
+      float dd = abs(depth-texture2D(depth_map,p).r);
+      if(dd<depth_cutoff) {
+        ++count;
+        scene_color+=texture2D(scene_map,p);
+      }
+    }
+  }
+
+  if (count==0) {
+    scene_color=texture2D(scene_map,gl_TexCoord[0].xy);
+  } else {
+    scene_color/=float(count);
+  }
+
+  gl_FragColor=scene_color;
+
+}
\ No newline at end of file
diff --git a/modules/gfx/src/shader/toon2_fs.glsl b/modules/gfx/src/shader/toon2_fs.glsl
index 7d5dc45f0bc0bfbef1bf0bb99cb790db315ab1ab..ae12978378d24389a124313e3c6b70120ea81061 100644
--- a/modules/gfx/src/shader/toon2_fs.glsl
+++ b/modules/gfx/src/shader/toon2_fs.glsl
@@ -33,7 +33,7 @@ void main()
   vec4 diff = vec4(0.0);
   vec4 spec = vec4(0.0);
   vec4 color = vec4(0.0);
-  vec3 normal = normalize(gl_TexCoord[0].stp);
+  vec3 normal = normalize(gl_TexCoord[2].stp);
 
   DirectionalLight(normal, gl_FrontMaterial.shininess, amb, diff, spec);
 
diff --git a/modules/gfx/src/shader/toon_fs.glsl b/modules/gfx/src/shader/toon_fs.glsl
index 06c17f7870e26275efc7e342beea90419bc3334e..4298ec02a44ff781e8dd87604a0d993403676d4e 100644
--- a/modules/gfx/src/shader/toon_fs.glsl
+++ b/modules/gfx/src/shader/toon_fs.glsl
@@ -25,7 +25,7 @@ void main()
   vec4 amb = vec4(0.0);
   vec4 diff = vec4(0.0);
   vec4 color = vec4(0.0);
-  vec3 normal = normalize(gl_TexCoord[0].stp);
+  vec3 normal = normalize(gl_TexCoord[2].stp);
 
   DirectionalLight(normal, amb, diff);
 
diff --git a/modules/gfx/src/shader/toon_vs.glsl b/modules/gfx/src/shader/toon_vs.glsl
index 3eb50da66c4c31edbee7d197fa2e21e8a2b87bf4..c4624ebd72fa4899fd56e4acac138d6dcc70c2bc 100644
--- a/modules/gfx/src/shader/toon_vs.glsl
+++ b/modules/gfx/src/shader/toon_vs.glsl
@@ -12,7 +12,7 @@ void main()
     normal = normalize(gl_NormalMatrix * gl_Normal);
   }
   // since a directional light is used, the position is not needed
-  gl_TexCoord[0].stp=normal;
+  gl_TexCoord[2].stp=normal;
 
   gl_FrontColor=gl_Color;
   gl_BackColor=gl_Color;
diff --git a/modules/gfx/src/vertex_array.cc b/modules/gfx/src/vertex_array.cc
index b2a30a6df7dc2cc83b64676ac2d166c0db4820c5..541b881511c621c4bf3aa3df75d91ed319059231 100644
--- a/modules/gfx/src/vertex_array.cc
+++ b/modules/gfx/src/vertex_array.cc
@@ -62,13 +62,15 @@ IndexedVertexArray::Entry::Entry()
   v[0]=0.0; v[1]=0.0; v[2]=0.0;
   n[0]=0.0; n[1]=0.0; n[2]=1.0;
   c[0]=0.0; c[1]=0.0; c[2]=0.0; c[3]=0.0;
+  t[0]=0.0; t[1]=0.0;
 }
 
-IndexedVertexArray::Entry::Entry(const Vec3& vv, const Vec3& nn, const Color& cc)
+  IndexedVertexArray::Entry::Entry(const Vec3& vv, const Vec3& nn, const Color& cc, const geom::Vec2& tt)
 {
   v[0]=vv[0]; v[1]=vv[1]; v[2]=vv[2];
   n[0]=nn[0]; n[1]=nn[1]; n[2]=nn[2];
   c[0]=cc[0]; c[1]=cc[1]; c[2]=cc[2]; c[3]=cc[3];
+  t[0]=tt[0]; t[1]=tt[1];
 }
 
 
@@ -76,6 +78,7 @@ IndexedVertexArray::IndexedVertexArray()
 {
   initialized_=false;
   Reset(); // replaces ctor initialization list
+  glGenTextures(1,&tex_id_);
 }
 
 IndexedVertexArray::~IndexedVertexArray()
@@ -85,24 +88,27 @@ IndexedVertexArray::~IndexedVertexArray()
 IndexedVertexArray::IndexedVertexArray(const IndexedVertexArray& va)
 {
   copy(va);
+  glGenTextures(1,&tex_id_);
 }
 
 IndexedVertexArray& IndexedVertexArray::operator=(const IndexedVertexArray& va)
 {
   copy(va);
+  // keep already allocated tex id
   return *this;
 }
 
 unsigned int IndexedVertexArray::GetFormat()
 {
   // hardcoded for now, may be refactored and moved into an impl
-  return GL_C4F_N3F_V3F;
+  return GL_T2F_C4F_N3F_V3F;
 }
 
 
 void IndexedVertexArray::Cleanup() 
 {
   if(initialized_) {
+    glDeleteTextures(1,&tex_id_);
     glDeleteLists(outline_mat_dlist_,1);
 #if OST_SHADER_SUPPORT_ENABLED
     glDeleteBuffers(7,buffer_id_);
@@ -137,10 +143,11 @@ void IndexedVertexArray::SetOutlineExpandColor(const Color& c) {outline_exp_colo
 
 VertexID IndexedVertexArray::Add(const Vec3& vert, 
                                  const Vec3& norm,
-                                 const Color& col) 
+                                 const Color& col,
+                                 const Vec2& texc) 
 {
   dirty_=true;
-  entry_list_.push_back(Entry(vert,norm,col));
+  entry_list_.push_back(Entry(vert,norm,col,texc));
   return entry_list_.size()-1;
 }
 
@@ -352,6 +359,21 @@ void IndexedVertexArray::SetColor(VertexID id, const Color& c)
   entry_list_[id].c[3]=c[3];
 }
 
+Vec2 IndexedVertexArray::GetTexCoord(VertexID id) const
+{
+  Vec2 nrvo;
+  if(id>=entry_list_.size()) return nrvo;
+  nrvo = Vec2(entry_list_[id].t);
+  return nrvo;
+} 
+
+void IndexedVertexArray::SetTexCoord(VertexID id, const Vec2& t) 
+{
+  if(id>=entry_list_.size()) return;
+  entry_list_[id].t[0]=t[0];
+  entry_list_[id].t[1]=t[1];
+}
+
 void IndexedVertexArray::SetOpacity(float o)
 {
   o=std::max(0.0f,std::min(1.0f,o));
@@ -648,6 +670,7 @@ void IndexedVertexArray::Reset()
   outline_exp_factor_=0.1;
   outline_exp_color_=Color(0,0,0);
   draw_normals_=false;
+  use_tex_=false;
 }
 
 void IndexedVertexArray::FlagRefresh()
@@ -937,7 +960,7 @@ void IndexedVertexArray::NPatch()
   IndexList tri_index_list;
   IndexList line_index_list;
 
-  entry_list.push_back(Entry(Vec3(),Vec3(),Color(1,0,0)));
+  entry_list.push_back(Entry(Vec3(),Vec3(),Color(1,0,0),Vec2()));
 
   for(uint c=0;c<tri_index_list_.size();) {
     VertexID id0 = tri_index_list_[c++];
@@ -975,7 +998,8 @@ void IndexedVertexArray::NPatch()
           3.0*(u*u*v*p210+u*u*w*p201+u*v*v*p120+v*v*w*p021+v*w*w*p012+u*w*w*p102)+
           6.0*u*v*w*p111;
         Vec3 n = Normalize(u*u*n200+v*v*n020+w*w*n002+u*v*n110+u*w*n101+v*w*n011);
-        entry_list.push_back(Entry(p,n,Color()));
+        // TODO: patch texture coord as well
+        entry_list.push_back(Entry(p,n,Color(),Vec2()));
         tab[npatch_tab_id(uc,vc,N)] = entry_list.size()-1;
       }
     }
@@ -1042,6 +1066,7 @@ void IndexedVertexArray::copy(const IndexedVertexArray& va)
   outline_exp_factor_=va.outline_exp_factor_;
   outline_exp_color_=va.outline_exp_color_;
   draw_normals_=va.draw_normals_;
+  use_tex_=va.use_tex_;
 }
   
 bool IndexedVertexArray::prep_buff()
@@ -1129,9 +1154,12 @@ void IndexedVertexArray::draw_ltq(bool use_buff)
       in place of the absolute pointer
     */
     glBindBuffer(GL_ARRAY_BUFFER, buffer_id_[VA_VERTEX_BUFFER]);
-    glVertexPointer(3, GL_FLOAT, sizeof(Entry), reinterpret_cast<void*>(sizeof(float)*7));
-    glNormalPointer(GL_FLOAT, sizeof(Entry), reinterpret_cast<void*>(sizeof(float)*4));
-    glColorPointer(4, GL_FLOAT, sizeof(Entry), 0);
+    glVertexPointer(3, GL_FLOAT, sizeof(Entry), reinterpret_cast<void*>(sizeof(float)*9));
+    glNormalPointer(GL_FLOAT, sizeof(Entry), reinterpret_cast<void*>(sizeof(float)*6));
+    glColorPointer(4, GL_FLOAT, sizeof(Entry), reinterpret_cast<void*>(sizeof(float)*2));
+    if(use_tex_) {
+      glTexCoordPointer(2, GL_FLOAT, sizeof(Entry), 0);
+    }
 #else
     glBindBuffer(GL_ARRAY_BUFFER, buffer_id_[VA_VERTEX_BUFFER]);
     glInterleavedArrays(GetFormat(),sizeof(Entry),NULL);
@@ -1179,9 +1207,12 @@ void IndexedVertexArray::draw_p(bool use_buff)
   if(use_buff && !Scene::Instance().InOffscreenMode()) {
 #if OST_SHADER_SUPPORT_ENABLED
     glBindBuffer(GL_ARRAY_BUFFER, buffer_id_[VA_VERTEX_BUFFER]);
-    glVertexPointer(3, GL_FLOAT, sizeof(Entry), reinterpret_cast<void*>(sizeof(float)*7));
-    glNormalPointer(GL_FLOAT, sizeof(Entry), reinterpret_cast<void*>(sizeof(float)*4));
-    glColorPointer(4, GL_FLOAT, sizeof(Entry), 0);
+    glVertexPointer(3, GL_FLOAT, sizeof(Entry), reinterpret_cast<void*>(sizeof(float)*9));
+    glNormalPointer(GL_FLOAT, sizeof(Entry), reinterpret_cast<void*>(sizeof(float)*6));
+    glColorPointer(4, GL_FLOAT, sizeof(Entry), reinterpret_cast<void*>(sizeof(float)*2));
+    if(use_tex_) {
+      glTexCoordPointer(2, GL_FLOAT, sizeof(Entry), 0);
+    }
     glDrawArrays(GL_POINTS,0,entry_list_.size());
 #endif
   } else {
diff --git a/modules/gfx/src/vertex_array.hh b/modules/gfx/src/vertex_array.hh
index c1916dc7ffe52f091c7a4e7adccedf530f87b9b8..332f03df3eadf12f2414585c02c070ddb43ba1b5 100644
--- a/modules/gfx/src/vertex_array.hh
+++ b/modules/gfx/src/vertex_array.hh
@@ -49,7 +49,8 @@ class DLLEXPORT_OST_GFX IndexedVertexArray {
  public:
   struct Entry {
     Entry();
-    Entry(const geom::Vec3& vv, const geom::Vec3& nn, const Color& cc);
+    Entry(const geom::Vec3& vv, const geom::Vec3& nn, const Color& cc, const geom::Vec2& tt);
+    float t[2];
     float c[4];
     float n[3];
     float v[3];
@@ -111,7 +112,7 @@ class DLLEXPORT_OST_GFX IndexedVertexArray {
   void SetOutlineExpandColor(const Color& c);
 
   // vertex, normal, and color (C4F_N3F_V3F)
-  VertexID Add(const geom::Vec3& vert, const geom::Vec3& norm, const Color& col);
+  VertexID Add(const geom::Vec3& vert, const geom::Vec3& norm, const Color& col, const geom::Vec2& tex=geom::Vec2());
 
   unsigned int GetVertexCount() const;
   void DumpVertices() const;
@@ -145,6 +146,9 @@ class DLLEXPORT_OST_GFX IndexedVertexArray {
   Color GetColor(VertexID id) const;
   void SetColor(VertexID id, const Color& col);
 
+  geom::Vec2 GetTexCoord(VertexID id) const;
+  void SetTexCoord(VertexID id, const geom::Vec2& tex);
+
   void SetOpacity(float o);
 
   // OpenGL rendering call
@@ -178,6 +182,8 @@ class DLLEXPORT_OST_GFX IndexedVertexArray {
   // experimental, do not use
   void SmoothVertices(float smoothf);
 
+  void SetTex(bool b) {use_tex_=b;}
+  uint& TexID() {return tex_id_;}
 
   const EntryList& GetEntries() const {return entry_list_;}
   const IndexList& GetQuadIndices() const {return quad_index_list_;}
@@ -216,6 +222,9 @@ class DLLEXPORT_OST_GFX IndexedVertexArray {
 
   bool draw_normals_;
 
+  bool use_tex_;
+  uint tex_id_;
+
   unsigned int buffer_id_[7]; // magic number related to the .cc buffer use
 
   void copy(const IndexedVertexArray& va);