Issues with lambertian shading and shadows (ray tracing)
<p>I've made a <a href="https://github.com/MrCappuccino/Tracey/tree/testing2" rel="nofollow noreferrer">ray tracer:</a></p>

<p>And I've been implementing the Blinn-Phong algorithm, but I've come to some issues when rendering in specific situations <a href="http://i.imgur.com/6NwrWGT.png:" rel="nofollow noreferrer">(otherwise it works quite well)</a></p>

<ul>
<li><p>When a sphere is hovering in the air, lambertian shading isn't working correctly (seems to be only happening if the sphere is above the light source position) - <a href="https://i.imgur.com/AWl6aym.png" rel="nofollow noreferrer">Screenshot</a></p></li>
<li><p>When light source is below sphere - <a href="https://i.imgur.com/cqkQuyl.png" rel="nofollow noreferrer">Screenshot</a></p></li>
<li><p>When a shadow is being cast onto a sphere (can also be seen in 1st example) - <a href="https://i.imgur.com/QWENdTc.png" rel="nofollow noreferrer">Screenshot</a></p></li>
<li><p>When there is more than 1 plane in the scene (Only if shadows are on) - <a href="https://i.imgur.com/jfzL43a.png" rel="nofollow noreferrer">Screenshot</a></p></li>
</ul>

<p>I'm assuming there is something wrong with my shadow  and lambertian shading algorithms, but I'm not sure what, could somebody help?</p>

<p>Code (there are no external libraries, just compile):</p>

<pre><code>Color finalColor;
Color ambient;
Color diffuse;
FPType lambertian;
FPType phong;
Color specular;
bool shadowed = false;

// Ambient
if(AMBIENT_ON)
{
    ambient =  closestObjectMaterial.GetColor() * AMBIENT_LIGHT * closestObjectMaterial.GetAmbient();
    finalColor += ambient;
}

// Shadows, Diffuse, Specular
for(const auto &amp;lightSource : lightSources)
{
    Vector lightDir = (lightSource-&gt;GetPosition() - point); // Calculate the directional vector towards the lightSource
    FPType distance = lightDir.Magnitude();
    lightDir = lightDir.Normalize();
    lambertian = closestObjectNormal.Dot(lightDir);

    // Shadows
    if(SHADOWS_ON &amp;&amp; lambertian &gt; 0)
    {
        Ray shadowRay(point, lightDir); // Cast a ray from the first intersection to the light

        std::vector&lt;FPType&gt; secondaryIntersections;
        for(const auto &amp;sceneObject : sceneObjects)
        {
            secondaryIntersections.push_back(sceneObject-&gt;GetIntersection(shadowRay));
        }

        for(const auto &amp;secondaryIntersection : secondaryIntersections)
        {
            if(secondaryIntersection &gt; TOLERANCE) // If shadow ray intersects with some object along the way
            {
                shadowed = true;
                finalColor *= closestObjectMaterial.GetDiffuse() * AMBIENT_LIGHT;
                break;
            }
        }
    }

    // Diffuse
    if(DIFFUSE_ON &amp;&amp; shadowed == false)
    {
        diffuse = closestObjectMaterial.GetColor().Average(lightSource-&gt;GetColor()) * closestObjectMaterial.GetDiffuse() * lightSource-&gt;GetIntensity() * std::fmax(lambertian, 0) / distance;
        finalColor += diffuse;
    }
    if(shadowed == false &amp;&amp; SPECULAR_ON)
    {
        // Specular
        if(closestObjectMaterial.GetSpecular() &gt; 0 &amp;&amp; closestObjectMaterial.GetSpecular() &lt;= 1)
        {
            Vector V = -sceneDirection;
            // Blinn-Phong
            Vector H = (lightDir + V).Normalize();
            FPType NdotH = closestObjectNormal.Dot(H);

            phong = pow(NdotH, 300);
            specular = lightSource-&gt;GetColor() * std::fmax(0, phong) * lightSource-&gt;GetIntensity() / distance; // closestObjectMaterial.GetSpecular(); add or no?
            finalColor += specular;
        }
    }
}

FPType Sphere::GetIntersection(Ray ray)
{
    Vector length = center - ray.GetOrigin(); // Length of the vector between the center and the ray origin (hypotenuse)
    FPType tca = length.Dot(ray.GetDirection()); // opposide side

    if(tca &lt; 0) // No intersection registered
        return -1;

if(tca &gt; 0) // Intersection registered
{
    FPType a = sqrt(length.Dot(length) - tca*tca); // Adjacent side (a = sqrt(c²-b²))

    if(a &gt; radius || a &lt; 0)
        return -1;

    FPType thc = sqrt(radius*radius - a*a); // the line between 2 intersection points / 2

    FPType primaryIntersection;
    primaryIntersection = tca - thc;
    if(primaryIntersection &gt; 0)
        return primaryIntersection;
    else
    {
        FPType secondaryIntersection = thc + tca;
        return secondaryIntersection;
    }
}
return -1;
</code></pre>

<p>}</p>

<ul>
<li><p><a href="https://github.com/MrCappuccino/Tracey/blob/testing2/src/main.cpp#L97" rel="nofollow noreferrer">Lines 97-132</a></p></li>
<li><p><a href="https://github.com/MrCappuccino/Tracey/blob/testing2/src/Scene.cpp" rel="nofollow noreferrer">To set the scene up</a></p></li>
</ul>