Victor Jore
Victor Jore

Reputation: 21

Problem with PathTracing ShadowRay, Spheres all black

So i'm making a raytracer in OpenGL, fully shader based, and i'm struggling to know where the problem is with my Shadow rays. If i multiply the radiance of the object by the shadowRay output, it seems like only the "edge" of the sphere is lighten up

I verified multiple times the code without finding where the problem comes from.

This is what i get:

Result

vec3 TraceShadowRay(vec3 hitPoint, vec3 normal, Object objects[3])
{
    Light pointLight;

    pointLight.position = vec3(0, 80, 0);
    pointLight.intensity = 2;

    Ray ShadowRay;
    ShadowRay.origin = hitPoint + normal * 1e-4;
    ShadowRay.dir = normalize(pointLight.position - ShadowRay.origin);
    ShadowRay.t = 100000;
    //ShadowRay.dir = vec3(0, 1, 0);

    for(int i = 0; i < 3; ++i)
    {
        if(objects[i].type == 0)
        {
            if(interectSphere(objects[i].position, objects[i].radius, ShadowRay))
            {
                return vec3(0);
            }
        }
        if(objects[i].type == 1)
        {
            if(intersectPlane(objects[i].normal, objects[i].position, ShadowRay))
            {
                return vec3(0);
            }
        }
    }
    float AngleNormalShadow = dot(ShadowRay.dir, normal);
    clamp(AngleNormalShadow, 0, 1);

    return GetLight(ShadowRay.origin, pointLight);// * AngleNormalShadow;
}

The getLight function:

vec3 GetLight(vec3 origin, Light light)
{
    return vec3(1, 1, 1) * light.intensity;
    //float dist = sqrt( ((origin.x - light.position.x) * (origin.x - light.position.x))  +   ((origin.y - light.position.y) * (origin.y - light.position.y)));
    //return (vec3(1, 1, 1) * light.intensity) / (4 * M_PI * ((origin - light.position).length * (origin - light.position).length));
}

The intersectSphere function:

bool interectSphere(const vec3 center, float radius, inout Ray r)
{
    vec3 o = r.origin;
    vec3 d = r.dir;

    vec3 v = o - center;

    float b = 2 * dot(v, d);
    float c = dot(v, v) - radius*radius;
    float delta = b*b - 4 * c;

    if(delta < 1e-4)
        return false;

    float t1 = (-b - sqrt(delta))/2;
    float t2 = (-b + sqrt(delta))/2;

    if(t1 < t2)
    {
        r.t = t1;
        r.t2 = t2;
    }
    else if(t2 < t1)
    {
        r.t = t2;
        r.t2 = t1;
    }

    r.reflectionNormal = normalize((r.origin + r.dir * r.t) - center);

    return true;
}

The result expected is a nice shaded sphere with light coming from the top of the spheres

Upvotes: 2

Views: 238

Answers (1)

fifoforlifo
fifoforlifo

Reputation: 774

Could it be a missing negation? Looks like interectSphere() returns true when there is a collision, but the calling code in TraceShadowRay() bails out when it returns true.

old:

        if(interectSphere(objects[i].position, objects[i].radius, ShadowRay))
        {
            return vec3(0);
        }

new:

        if(!interectSphere(objects[i].position, objects[i].radius, ShadowRay))
        {
            return vec3(0);
        }

Upvotes: 1

Related Questions