diff --git a/modules/gfx/pymod/export_gfx_obj.cc b/modules/gfx/pymod/export_gfx_obj.cc
index 07d845636676fbd2c381ee1bbab25a4bf8aa0ca4..68e88f90169ae1c1f190a3b778da26d0f63160a1 100644
--- a/modules/gfx/pymod/export_gfx_obj.cc
+++ b/modules/gfx/pymod/export_gfx_obj.cc
@@ -157,6 +157,9 @@ void export_GfxObj()
     .add_property("opacity",&GfxObjBase::GetOpacity,&GfxObjBase::SetOpacity)
     .add_property("solid",&GfxObjBase::GetSolid,&GfxObjBase::SetSolid)
     .add_property("solid_color",&GfxObjBase::GetSolidColor,&GfxObjBase::SetSolidColor)
+    .add_property("clip",&GfxObjBase::GetClip,&GfxObjBase::SetClip)
+    .add_property("clip_plane",&GfxObjBase::GetClipPlane,&GfxObjBase::SetClipPlane)
+    .add_property("clip_offset",&GfxObjBase::GetClipOffset,&GfxObjBase::SetClipOffset)
     COLOR_BY_DEF()
    ;
 
diff --git a/modules/gfx/src/gfx_object.cc b/modules/gfx/src/gfx_object.cc
index 71181316fedef1e2ded80931432cc7e4726e96e5..052f5c9f2d94298eb0b84e2367383ff9ece45aee 100644
--- a/modules/gfx/src/gfx_object.cc
+++ b/modules/gfx/src/gfx_object.cc
@@ -39,6 +39,10 @@
 #  include <ost/img/alg/stat.hh>
 #endif // OST_IMG_ENABLED
 
+#if OST_SHADER_SUPPORT_ENABLED
+#include "shader.hh"
+#endif
+
 namespace ost { namespace gfx {
 
 GfxObj::GfxObj(const String& name):
@@ -66,6 +70,9 @@ GfxObj::GfxObj(const String& name):
 #endif
   solid_(false),
   solid_color_(RGB(0.7,0.7,0.7)),
+  clip_flag_(false),
+  clip_plane_(),
+  clip_offset_(0.0),
   c_ops_(),
   labels_(),
   use_occlusion_(false)
@@ -102,6 +109,11 @@ void GfxObj::DeepSwap(GfxObj& go)
   std::swap(smoothf_,go.smoothf_);
   std::swap(outline_flag_,go.outline_flag_);
   std::swap(outline_mode_,go.outline_mode_);
+  std::swap(solid_,go.solid_);
+  std::swap(solid_color_,go.solid_color_);
+  std::swap(clip_flag_,go.clip_flag_);
+  std::swap(clip_plane_,go.clip_plane_);
+  std::swap(clip_offset_,go.clip_offset_);
   std::swap(c_ops_,go.c_ops_);
   std::swap(labels_,go.labels_);
   std::swap(use_occlusion_,go.use_occlusion_);
@@ -152,7 +164,27 @@ void GfxObj::RenderGL(RenderPass pass)
       only STANDARD_RENDER_PASS and GLOW_RENDER_PASS are
       passed down to the custom rendering routines
     */
-   
+  
+    if(clip_flag_) {
+      glEnable(GL_CLIP_DISTANCE0);
+#if OST_SHADER_SUPPORT_ENABLED
+      GLuint cp = Shader::Instance().GetCurrentProgram();
+      if(cp>0) {
+        glUniform1i(glGetUniformLocation(cp,"clip_flag"),1);
+        glUniform4f(glGetUniformLocation(cp,"clip_plane"),
+                   clip_plane_[0],clip_plane_[1],clip_plane_[2],clip_plane_[3]);
+      } else {
+        GLdouble eq[4];
+        for(size_t i=0;i<4;++i) eq[i]=clip_plane_[i];
+        glClipPlane(GL_CLIP_PLANE0,eq);
+      }
+#else
+      GLdouble eq[4];
+      for(size_t i=0;i<4;++i) eq[i]=clip_plane_[i];
+      glClipPlane(GL_CLIP_PLANE0,eq);
+#endif
+    }
+
     if(pass==DEPTH_RENDER_PASS) {
       render_depth_only();
     } else if(pass==TRANSPARENT_RENDER_PASS) {
@@ -181,6 +213,10 @@ void GfxObj::RenderGL(RenderPass pass)
       render_labels();
     }
 
+    if(clip_flag_) {
+      glDisable(GL_CLIP_DISTANCE0);
+    }
+
     glPopMatrix();    
   }
 }
@@ -393,6 +429,27 @@ void GfxObj::SetSolidColor(const Color& c)
   Scene::Instance().RequestRedraw();
 }
 
+void GfxObj::SetClip(bool f)
+{
+  clip_flag_=f;
+  // va_.SetClip(clip_flag_);
+  Scene::Instance().RequestRedraw();
+}
+
+void GfxObj::SetClipPlane(const geom::Vec4& p)
+{
+  clip_plane_=p;
+  // va_.SetSolidColor(solid_color_);
+  Scene::Instance().RequestRedraw();
+}
+
+void GfxObj::SetClipOffset(float f)
+{
+  clip_offset_=f;
+  va_.SetClipOffset(clip_offset_);
+  Scene::Instance().RequestRedraw();
+}
+
 void GfxObj::ColorBy(const mol::EntityView& ev, 
                       const String& prop,
                       const Gradient& g, float minv, float maxv)
diff --git a/modules/gfx/src/gfx_object.hh b/modules/gfx/src/gfx_object.hh
index 0b70065d7f820ca924ef07b3d2ad3005fe4e71b2..51806e3570e4b8de696df5eba939049bffa4c4dc 100644
--- a/modules/gfx/src/gfx_object.hh
+++ b/modules/gfx/src/gfx_object.hh
@@ -93,6 +93,13 @@ public:
   virtual void SetSolidColor(const Color& c);
   virtual Color GetSolidColor() const {return solid_color_;}
   
+  virtual void SetClip(bool f);
+  virtual bool GetClip() const {return clip_flag_;}
+  virtual void SetClipPlane(const geom::Vec4&);
+  virtual geom::Vec4 GetClipPlane() const {return clip_plane_;}
+  virtual void SetClipOffset(float f);
+  virtual float GetClipOffset() const {return clip_offset_;}
+
   virtual void ColorBy(const mol::EntityView& ev, 
                        const String& prop,
                        const Gradient& g, float minv, float maxv);
@@ -250,6 +257,10 @@ public:
   bool solid_;
   Color solid_color_;
 
+  bool clip_flag_;
+  geom::Vec4 clip_plane_;
+  float clip_offset_;
+
   boost::ptr_vector<gfx::ColorOp> c_ops_;
 
   TextPrimList labels_;
diff --git a/modules/gfx/src/gfx_object_base.hh b/modules/gfx/src/gfx_object_base.hh
index 448de0cf2687781045e7b59bc72b145be0ee1c2d..07e49a92eb4df39fa9359b3f09e37f4e3eb9ef40 100644
--- a/modules/gfx/src/gfx_object_base.hh
+++ b/modules/gfx/src/gfx_object_base.hh
@@ -121,6 +121,13 @@ class DLLEXPORT_OST_GFX GfxObjBase: public GfxNode
   virtual bool GetSolid() const = 0;
   virtual void SetSolidColor(const Color& c) = 0;
   virtual Color GetSolidColor() const = 0;
+
+  virtual void SetClip(bool f) = 0;
+  virtual bool GetClip() const = 0;
+  virtual void SetClipPlane(const geom::Vec4&) = 0;
+  virtual geom::Vec4 GetClipPlane() const = 0;
+  virtual void SetClipOffset(float f) = 0;
+  virtual float GetClipOffset() const = 0;
   
   /// \brief color each component based on the gradient-mapped property of 
   ///    the given entity
diff --git a/modules/gfx/src/shader/basic_fs.glsl b/modules/gfx/src/shader/basic_fs.glsl
index 9856cd3a47445b3ea94d57e9e00ea34c90ec2474..c0a9d6f084f88fc66f8844d8a595edcc5c4ea10b 100644
--- a/modules/gfx/src/shader/basic_fs.glsl
+++ b/modules/gfx/src/shader/basic_fs.glsl
@@ -1,7 +1,12 @@
 uniform bool fog_flag;
+uniform float clip_offset;
 
 void main()
 {
+  if(gl_FragCoord.z<clip_offset) {
+    discard;
+  }
+
   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;
diff --git a/modules/gfx/src/shader/dumpnorm_fs.glsl b/modules/gfx/src/shader/dumpnorm_fs.glsl
index 09bee99284fd774c4d5a010f10b31c603d104aa9..926622a7dc2085624f570c3388a55f9277a64a8d 100644
--- a/modules/gfx/src/shader/dumpnorm_fs.glsl
+++ b/modules/gfx/src/shader/dumpnorm_fs.glsl
@@ -1,5 +1,10 @@
+uniform float clip_offset;
+
 void main()
 {
+  if(gl_FragCoord.z<clip_offset) {
+    discard;
+  }
   gl_FragColor.rgb=normalize(gl_TexCoord[0]).stp*0.5+0.5;
 }
 
diff --git a/modules/gfx/src/shader/fraglight_fs.glsl b/modules/gfx/src/shader/fraglight_fs.glsl
index 9baa64b043a516b1293a66beaaf684e1627600b9..b8c7b6b21ded3428e6907d06d27b83d14c8f206b 100644
--- a/modules/gfx/src/shader/fraglight_fs.glsl
+++ b/modules/gfx/src/shader/fraglight_fs.glsl
@@ -5,9 +5,13 @@ uniform sampler2D depth_map;
 uniform int depth_mode;
 uniform bool tex_flag;
 uniform sampler2D tex_map;
+uniform float clip_offset;
 
 void main()
 {
+  if(gl_FragCoord.z<clip_offset) {
+    discard;
+  }
   vec4 color = gl_Color;
 
   if(tex_flag) {
diff --git a/modules/gfx/src/shader/fraglight_vs.glsl b/modules/gfx/src/shader/fraglight_vs.glsl
index 8a7ca2a3bc6e7fbac32e8420f867f5a833a876bc..18472b2c150c6297ddb5d606437d0dfa1fa6e84d 100644
--- a/modules/gfx/src/shader/fraglight_vs.glsl
+++ b/modules/gfx/src/shader/fraglight_vs.glsl
@@ -1,3 +1,6 @@
+uniform vec4 clip_plane;
+uniform bool clip_flag;
+
 void main()
 {
   // transformed position
@@ -21,5 +24,8 @@ void main()
 
   gl_FrontColor=gl_Color;
   gl_BackColor=gl_Color;
+  if(clip_flag) {
+    gl_ClipDistance[0] = dot(ec_Pos, clip_plane);
+  }
 }
 
diff --git a/modules/gfx/src/vertex_array.cc b/modules/gfx/src/vertex_array.cc
index 155417b65e2cb2080bd6a5230ee30b936c3f5134..d52506f49501760f2f151b7b9b0eea971a4fb70e 100644
--- a/modules/gfx/src/vertex_array.cc
+++ b/modules/gfx/src/vertex_array.cc
@@ -431,7 +431,9 @@ void IndexedVertexArray::RenderGL()
   
   glPushAttrib(GL_ALL_ATTRIB_BITS);
   glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
-  
+
+  set_clip_offset(clip_offset_);
+
   if(use_tex_) {
     glEnable(GL_TEXTURE_2D);
   } else {
@@ -493,7 +495,7 @@ void IndexedVertexArray::RenderGL()
     } else {
       glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
     }
-    if(cull_face_ && !solid_) {
+    if(cull_face_ && !solid_ && clip_offset_<=0.0) {
       glEnable(GL_CULL_FACE);
     } else { 
       glDisable(GL_CULL_FACE); 
@@ -537,6 +539,7 @@ void IndexedVertexArray::RenderGL()
       glUniform4f(glGetUniformLocation(Shader::Instance().GetCurrentProgram(),"color"),
                   outline_exp_color_[0],outline_exp_color_[1],
                   outline_exp_color_[2],opacity_);
+      set_clip_offset(clip_offset_);
       glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
       draw_ltq(use_buff);
 
@@ -700,6 +703,7 @@ void IndexedVertexArray::Reset()
   outline_exp_color_=Color(0,0,0);
   solid_=false;
   solid_color_=RGB(1,1,1);
+  clip_offset_=0.0;
   draw_normals_=false;
   use_tex_=false;
 }
@@ -1098,6 +1102,7 @@ void IndexedVertexArray::copy(const IndexedVertexArray& va)
   outline_exp_color_=va.outline_exp_color_;
   solid_=va.solid_;
   solid_color_=va.solid_color_;
+  clip_offset_=va.clip_offset_;
   draw_normals_=va.draw_normals_;
   use_tex_=va.use_tex_;
 }
@@ -1253,10 +1258,12 @@ void IndexedVertexArray::draw_ltq(bool use_buff)
     float aspect=Scene::Instance().GetAspect();
     float rh=2.0*fabs(tan(fov)*znear);
     float rw=rh*aspect;
-    float rz=-znear-0.1;
+    float rz=-(znear+clip_offset_)-0.05;
 
     glDisable(GL_LIGHTING);
-  
+
+    set_clip_offset(0.0);
+
     glBegin(GL_TRIANGLE_STRIP);
     glColor3fv(solid_color_);
     glNormal3f(0,0,1);
@@ -1265,6 +1272,9 @@ void IndexedVertexArray::draw_ltq(bool use_buff)
     glVertex3f(-rw,rh,rz);
     glVertex3f(rw,rh,rz);
     glEnd();
+
+    set_clip_offset(clip_offset_);
+
     glDisable(GL_STENCIL_TEST);
     glPopMatrix();
   }
@@ -1486,4 +1496,16 @@ geom::AlignedCuboid IndexedVertexArray::GetBoundingBox() const
   }
 }
 
+void IndexedVertexArray::set_clip_offset(float o)
+{
+#if OST_SHADER_SUPPORT_ENABLED
+  float n=Scene::Instance().GetNear();
+  float f=Scene::Instance().GetFar();
+  float z=n+o;
+  float t=(f*(-n+o)+n*(n+o))/((f-n)*(n+o));
+  t=(t+1.0)*0.5;
+  glUniform1f(glGetUniformLocation(Shader::Instance().GetCurrentProgram(),"clip_offset"),t);
+#endif
+}
+
 }} // ns
diff --git a/modules/gfx/src/vertex_array.hh b/modules/gfx/src/vertex_array.hh
index 539d871b775c6219a397c0ca4795a23baa8c402b..f0380b671d7552eacdb943381d3985aaf77e2c1f 100644
--- a/modules/gfx/src/vertex_array.hh
+++ b/modules/gfx/src/vertex_array.hh
@@ -121,6 +121,8 @@ class DLLEXPORT_OST_GFX IndexedVertexArray {
   bool GetSolid() const {return solid_;}
   void SetSolidColor(const Color& c) {solid_color_=c;}
   bool GetSolidcolor() const {return solid_color_;}
+  void SetClipOffset(float f) {clip_offset_=f;}
+  float GetClipOffset() const {return clip_offset_;}
 
   // vertex, normal, color and texcoord (T2F_C4F_N3F_V3F)
   VertexID Add(const geom::Vec3& vert, const geom::Vec3& norm, const Color& col, const geom::Vec2& tex=geom::Vec2());
@@ -240,6 +242,7 @@ class DLLEXPORT_OST_GFX IndexedVertexArray {
   Color outline_exp_color_;
   bool solid_;
   Color solid_color_;
+  float clip_offset_;
   bool draw_normals_;
 
   bool use_tex_;
@@ -253,6 +256,7 @@ class DLLEXPORT_OST_GFX IndexedVertexArray {
   void draw_p(bool use_buff);
   void draw_aalines();
   void draw_line_halo(bool use_buff);
+  void set_clip_offset(float);
 };
 
 }} // ns