Shadows in a ray tracer


I’m trying to find a solution to have colours in the shadows of my ray tracer, I’m not looking for something sophisticated like soft shadows, I’m just looking for something that does not look wrong. The situation is the following:

As you see, the shadow on the green wall is brighter than the wall, and this is not correct. I did not find the formula to calculate the color of the shadow, I’m trying to find a way by myself. To calculate the light on the shadow, I’m simply adding the ambient component, the color of the material, and the dotProduct( between the direction of the ray and the normal of the striked triangle). To try to tune the shadows, I’ve added a variable called ambient_coeficient and ambient_diffuse, as explained here The sum of these 2 variables is always 1, and I’ve tried to adjust them in order to avoid the brighter shadow but without any result. The scene is too dark, or the shadow on the wall is too brighter. This is the snippet of code that I use to find out the amount of light that needs to be added on a surface in shadow.

// surfelX->getGeometricNormal() this simply returns the direction on which the surface is pointing
// wi is the direction of the ray
float dProd = abs(glm::dot(wi, surfelX->getGeometricNormal()));
// vecAmbientLight is a glm::vec3 that contains a valure for a white light
// color is the color of the material. green in the case of the wall
Light += vecAmbientLight + glm::vec3( dProd * ambient_coeficient) * color;

the whole repository is here


Problem fixed. I was adding to much light in the shadow branch. Instead of

        float dProd = abs(glm::dot(wi, surfelX->getGeometricNormal()));
        Light +=
        vecAmbientLight + glm::vec3( dProd * diffuse_coeficient) * color;

It can simply be:

        Light += vecAmbientLight;

This is an approximation, and it has the drawbacks that it needs to be adjusted by the user when rendering the scene.

the vecAmbientLight is calculated with this function that takes as parameter the color of the material.

glm::vec3 ofxRayTracer::getAmbientLight(const glm::vec3& color) const{
    return color * ambientTerm;

ambientTerm is just a float (in my case simply 0.2), it can be a constant or a value that the user can adjust.