diff --git a/apps/tutorials/pe/02_ConfinedGasExtended.cfg b/apps/tutorials/pe/02_ConfinedGasExtended.cfg
index 1e1b9eb004a06fb94697ee26020344eeed99cf0a..f06e81138cd2e4f879e6d1f04d6267e279ea4598 100644
--- a/apps/tutorials/pe/02_ConfinedGasExtended.cfg
+++ b/apps/tutorials/pe/02_ConfinedGasExtended.cfg
@@ -21,6 +21,7 @@ Raytracing
    upVector < 0, 0, 1 >;
    antiAliasFactor 2;
    reductionMethod MPI_REDUCE;
+   backgroundColor < 0.18, 0.18, 0.18 >;
    Lighting {
       pointLightOrigin < -10, 10, 15 >;
       ambientColor < 0.3, 0.3, 0.3 >;
diff --git a/src/pe/ccd/HashGrids.cpp b/src/pe/ccd/HashGrids.cpp
index 8b7b001c7887d601ae6bab15cd00595bfc4a3cce..f2bdc9c83b03cb5c65daf68e062b1e02098883f4 100644
--- a/src/pe/ccd/HashGrids.cpp
+++ b/src/pe/ccd/HashGrids.cpp
@@ -1179,8 +1179,6 @@ bool HashGrids::powerOfTwo( size_t number )
 }
 //*************************************************************************************************
 
-
-uint64_t HashGrids::intersectionTestCount = 0; //ToDo remove again
    
 //=================================================================================================
 //
diff --git a/src/pe/ccd/HashGrids.h b/src/pe/ccd/HashGrids.h
index f5697eac1f294f1922ddbd6763ae68968f468547..c6146810b9f60f719f5407430ecf50ee9d16eb50 100644
--- a/src/pe/ccd/HashGrids.h
+++ b/src/pe/ccd/HashGrids.h
@@ -99,9 +99,7 @@ public:
    static const size_t gridActivationThreshold;
    static const real_t hierarchyFactor;
    //**********************************************************************************************
-   
-   static uint64_t intersectionTestCount; // ToDo remove again
-   
+      
 private:
    //**Type definitions****************************************************************************
    //! Vector for storing (handles to) rigid bodies.
@@ -583,7 +581,6 @@ BodyID HashGrids::HashGrid::getBodyIntersectionForBlockCell(const Vector3<int32_
                continue;
             }
                
-            HashGrids::intersectionTestCount++;
             bool intersects = SingleCast<BodyTuple, raytracing::IntersectsFunctor, bool>::execute(cellBody, intersectsFunc);
             if (intersects && t_local < t_closest) {
                body = cellBody;
diff --git a/src/pe/raytracing/Raytracer.cpp b/src/pe/raytracing/Raytracer.cpp
index a464408bbec02cede0906077b5887f5bbf5ba3af..5bb4c22a925fe719d78a9c5aed70a9e6c421e904 100644
--- a/src/pe/raytracing/Raytracer.cpp
+++ b/src/pe/raytracing/Raytracer.cpp
@@ -141,14 +141,6 @@ Raytracer::Raytracer(const shared_ptr<BlockStorage> forest, const BlockDataID st
    fov_vertical_ = config.getParameter<real_t>("fov_vertical");
    antiAliasFactor_ = config.getParameter<uint16_t>("antiAliasFactor", 1);
    
-   if (config.isDefined("tbuffer_output_directory")) {
-      setTBufferOutputEnabled(true);
-      setTBufferOutputDirectory(config.getParameter<std::string>("tbuffer_output_directory", "."));
-      WALBERLA_LOG_INFO_ON_ROOT("t buffers will be written to " << getTBufferOutputDirectory() << ".");
-   } else {
-      setTBufferOutputEnabled(false);
-   }
-   
    setLocalImageOutputEnabled(config.getParameter<bool>("local_image_output_enabled", false));
       
    if (config.isDefined("image_output_directory")) {
@@ -278,68 +270,6 @@ std::string Raytracer::getOutputFilename(const std::string& base, size_t timeste
    return fileNameStream.str();
 }
 
-/*!\brief Writes the depth values of the intersections buffer to an image file in the tBuffer output directory.
- * \param intersectionsBuffer Buffer with intersection info for each pixel.
- * \param timestep Timestep this image is from.
- * \param isGlobalImage Whether this image is the fully stitched together one.
- */
-void Raytracer::writeDepthsToFile(const std::vector<BodyIntersectionInfo>& intersectionsBuffer,
-                                   size_t timestep, bool isGlobalImage) const {
-   writeDepthsToFile(intersectionsBuffer, getOutputFilename("tbuffer", timestep, isGlobalImage));
-}
-
-/*!\brief Writes the depth values of the intersections buffer to an image file in the tBuffer output directory.
- * \param intersectionsBuffer Buffer with intersection info for each pixel.
- * \param fileName Name of the output file.
- */
-void Raytracer::writeDepthsToFile(const std::vector<BodyIntersectionInfo>& intersectionsBuffer,
-                                  const std::string& fileName) const {
-   real_t inf = std::numeric_limits<real_t>::max();
-   
-   real_t t_max = 1;
-   real_t t_min = inf;
-   for (size_t x = 0; x < pixelsHorizontal_; x++) {
-      for (size_t y = 0; y < pixelsVertical_; y++) {
-         size_t i = coordinateToArrayIndex(x, y);
-         real_t t = real_c(intersectionsBuffer[i].t);
-         if (t < t_min) {
-            t_min = t;
-         }
-      }
-   }
-   if (realIsIdentical(t_min, inf)) t_min = 0;
-   
-   t_max = forest_->getDomain().maxDistance(cameraPosition_);
-   
-   filesystem::path dir (getTBufferOutputDirectory());
-   filesystem::path file (fileName);
-   filesystem::path fullPath = dir / file;
-   
-   std::vector<u_char> lodeTBuffer(pixelsHorizontal_*pixelsVertical_);
-   
-   uint32_t l = 0;
-   for (size_t y = pixelsVertical_-1; y > 0; y--) {
-      for (size_t x = 0; x < pixelsHorizontal_; x++) {
-         size_t i = coordinateToArrayIndex(x, y);
-         u_char g = 0;
-         real_t t = real_c(intersectionsBuffer[i].t);
-         if (realIsIdentical(t, inf)) {
-            g = (u_char)0;
-         } else {
-            real_t t_scaled = (1-(t-t_min)/(t_max-t_min));
-            g = (u_char)(255 * std::max(std::min(t_scaled, real_t(1)), real_t(0)));
-         }
-         lodeTBuffer[l] = g;
-         l++;
-      }
-   }
-   
-   uint32_t error = lodepng::encode(fullPath.string(), lodeTBuffer, getPixelsHorizontal(), getPixelsVertical(), LCT_GREY);
-   if(error) {
-      WALBERLA_LOG_WARNING("lodePNG error " << error << " when trying to save tbuffer file to " << fullPath.string() << ": " << lodepng_error_text(error));
-   }
-}
-
 /*!\brief Writes the image of the current intersection buffer to a file in the image output directory.
  * \param intersectionsBuffer Buffer with intersection info for each pixel.
  * \param timestep Timestep this image is from.
@@ -481,12 +411,6 @@ void Raytracer::localOutput(const std::vector<BodyIntersectionInfo>& intersectio
          if (tt != NULL) tt->stop("Local Output");
       }
    }
-   
-   if (getTBufferOutputEnabled()) {
-      if (tt != NULL) tt->start("Local Output");
-      writeDepthsToFile(intersectionsBuffer, timestep);
-      if (tt != NULL) tt->stop("Local Output");
-   }
 }
 
 void Raytracer::output(const std::vector<BodyIntersectionInfo>& intersectionsBuffer, size_t timestep, WcTimingTree* tt) {
@@ -495,15 +419,10 @@ void Raytracer::output(const std::vector<BodyIntersectionInfo>& intersectionsBuf
       if (getImageOutputEnabled()) {
          writeImageToFile(intersectionsBuffer, timestep, true);
       }
-      if (getTBufferOutputEnabled()) {
-         writeDepthsToFile(intersectionsBuffer, timestep, true);
-      }
       if (tt != NULL) tt->stop("Output");
    }
 }
 
-uint64_t Raytracer::naiveIntersectionTestCount = 0;
-
 }
 }
 }
diff --git a/src/pe/raytracing/Raytracer.h b/src/pe/raytracing/Raytracer.h
index f3579d725f61ac2b75a4e1cbd50fb18d5e88bb62..b2b57b9c67fe8385903f7f9fc7282715cb5e25ce 100644
--- a/src/pe/raytracing/Raytracer.h
+++ b/src/pe/raytracing/Raytracer.h
@@ -138,8 +138,6 @@ private:
                                                            * a given body should be visible in the final image. */
    Algorithm raytracingAlgorithm_;  //!< Algorithm to use while intersection testing.
    ReductionMethod reductionMethod_; //!< Reduction method used for assembling the image from all processes.
-   
-   static uint64_t naiveIntersectionTestCount;
    //@}
    
    /*!\name Member variables for raytracing geometry */
@@ -169,8 +167,6 @@ public:
    inline const Vec3& getLookAtPoint() const;
    inline const Vec3& getUpVector() const;
    inline const Color& getBackgroundColor() const;
-   inline bool getTBufferOutputEnabled() const;
-   inline const std::string& getTBufferOutputDirectory() const;
    inline bool getImageOutputEnabled() const;
    inline bool getLocalImageOutputEnabled() const;
    inline const std::string& getImageOutputDirectory() const;
@@ -181,8 +177,6 @@ public:
    /*!\name Set functions */
    //@{
    inline void setBackgroundColor(const Color& color);
-   inline void setTBufferOutputEnabled(const bool enabled);
-   inline void setTBufferOutputDirectory(const std::string& path);
    inline void setImageOutputEnabled(const bool enabled);
    inline void setLocalImageOutputEnabled(const bool enabled);
    inline void setImageOutputDirectory(const std::string& path);
@@ -208,10 +202,6 @@ private:
                WcTimingTree* tt = NULL);
 
    std::string getOutputFilename(const std::string& base, size_t timestep, bool isGlobalImage) const;
-   void writeDepthsToFile(const std::vector<BodyIntersectionInfo>& intersectionsBuffer,
-                          size_t timestep, bool isGlobalImage = false) const;
-   void writeDepthsToFile(const std::vector<BodyIntersectionInfo>& intersectionsBuffer,
-                          const std::string& fileName) const;
    void writeImageToFile(const std::vector<BodyIntersectionInfo>& intersectionsBuffer,
                          size_t timestep, bool isGlobalImage = false) const;
    void writeImageToFile(const std::vector<BodyIntersectionInfo>& intersectionsBuffer,
@@ -300,22 +290,6 @@ inline const Color& Raytracer::getBackgroundColor() const {
    return backgroundColor_;
 }
 
-/*!\brief Returns true if tbuffer output to a file is enabled.
- *
- * \return True if tbuffer output enabled, otherwise false.
- */
-inline bool Raytracer::getTBufferOutputEnabled() const {
-   return tBufferOutputEnabled_;
-}
-
-/*!\brief Returns the directory where the tbuffer output file will be saved in.
- *
- * \return Path to the tbuffer output directory.
- */
-inline const std::string& Raytracer::getTBufferOutputDirectory() const {
-   return tBufferOutputDirectory_;
-}
-   
 /*!\brief Returns true if image output to a file is enabled.
  *
  * \return True if image output enabled, otherwise false.
@@ -362,23 +336,6 @@ inline void Raytracer::setBackgroundColor(const Color& color) {
    backgroundColor_ = color;
 }
    
-/*!\brief Enable / disable outputting the tBuffer to a file in the specified directory.
- * \param enabled Set to true / false to enable / disable tbuffer output.
- */
-inline void Raytracer::setTBufferOutputEnabled(const bool enabled) {
-   tBufferOutputEnabled_ = enabled;
-}
-
-/*!\brief Enable / disable outputting the tBuffer to a file in the specified directory.
- * \param enabled Set to true / false to enable / disable tbuffer output.
- */
-inline void Raytracer::setTBufferOutputDirectory(const std::string& path) {
-   filesystem::path dir (path);
-   WALBERLA_CHECK(filesystem::exists(dir) && filesystem::is_directory(dir), "Tbuffer output directory " << path << " is invalid.");
-   
-   tBufferOutputDirectory_ = path;
-}
-   
 /*!\brief Enable / disable outputting images in the specified directory.
  * \param enabled Set to true / false to enable / disable image output.
  */
@@ -515,8 +472,6 @@ inline void Raytracer::traceRayNaively(const Ray& ray, BodyID& body_closest, rea
          }
          
          bool intersects = SingleCast<BodyTypeTuple, IntersectsFunctor, bool>::execute(*bodyIt, func);
-         Raytracer::naiveIntersectionTestCount++;
-         
          if (intersects && t < t_closest) {
             // body was shot by ray and is currently closest to camera
             t_closest = t;
@@ -577,12 +532,8 @@ void Raytracer::generateImage(const size_t timestep, WcTimingTree* tt) {
          hashgrids->update();
       }
       if (tt != NULL) tt->stop("HashGrids Update");
-      
-      ccd::HashGrids::intersectionTestCount = 0;
    }
    
-   Raytracer::naiveIntersectionTestCount = 0;
-   
    real_t t, t_closest;
    Vec3 n;
    Vec3 n_closest;
@@ -625,6 +576,10 @@ void Raytracer::generateImage(const size_t timestep, WcTimingTree* tt) {
          
          traceRayInGlobalBodyStorage<BodyTypeTuple>(ray, body_closest, t_closest, n_closest);
          
+         BodyIntersectionInfo& intersectionInfo = intersectionsBuffer[coordinateToArrayIndex(x, y)];
+         intersectionInfo.imageX = uint32_t(x);
+         intersectionInfo.imageY = uint32_t(y);
+         
          if (!realIsIdentical(t_closest, inf) && body_closest != NULL) {
             Color color = getColor(body_closest, ray, t_closest, n_closest);
             if (isErrorneousPixel) {
@@ -632,37 +587,24 @@ void Raytracer::generateImage(const size_t timestep, WcTimingTree* tt) {
                isErrorneousPixel = false;
             }
             
-            BodyIntersectionInfo intersectionInfo = {
-               uint32_t(x),
-               uint32_t(y),
-               body_closest->getSystemID(),
-               t_closest,
-               color[0],
-               color[1],
-               color[2]
-            };
+            intersectionInfo.bodySystemID = body_closest->getSystemID();
+            intersectionInfo.t = t_closest;
+            intersectionInfo.r = color[0];
+            intersectionInfo.g = color[1];
+            intersectionInfo.b = color[2];
             
-            intersectionsBuffer[coordinateToArrayIndex(x, y)] = intersectionInfo;
             intersections.push_back(intersectionInfo);
+         } else {
+            intersectionInfo.bodySystemID = 0;
+            intersectionInfo.t = inf;
+            intersectionInfo.r = backgroundColor_[0];
+            intersectionInfo.g = backgroundColor_[1];
+            intersectionInfo.b = backgroundColor_[2];
          }
       }
    }
    if (tt != NULL) tt->stop("Intersection Testing");
 
-   if (raytracingAlgorithm_ == RAYTRACE_COMPARE_BOTH || raytracingAlgorithm_ == RAYTRACE_COMPARE_BOTH_STRICTLY) {
-      uint64_t naiveTests = Raytracer::naiveIntersectionTestCount;
-      uint64_t hashgridsTests = ccd::HashGrids::intersectionTestCount;
-      mpi::reduceInplace(naiveTests, mpi::SUM, 0);
-      mpi::reduceInplace(hashgridsTests, mpi::SUM, 0);
-      WALBERLA_ROOT_SECTION() {
-         uint64_t savedIntersections = naiveTests-hashgridsTests;
-         real_t savedIntersectionsPercentage = (real_t(1)-real_c(hashgridsTests)/real_c(naiveTests))*100;
-         WALBERLA_LOG_INFO("Intersection statistics (processes: " << mpi::MPIManager::instance()->numProcesses() << "):");
-         WALBERLA_LOG_INFO(" Naive tests:     " << std::setw(10) << naiveTests);
-         WALBERLA_LOG_INFO(" HashGrids tests: " << std::setw(10) << hashgridsTests);
-         WALBERLA_LOG_INFO(" Saved tests:     " << std::setw(10) << savedIntersections << " (" << std::setprecision(4) << savedIntersectionsPercentage << "%)");
-      }
-   }
    if (raytracingAlgorithm_ == RAYTRACE_COMPARE_BOTH || raytracingAlgorithm_ == RAYTRACE_COMPARE_BOTH_STRICTLY) {
       if (pixelErrors > 0) {
          WALBERLA_LOG_WARNING(pixelErrors << " pixel errors found!");