diff --git a/src/pe/raytracing/Intersects.h b/src/pe/raytracing/Intersects.h
index ae045d6d3fc20e91ab4e0f1a91d8137f0aba38a0..d8ffff061bc7a9d02ea9a506c01a799c96e65685 100644
--- a/src/pe/raytracing/Intersects.h
+++ b/src/pe/raytracing/Intersects.h
@@ -28,34 +28,39 @@
 #include "pe/rigidbody/Sphere.h"
 #include "pe/rigidbody/Union.h"
 #include "pe/utility/BodyCast.h"
+#include <boost/math/special_functions/sign.hpp>
+#include <boost/tuple/tuple.hpp>
 
 #include <pe/raytracing/Ray.h>
 
-#include <boost/tuple/tuple.hpp>
-
 #define EPSILON real_t(1e-4)
 
+using namespace boost::math;
+
 namespace walberla {
 namespace pe {
 namespace raytracing {
 inline bool intersects(const AABB& aabb, const Ray& ray, real_t& t, real_t padding = real_t(0.0));
 
-inline bool intersects(const SphereID sphere, const Ray& ray, real_t& t);
-inline bool intersects(const PlaneID plane, const Ray& ray, real_t& t);
-inline bool intersects(const BoxID box, const Ray& ray, real_t& t);
+inline bool intersects(const SphereID sphere, const Ray& ray, real_t& t, Vec3& n);
+inline bool intersects(const PlaneID plane, const Ray& ray, real_t& t, Vec3& n);
+inline bool intersects(const BoxID box, const Ray& ray, real_t& t, Vec3& n);
 
 struct IntersectsFunctor
 {
    const Ray& ray_;
    real_t& t_;
+   Vec3& n_;
    
-   IntersectsFunctor(const Ray& ray, real_t& t) : ray_(ray), t_(t) {}
+   IntersectsFunctor(const Ray& ray, real_t& t, Vec3& n) : ray_(ray), t_(t), n_(n) {}
    
    template< typename BodyType >
-   bool operator()( BodyType* bd1 ) { return intersects( bd1, ray_, t_); }
+   bool operator()( BodyType* bd1 ) {
+      return intersects( bd1, ray_, t_, n_);
+   }
 };
 
-inline bool intersects(const SphereID sphere, const Ray& ray, real_t& t) {
+inline bool intersects(const SphereID sphere, const Ray& ray, real_t& t, Vec3& n) {
    real_t inf = std::numeric_limits<real_t>::max();
    const Vec3& direction = ray.getDirection();
    Vec3 displacement = ray.getOrigin() - sphere->getPosition();
@@ -89,22 +94,24 @@ inline bool intersects(const SphereID sphere, const Ray& ray, real_t& t) {
          t = t1;
       }
    }
+   Vec3 intersectionPoint = ray.getOrigin() + direction*t;
+   n = (intersectionPoint - sphere->getPosition()).getNormalized();
+
    return true;
 }
 
-inline bool intersects(const PlaneID plane, const Ray& ray, real_t& t) {
+inline bool intersects(const PlaneID plane, const Ray& ray, real_t& t, Vec3& n) {
    real_t inf = std::numeric_limits<real_t>::max();
    const Vec3& direction = ray.getDirection();
    const Vec3& origin = ray.getOrigin();
-   real_t denominator = plane->getNormal() * direction;
+   const Vec3& planeNormal = plane->getNormal();
+   real_t denominator = planeNormal * direction;
    if (std::abs(denominator) > EPSILON) {
       real_t t_;
-      t_ = ((plane->getPosition() - origin) * plane->getNormal()) / denominator;
-      
+      t_ = ((plane->getPosition() - origin) * planeNormal) / denominator;
       if (t_ > EPSILON) {
-         Vec3 intersectionPoint = (t_*direction + origin);
-         Vec3 originToIntersection = origin - intersectionPoint;
-         t = originToIntersection.length();
+         t = t_;
+         n = planeNormal * sign(-denominator);
          return true;
       } else {
          t = inf;
@@ -114,7 +121,7 @@ inline bool intersects(const PlaneID plane, const Ray& ray, real_t& t) {
    return false;
 }
 
-inline bool intersects(const BoxID box, const Ray& ray, real_t& t) {
+inline bool intersects(const BoxID box, const Ray& ray, real_t& t, Vec3& n) {
    Ray transformedRay(box->pointFromWFtoBF(ray.getOrigin()), box->vectorFromWFtoBF(ray.getDirection()));
    
    const Vec3& lengths = box->getLengths();
@@ -131,6 +138,7 @@ inline bool intersects(const BoxID box, const Ray& ray, real_t& t) {
    
    real_t inf = std::numeric_limits<real_t>::max();
    
+   size_t tminAxis = 0, tmaxAxis = 0;
    real_t txmin, txmax;
    real_t tmin = txmin = (bounds[sign[0]][0] - origin[0]) * invDirection[0];
    real_t tmax = txmax = (bounds[1-sign[0]][0] - origin[0]) * invDirection[0];
@@ -141,9 +149,11 @@ inline bool intersects(const BoxID box, const Ray& ray, real_t& t) {
       return false;
    }
    if (tymin > tmin) {
+      tminAxis = 1;
       tmin = tymin;
    }
    if (tymax < tmax) {
+      tmaxAxis = 1;
       tmax = tymax;
    }
    real_t tzmin = (bounds[sign[2]][2] - origin[2]) * invDirection[2];
@@ -153,16 +163,20 @@ inline bool intersects(const BoxID box, const Ray& ray, real_t& t) {
       return false;
    }
    if (tzmin > tmin) {
+      tminAxis = 2;
       tmin = tzmin;
    }
    if (tzmax < tmax) {
+      tmaxAxis = 2;
       tmax = tzmax;
    }
    
+   n[0] = n[1] = n[2] = real_t(0);
    real_t t_;
    if (tmin > 0) {
       // ray hit box from outside
       t_ = tmin;
+      n[tminAxis] = real_t(1);
    } else if (tmax < 0) {
       // tmin and tmax are smaller than 0 -> box is in rays negative direction
       t = inf;
@@ -170,8 +184,16 @@ inline bool intersects(const BoxID box, const Ray& ray, real_t& t) {
    } else {
       // ray origin within box
       t_ = tmax;
+      n[tmaxAxis] = real_t(1);
+   }
+   
+   if (transformedRay.getDirection() * n > 0) {
+      n = -n;
    }
    
+   n = box->vectorFromBFtoWF(n);
+   WALBERLA_LOG_INFO("t_: " << t_ << ", n: " << n);
+   
    t = t_;
    return true;
 }
diff --git a/src/pe/raytracing/Raytracer.h b/src/pe/raytracing/Raytracer.h
index 3c2cc9959b336ef34e89877060bcfb69eaa814d4..1a1c239819ea214f22d091dae5fef74deb91a4f4 100644
--- a/src/pe/raytracing/Raytracer.h
+++ b/src/pe/raytracing/Raytracer.h
@@ -254,10 +254,10 @@ void Raytracer::rayTrace(const size_t timestep) {
    std::vector<BodyIntersectionInfo> intersections; // contains for each pixel information about an intersection, if existent
    
    real_t t, t_closest;
-   walberla::id_t id_closest;
+   Vec3 n;
    RigidBody* body_closest = NULL;
    Ray ray(cameraPosition_, Vec3(1,0,0));
-   IntersectsFunctor func(ray, t);
+   IntersectsFunctor func(ray, t, n);
    tp_["Raytracing"].start();
    for (size_t x = 0; x < pixelsHorizontal_; x++) {
       for (size_t y = 0; y < pixelsVertical_; y++) {
@@ -265,8 +265,8 @@ void Raytracer::rayTrace(const size_t timestep) {
          Vec3 direction = (pixelLocation - cameraPosition_).getNormalized();
          ray.setDirection(direction);
          
+         n[0] = n[1] = n[2] = real_t(0);
          t_closest = inf;
-         id_closest = 0;
          body_closest = NULL;
          for (auto blockIt = forest_->begin(); blockIt != forest_->end(); ++blockIt) {
 #ifndef DISABLE_BLOCK_AABB_INTERSECTION_PRECHECK
@@ -288,7 +288,6 @@ void Raytracer::rayTrace(const size_t timestep) {
                if (intersects && t < t_closest) {
                   // body was shot by ray and currently closest to camera
                   t_closest = t;
-                  id_closest = bodyIt->getID();
                   body_closest = *bodyIt;
                }
             }
@@ -310,7 +309,6 @@ void Raytracer::rayTrace(const size_t timestep) {
                if (intersects && t < t_closest) {
                   // body was shot by ray and currently closest to camera
                   t_closest = t;
-                  id_closest = bodyIt->getID();
                   body_closest = *bodyIt;
                }
             }
diff --git a/tests/pe/Raytracing.cpp b/tests/pe/Raytracing.cpp
index 7e1e5f22574774d9f281dc11a7b057ec337aceb1..3722f69f8f9ef131cc46e7cf0fb91ba19bb45275 100644
--- a/tests/pe/Raytracing.cpp
+++ b/tests/pe/Raytracing.cpp
@@ -16,6 +16,8 @@
 #include "core/DataTypes.h"
 #include "core/math/Vector3.h"
 
+#include <pe/raytracing/Ray.h>
+#include <pe/raytracing/Intersects.h>
 #include <pe/raytracing/Raytracer.h>
 
 using namespace walberla;
@@ -29,25 +31,29 @@ void SphereIntersectsTest()
    MaterialID iron = Material::find("iron");
    Sphere sp1(123, 1, Vec3(3,3,3), Vec3(0,0,0), Quat(), 2, iron, false, true, false);
    real_t t;
+   Vec3 n;
    
    // ray through the center
    Ray ray1(Vec3(3,-5,3), Vec3(0,1,0));
    WALBERLA_LOG_INFO("RAY -> SPHERE");
    
-   WALBERLA_CHECK(intersects(&sp1, ray1, t));
+   WALBERLA_CHECK(intersects(&sp1, ray1, t, n));
    WALBERLA_CHECK_FLOAT_EQUAL(t, real_t(6));
+   WALBERLA_CHECK_FLOAT_EQUAL(n[0], real_t(0));
+   WALBERLA_CHECK_FLOAT_EQUAL(n[1], real_t(-1));
+   WALBERLA_CHECK_FLOAT_EQUAL(n[2], real_t(0));
 
    // ray tangential
    Ray ray2(Vec3(3,-5,3), Vec3(0,7.5,real_t(std::sqrt(real_t(15))/real_t(2))).getNormalized());
-   WALBERLA_CHECK(!intersects(&sp1, ray2, t));
+   WALBERLA_CHECK(!intersects(&sp1, ray2, t, n));
    
    // sphere behind ray origin
    Sphere sp2(123, 1, Vec3(3,-8,3), Vec3(0,0,0), Quat(), 2, iron, false, true, false);
-   WALBERLA_CHECK(!intersects(&sp2, ray1, t));
+   WALBERLA_CHECK(!intersects(&sp2, ray1, t, n));
    
    // sphere around ray origin
    Sphere sp3(123, 1, Vec3(3,-5,3), Vec3(0,0,0), Quat(), 2, iron, false, true, false);
-   WALBERLA_CHECK(intersects(&sp3, ray1, t));
+   WALBERLA_CHECK(intersects(&sp3, ray1, t, n));
    WALBERLA_CHECK_FLOAT_EQUAL(t, real_t(2));
 }
 
@@ -58,22 +64,40 @@ void PlaneIntersectsTest() {
    
    Ray ray1(Vec3(-5,3,3), Vec3(1,0,0));
    real_t t;
+   Vec3 n;
    
    WALBERLA_LOG_INFO("RAY -> PLANE");
-   WALBERLA_CHECK(intersects(&pl1, ray1, t), "ray through center did not hit");
+   WALBERLA_CHECK(intersects(&pl1, ray1, t, n), "ray through center did not hit");
    WALBERLA_CHECK_FLOAT_EQUAL(t, real_t(8), "distance between ray and plane is incorrect");
    
    Ray ray2(Vec3(-5,3,3), Vec3(1,0,-1).getNormalized());
-   WALBERLA_CHECK(intersects(&pl1, ray2, t), "ray towards random point on plane didn't hit");
+   WALBERLA_CHECK(intersects(&pl1, ray2, t, n), "ray towards random point on plane didn't hit");
    WALBERLA_CHECK_FLOAT_EQUAL(t, real_t(sqrt(real_t(128))), "distance between ray and plane is incorrect");
+   WALBERLA_CHECK_FLOAT_EQUAL(n[0], real_t(-1), "incorrect normal calculated");
+   WALBERLA_CHECK_FLOAT_EQUAL(n[1], real_t(0), "incorrect normal calculated");
+   WALBERLA_CHECK_FLOAT_EQUAL(n[2], real_t(0), "incorrect normal calculated");
+   
+   Plane pl1neg(1, 1, Vec3(3, 3, 3), Vec3(-1, 0, 0), real_t(1.0), iron);
+   WALBERLA_CHECK(intersects(&pl1neg, ray2, t, n), "ray towards random point on plane didn't hit");
+   WALBERLA_CHECK_FLOAT_EQUAL(n[0], real_t(-1), "incorrect normal calculated");
+   WALBERLA_CHECK_FLOAT_EQUAL(n[1], real_t(0), "incorrect normal calculated");
+   WALBERLA_CHECK_FLOAT_EQUAL(n[2], real_t(0), "incorrect normal calculated");
+   
+   Ray ray3(Vec3(-5,3,3), Vec3(-1,0,0).getNormalized());
+   Plane pl5(1, 1, Vec3(-7, 3, 3), Vec3(1, 0, 0), real_t(1.0), iron);
+   WALBERLA_CHECK(intersects(&pl5, ray3, t, n), "ray towards random point on plane didn't hit");
+   WALBERLA_CHECK_FLOAT_EQUAL(t, real_t(2), "distance between ray and plane is incorrect");
+   WALBERLA_CHECK_FLOAT_EQUAL(n[0], real_t(1), "incorrect normal calculated");
+   WALBERLA_CHECK_FLOAT_EQUAL(n[1], real_t(0), "incorrect normal calculated");
+   WALBERLA_CHECK_FLOAT_EQUAL(n[2], real_t(0), "incorrect normal calculated");
 
    // plane with center 3,3,3 and parallel to x-z plane
    Plane pl2(1, 1, Vec3(3, 3, 3), Vec3(0, 1, 0), real_t(1.0), iron);
-   WALBERLA_CHECK(!intersects(&pl2, ray1, t), "ray parallel to plane shouldnt hit");
+   WALBERLA_CHECK(!intersects(&pl2, ray1, t, n), "ray parallel to plane shouldnt hit");
    
    // plane with center -10,3,3 and parallel to y-z plane
    Plane pl4(1, 1, Vec3(-10, 3, 3), Vec3(1, 0, 0), real_t(1.0), iron);
-   WALBERLA_CHECK(!intersects(&pl4, ray1, t), "ray hit plane behind origin");
+   WALBERLA_CHECK(!intersects(&pl4, ray1, t, n), "ray hit plane behind origin");
 }
 
 void BoxIntersectsTest() {
@@ -81,37 +105,55 @@ void BoxIntersectsTest() {
 
    MaterialID iron = Material::find("iron");
    real_t t;
+   Vec3 n;
    
    Box box1(127, 5, Vec3(0, -15, 0), Vec3(0, 0, 0), Quat(), Vec3(10, 10, 10), iron, false, true, false);
    Ray ray1(Vec3(3,-5,3), Vec3(0,1,0));
-   WALBERLA_CHECK(!intersects(&box1, ray1, t));
+   WALBERLA_CHECK(!intersects(&box1, ray1, t, n));
    
    Box box2(128, 5, Vec3(0, -2, 0), Vec3(0, 0, 0), Quat(), Vec3(10, 10, 10), iron, false, true, false);
-   WALBERLA_CHECK(intersects(&box2, ray1, t));
+   WALBERLA_CHECK(intersects(&box2, ray1, t, n));
    WALBERLA_CHECK_FLOAT_EQUAL_EPSILON(t, real_t(8), real_t(1e-7));
    
    Box box3(128, 5, Vec3(0, 5, 0), Vec3(0, 0, 0), Quat(), Vec3(10, 10, 10), iron, false, true, false);
-   WALBERLA_CHECK(intersects(&box3, ray1, t));
+   WALBERLA_CHECK(intersects(&box3, ray1, t, n));
    WALBERLA_CHECK_FLOAT_EQUAL(t, real_t(5));
    
+   Ray ray6(Vec3(-8,5,0), Vec3(1,0,0));
+   WALBERLA_CHECK(intersects(&box3, ray6, t, n));
+   WALBERLA_CHECK_FLOAT_EQUAL(t, real_t(3));
+   WALBERLA_CHECK_FLOAT_EQUAL(n[0], real_t(-1), "incorrect normal calculated");
+   WALBERLA_CHECK_FLOAT_EQUAL(n[1], real_t(0), "incorrect normal calculated");
+   WALBERLA_CHECK_FLOAT_EQUAL(n[2], real_t(0), "incorrect normal calculated");
+   
+   Ray ray7(Vec3(8,5,0), Vec3(-1,0,0));
+   WALBERLA_CHECK(intersects(&box3, ray7, t, n));
+   WALBERLA_CHECK_FLOAT_EQUAL(t, real_t(3));
+   WALBERLA_CHECK_FLOAT_EQUAL(n[0], real_t(1), "incorrect normal calculated");
+   WALBERLA_CHECK_FLOAT_EQUAL(n[1], real_t(0), "incorrect normal calculated");
+   WALBERLA_CHECK_FLOAT_EQUAL(n[2], real_t(0), "incorrect normal calculated");
+
    // ray origin within box
    Ray ray2(Vec3(-2,0,0), Vec3(1,0,1).getNormalized());
-   WALBERLA_CHECK(intersects(&box3, ray2, t));
+   WALBERLA_CHECK(intersects(&box3, ray2, t, n));
    WALBERLA_CHECK_FLOAT_EQUAL_EPSILON(t, real_t(7.0710), real_t(1e-4));
    
    Ray ray3(Vec3(3,-5,3), Vec3(2, -1.5, 0.5).getNormalized());
    Box box4(128, 5, Vec3(0, 8, 0), Vec3(0, 0, 0), Quat(), Vec3(10, 10, 10), iron, false, true, false);
-   WALBERLA_CHECK(!intersects(&box4, ray3, t));
+   WALBERLA_CHECK(!intersects(&box4, ray3, t, n));
    
    Ray ray4(Vec3(3,-5,3), Vec3(-2, 3, 0.5).getNormalized());
-   WALBERLA_CHECK(intersects(&box4, ray4, t));
+   WALBERLA_CHECK(intersects(&box4, ray4, t, n));
    WALBERLA_CHECK_FLOAT_EQUAL_EPSILON(t, real_t(9.7068), real_t(1e-4));
    
    Box box5(128, 5, Vec3(4, 0, 0), Vec3(0, 0, 0), Quat(), Vec3(4, 4, 4), iron, false, true, false);
    box5.rotate(0,0,math::M_PI/4);
    Ray ray5(Vec3(0,1.5,0), Vec3(1,0,0));
-   WALBERLA_CHECK(intersects(&box5, ray5, t));
+   WALBERLA_CHECK(intersects(&box5, ray5, t, n));
    WALBERLA_CHECK_FLOAT_EQUAL_EPSILON(t, real_t(2.67157), real_t(1e-4));
+   WALBERLA_CHECK_FLOAT_EQUAL_EPSILON(n[0], real_t(-0.707107), real_t(1e-5), "incorrect normal calculated");
+   WALBERLA_CHECK_FLOAT_EQUAL_EPSILON(n[1], real_t(0.707107), real_t(1e-5), "incorrect normal calculated");
+   WALBERLA_CHECK_FLOAT_EQUAL(n[2], real_t(0), "incorrect normal calculated");
 }
 
 void AABBIntersectsTest() {