diff --git a/modules/gfx/pymod/export_scene.cc b/modules/gfx/pymod/export_scene.cc
index 9f3042cb2d7328097691db1d338744d680d0946c..5a8a5929d29a788468f907ba90534f7f79aeac10 100644
--- a/modules/gfx/pymod/export_scene.cc
+++ b/modules/gfx/pymod/export_scene.cc
@@ -83,13 +83,14 @@ void export_Scene()
   void (Scene::* set_light_prop2)(float,float,float) = &Scene::SetLightProp;
 
   void (Scene::* export1)(const String&, uint, uint, bool) = &Scene::Export;
-  void (Scene::* export2)(const String&, bool) = &Scene::Export;
-  void (Scene::* export3)(Exporter*) const = &Scene::Export;
+  void (Scene::* export2)(const String&, uint, uint, int, bool) = &Scene::Export;
+  void (Scene::* export3)(const String&, bool) = &Scene::Export;
+  void (Scene::* export4)(Exporter*) const = &Scene::Export;
   void (Scene::*remove1)(const GfxNodeP&) = &Scene::Remove;
   void (Scene::*remove2)(const String&) = &Scene::Remove;
   void (Scene::*center_on1)(const String&) = &Scene::CenterOn;
   void (Scene::*center_on2)(const GfxObjP&) = &Scene::CenterOn;
-  
+  bool (Scene::*start_offscreen_mode2)(unsigned int, unsigned int, int) = &Scene::StartOffscreenMode;  
   class_<Viewport>("Viewport", init<>())
     .def_readwrite("x", &Viewport::x)
     .def_readwrite("y", &Viewport::y)
@@ -197,7 +198,8 @@ void export_Scene()
     .def("Apply", apply)
     .def("Export",export1, arg("transparent")=false)
     .def("Export",export2, arg("transparent")=false)
-    .def("Export",export3)
+    .def("Export",export3, arg("transparent")=false)
+    .def("Export",export4)
     .def("ExportPov",&Scene::ExportPov,
          scene_export_pov_overloads())
     .def("PushView",&Scene::PushView)
@@ -227,7 +229,7 @@ void export_Scene()
     .add_property("ao_quality",&Scene::GetAmbientOcclusionQuality,&Scene::SetAmbientOcclusionQuality)
     .add_property("ao_size",&Scene::GetAmbientOcclusionSize,&Scene::SetAmbientOcclusionSize)
     .def("AttachObserver",&Scene::AttachObserver)
-    .def("StartOffscreenMode",&Scene::StartOffscreenMode)
+    .def("StartOffscreenMode",start_offscreen_mode2)
     .def("StopOffscreenMode",&Scene::StopOffscreenMode)
     .def("SetShadingMode",&Scene::SetShadingMode)
     .def("SetBeacon",&Scene::SetBeacon)
diff --git a/modules/gfx/src/entity.cc b/modules/gfx/src/entity.cc
index df1ad6bfc08fc8b9b7d421653eca750d7f0469cd..87754017859d3ffea6f55642ecad4673a3f885b2 100644
--- a/modules/gfx/src/entity.cc
+++ b/modules/gfx/src/entity.cc
@@ -376,8 +376,9 @@ void Entity::CustomRenderPov(PovState& pov)
 
 void Entity::Export(Exporter* ex)
 {
+  if(!IsVisible()) return;
+
   ex->NodeStart(GetName(),Exporter::OBJ);
-  // in the simplest case, just export va
   if(rebuild_ || refresh_) {
     PreRenderGL(true);
   }
diff --git a/modules/gfx/src/gfx_node.cc b/modules/gfx/src/gfx_node.cc
index 813ce6f413e677e8b884ae191f4b3a608b27a47c..59b44d162d991620c77bd58ad300f49f5d3fc8de 100644
--- a/modules/gfx/src/gfx_node.cc
+++ b/modules/gfx/src/gfx_node.cc
@@ -108,7 +108,9 @@ void GfxNode::Export(Exporter* ex)
   if(!IsVisible()) return;
   ex->NodeStart(GetName(),Exporter::GROUP);
   for(GfxNodeVector::iterator it=node_vector_.begin();it!=node_vector_.end();++it) {
-    (*it)->Export(ex);
+    if((*it)->IsVisible()) {
+      (*it)->Export(ex);
+    }
   }
   ex->NodeEnd(GetName());
 }
diff --git a/modules/gfx/src/impl/glx_offscreen_buffer.cc b/modules/gfx/src/impl/glx_offscreen_buffer.cc
index 10fcb12af2a6c19c9e802c798c28e7c4b39b00ca..6b934d1155ce89a69e88bc7b66dfdf0b7e0cea6b 100644
--- a/modules/gfx/src/impl/glx_offscreen_buffer.cc
+++ b/modules/gfx/src/impl/glx_offscreen_buffer.cc
@@ -21,6 +21,8 @@
   Author: Ansgar Philippsen
 */
 
+#include <iomanip>
+
 #include <ost/log.hh>
 #include <ost/gfx/offscreen_buffer.hh>
 #include <ost/gfx/scene.hh>
@@ -63,40 +65,57 @@ OffscreenBuffer::OffscreenBuffer(unsigned int width, unsigned int height, const
   attrib_list.push_back(GLX_STENCIL_SIZE);
   attrib_list.push_back(8);
   attrib_list.push_back(GLX_SAMPLE_BUFFERS);
-  attrib_list.push_back(1);
+  attrib_list.push_back(f.multisample ? 1 : 0);
   attrib_list.push_back(0);
-
+  bool search_multisample=f.multisample;
   int nelem=0;
   LOG_DEBUG("offscreen buffer: glXChooseFBConfig");
   fbconfig_ =glXChooseFBConfig(dpy_,0,&attrib_list[0],&nelem);
   if(fbconfig_==0 || nelem==0) {
-    LOG_DEBUG("no offscreen rendering context with multisample, trying without");
-    // take out the multisample requirement
-    attrib_list[attrib_list.size()-2]=0;
-    fbconfig_ =glXChooseFBConfig(dpy_,0,&attrib_list[0],&nelem);
-    if(fbconfig_==0 || nelem==0) {
+    if(f.multisample) {
+      LOG_DEBUG("no offscreen rendering context with multisample, trying without");
+      // take out the multisample requirement
+      attrib_list[attrib_list.size()-2]=0;
+      fbconfig_ =glXChooseFBConfig(dpy_,0,&attrib_list[0],&nelem);
+      if(fbconfig_==0 || nelem==0) {
+        LOG_ERROR("error creating offscreen rendering context: glXChooseFBConfig failed");
+        return;
+      }
+      search_multisample=false;
+    } else {
       LOG_ERROR("error creating offscreen rendering context: glXChooseFBConfig failed");
+      XCloseDisplay(dpy_);
       return;
     }
   }
-#if 0
-  /*
-   let export routine and start offscreen rendering context ask for min/max/next available
-   multisample
-   */
-  for(size_t i=0;i<nelem;++i) {
-    std::cerr << i << " ";
+#ifndef NDEBUG
+  LOG_VERBOSE("offscreen buffer: available framebuffer configs");
+  for(int i=0;i<nelem;++i) {
     int rbits; glXGetFBConfigAttrib(dpy_,fbconfig_[i], GLX_RED_SIZE, &rbits);
     int gbits; glXGetFBConfigAttrib(dpy_,fbconfig_[i], GLX_GREEN_SIZE, &gbits);
     int bbits; glXGetFBConfigAttrib(dpy_,fbconfig_[i], GLX_BLUE_SIZE, &bbits);
     int dbits; glXGetFBConfigAttrib(dpy_,fbconfig_[i], GLX_DEPTH_SIZE, &dbits);
     int sbits; glXGetFBConfigAttrib(dpy_,fbconfig_[i], GLX_STENCIL_SIZE, &sbits);
     int ms; glXGetFBConfigAttrib(dpy_,fbconfig_[i], GLX_SAMPLES, &ms);
-    std::cerr << "rgb=" << rbits << "." << gbits << "." << bbits << " d=" << dbits << " s=" << sbits << " ms=" << ms << std::endl;
+    LOG_VERBOSE(" " << std::setw(3) << i << std::setw(0) << ": rgb=" << rbits << "." << gbits << "." << bbits << " d=" << dbits << " s=" << sbits << " ms=" << ms);
   }
-  fb_config_id_=nelem-1;
 #endif
   fb_config_id_=0;
+  if(search_multisample) {
+    int ms;
+    int best_ms;
+    glXGetFBConfigAttrib(dpy_,fbconfig_[0], GLX_SAMPLES, &best_ms);
+    for(int i=1;i<nelem;++i) {
+      glXGetFBConfigAttrib(dpy_,fbconfig_[i], GLX_SAMPLES, &ms);
+      if(ms<=static_cast<int>(f.samples) && ms>best_ms) {
+        fb_config_id_=i;
+        best_ms=ms;
+      }
+    }
+  }
+#ifndef NDEBUG
+  LOG_VERBOSE("offscreen buffer: using buffer # " << fb_config_id_ << " for export");
+#endif
 
   attrib_list.clear();
   attrib_list.push_back(GLX_PBUFFER_WIDTH);
@@ -109,6 +128,8 @@ OffscreenBuffer::OffscreenBuffer(unsigned int width, unsigned int height, const
   pbuffer_ = glXCreatePbuffer(dpy_, fbconfig_[fb_config_id_], &attrib_list[0]);
   if(!pbuffer_) {
     LOG_ERROR("error creating offscreen rendering context: glXCreatePBuffer failed");
+    XFree(fbconfig_);
+    XCloseDisplay(dpy_);
     return;
   }
 
@@ -126,6 +147,8 @@ OffscreenBuffer::OffscreenBuffer(unsigned int width, unsigned int height, const
   if(!context_) {
     LOG_ERROR("error creating offscreen rendering context: glXCreateNewContext failed");
     glXDestroyPbuffer(dpy_, pbuffer_);
+    XFree(fbconfig_);
+    XCloseDisplay(dpy_);
     return;
   }
 
@@ -139,6 +162,10 @@ OffscreenBuffer::~OffscreenBuffer()
     glXDestroyContext(dpy_, context_);
     LOG_DEBUG("offscreen buffer: glXDestroyPbuffer()");
     glXDestroyPbuffer(dpy_, pbuffer_);
+    LOG_DEBUG("offscreen buffer: XFree(fbconfig_list)");
+    XFree(fbconfig_);
+    LOG_DEBUG("offscreen buffer: XCloseDisplay()");
+    XCloseDisplay(dpy_);
   }
 }
 
diff --git a/modules/gfx/src/scene.cc b/modules/gfx/src/scene.cc
index e4d37b841160760a1c130f832f0b9828abc03daa..724482a79e1d6e0df4e9333abbc1441f93570020 100644
--- a/modules/gfx/src/scene.cc
+++ b/modules/gfx/src/scene.cc
@@ -1584,11 +1584,18 @@ uint Scene::GetSelectionMode() const
   return selection_mode_;
 }
 
-bool Scene::StartOffscreenMode(unsigned int width, unsigned int height)
+bool Scene::StartOffscreenMode(unsigned int width, unsigned int height, int max_samples)
 {
   LOG_DEBUG("Scene: starting offscreen rendering mode " << width << "x" << height);
   if(main_offscreen_buffer_) return false;
-  main_offscreen_buffer_ = new OffscreenBuffer(width,height,OffscreenBufferFormat(),true);
+  OffscreenBufferFormat obf;
+  if(max_samples>0) {
+    obf.multisample=true;
+    obf.samples=max_samples;
+  } else {
+    obf.multisample=false;
+  }
+  main_offscreen_buffer_ = new OffscreenBuffer(width,height,obf,true);
 
   if(!main_offscreen_buffer_->IsValid()) {
     LOG_ERROR("Scene: error during offscreen buffer creation");
@@ -1642,6 +1649,12 @@ void Scene::StopOffscreenMode()
 
 void Scene::Export(const String& fname, unsigned int width,
                    unsigned int height, bool transparent)
+{
+  Export(fname,width,height,0,transparent);
+}
+
+void Scene::Export(const String& fname, unsigned int width,
+                   unsigned int height, int max_samples, bool transparent)
 {
   int d_index=fname.rfind('.');
   if (d_index==-1) {
@@ -1658,7 +1671,14 @@ void Scene::Export(const String& fname, unsigned int width,
 
   // only switch if offscreen mode is not active
   if(of_flag) {
-    if(!StartOffscreenMode(width,height)) {
+    if(max_samples<0) {
+      int msamples=0;
+      if(OST_GL_VERSION_2_0) {
+        glGetIntegerv(GL_SAMPLES, &msamples);
+      }
+      max_samples=msamples;
+    }
+    if(!StartOffscreenMode(width,height, max_samples)) {
       return;
     }
   }
diff --git a/modules/gfx/src/scene.hh b/modules/gfx/src/scene.hh
index a8a9afbe1a8170083358694a2be1b06da7724936..477b160ca58b0b97c266f4fa25b132921ecdc5e2 100644
--- a/modules/gfx/src/scene.hh
+++ b/modules/gfx/src/scene.hh
@@ -294,6 +294,10 @@ class DLLEXPORT_OST_GFX Scene {
   /// dimensions here are ignored
   void Export(const String& fname, unsigned int w,
               unsigned int h, bool transparent=false);
+  /// \brief export into bitmap, using multisample anti-aliasing
+  /// \ref Scene::StartOfffscreenMode(unsigned int, unsigned int, int) for more detail
+  void Export(const String& fname, unsigned int w,
+              unsigned int h, int max_samples, bool transparent=false);
 
   /// \brief export snapshot of current scene
   void Export(const String& fname, bool transparent=false);
@@ -465,9 +469,16 @@ class DLLEXPORT_OST_GFX Scene {
     During batch mode, this is the only way to get meaningful
     functionality with the gfx module
 
-    returns true upon success and false upon failure
+    Returns true upon success and false upon failure
+
+    You can ask for multisampling to be enabled by giving the
+    max_samples a value larger than zero; in this case, the framebuffer
+    with at most this many samplebuffers will be used. The recommended
+    value here is 4; going to 8 or 16 may give you higher export times
+    with usually no marked increase in quality.
+
   */
-  bool StartOffscreenMode(unsigned int w, unsigned int h);
+  bool StartOffscreenMode(unsigned int w, unsigned int h, int max_samples);
   /// \brief stops offline rendering in interactive mode
   void StopOffscreenMode();