Actually, it is not enough to find the first collision, one ray can have more collision with the triangles in the mesh and I’ve to pick up the closest collision point (intersection) for that ray.
This is the previous code:
shared_ptr<Surfel> RayCaster::findFirstIntersection(const Ray& ray, const ofMesh& mesh, const glm::mat4& globalTransfMatrix) const{
vector<ofMeshFace> faces = mesh.getUniqueFaces();
bool found = false;
for (ofMeshFace face : faces) {
glm::vec3 baricenter;
found = glm::intersectRayTriangle(
ray.origin, ray.direction,
glm::vec3(globalTransfMatrix * glm::vec4(face.getVertex(0), 1.f)),
glm::vec3(globalTransfMatrix * glm::vec4(face.getVertex(1), 1.f)),
glm::vec3(globalTransfMatrix * glm::vec4(face.getVertex(2), 1.f)),
baricenter);
if (found) {
glm::vec3 faceNormal = face.getFaceNormal();
glm::vec3 position = getPointOnTriangle(ray, baricenter);
return shared_ptr<Surfel>(new Surfel(faceNormal, ray.direction, position));
break;
}
}
return nullptr;
};
This code was generating this image (320x200 resolution)

As you see the intersection are not sorted. That’s why I’ve changed the code as follow:
shared_ptr<Surfel> RayCaster::findFirstIntersection(const Ray& ray, const ofMesh& mesh, const glm::mat4& globalTransfMatrix) const{
vector<ofMeshFace> faces = mesh.getUniqueFaces();
// at the beginning, no intersection is found and the distance to the closest surface
// is set to an high value;
bool found = false;
float distanceToTheClosestSurface = numeric_limits<float>::max();
glm::vec3 faceNormal;
glm::vec3 position;
glm::vec3 rayDirection;
for (ofMeshFace face : faces) {
glm::vec3 baricenter;
bool intersection = glm::intersectRayTriangle(
ray.origin, ray.direction,
glm::vec3(globalTransfMatrix * glm::vec4(face.getVertex(0), 1.f)),
glm::vec3(globalTransfMatrix * glm::vec4(face.getVertex(1), 1.f)),
glm::vec3(globalTransfMatrix * glm::vec4(face.getVertex(2), 1.f)),
baricenter);
// when an intersection is found, it updates the distanceToTheClosestSurface value
// this value is used to order the new intersections, if a new intersection with a smaller baricenter.z
// value is found, this one will become the new intersection
if (intersection) {
if (baricenter.z < distanceToTheClosestSurface) {
found = true;
distanceToTheClosestSurface = baricenter.z;
faceNormal = face.getFaceNormal();
position = getPointOnTriangle(ray, baricenter);
rayDirection = ray.direction;
}
}
}
if (found) {
return shared_ptr<Surfel>(new Surfel(faceNormal, rayDirection, position));
} else {
return nullptr;
}
};
And this goes better but as you see the right part of the image looks still wrong.

Any idea about what I’m doing wrong?
This is the method that I’m using for calculating the light, simple lambertian light for now:
ofColor RayCaster::L_scatteredDirect(const shared_ptr<Surfel>& surfelX,const glm::vec3 wo) const{
glm::vec3 tmpCol;
for(int i = 0; i<lights.size(); i++){
glm::vec3 lightPos = lights[i].getGlobalPosition();
//lambertian light
glm::vec3 lightDirection = glm::normalize(lightPos - surfelX->getPosition());
glm::vec3 color = surfelX->getColor();
// surfelX->getGeometricNormal() returns the normal that was
// founded using face.getFaceNormal()
float dProd = glm::dot(surfelX->getGeometricNormal(), lightDirection);
tmpCol += glm::vec3( dProd ) * color;
}
return ofColor(tmpCol.x*255, tmpCol.y*255, tmpCol.z*255);
};