dimanche 17 décembre 2017

Ray tracing sphere reflection bug

I am trying to implement the ray tracing algorithm and I have some trouble computing the reflected rays of spherical objects.It seems that for some particular rays, the reflected ray just passes through and is collinear with the traced ray. Bellow is how i record the ray - sphere intersection:

bool Sphere::intersectLocal(const ray & r, isect & i) const {
    Vec3d P = r.getPosition();
    Vec3d D = r.getDirection();
    //D.normalize();
    double a = dot(D, D);
    double b = 2 * dot(P, D);
    double c = dot(P, P) - 1;
    double delta = b * b - 4 * a * c;
    if (delta < 0)
        return false;
    if (delta == 0) {
        double t = -b / 2 * a;
        Vec3d Q = P + t * D;
        Vec3d N = Q;
        N.normalize();
        i.setT(t);
        i.setN(N);
        i.setObject(this);
        return true;
    }
    if (delta > 0) {
        double t1 = (-b - sqrt(delta)) / 2 * a;
        double t2 = (-b + sqrt(delta)) / 2 * a;
        double t;
        if (t1 > 0) t = t1;
        else if (t2 > 0) t = t2;
        else return false;
        Vec3d N = P + t * D;
        N.normalize();
        i.setT(t);
        i.setN(N);
        i.setObject(this);
        return true;
    }
    return false;
}

And this is how I compute the reflected ray for each intersection:

isect i;
if (scene - > intersect(r, i)) {
    // An intersection occured!  
    const Material & m = i.getMaterial();
    double t = i.t;
    Vec3d N = i.N;
    Vec3d I = m.shade(scene, r, i); //local illumination
    if (!m.kr(i).iszero() && depth >= 0) {
        // compute reflection direction
        Vec3d raydir = r.getDirection();
        Vec3d refldir = 2 * dot(-raydir, i.N) * i.N + raydir;
        refldir.normalize();
        ray reflectionRay = ray(r.at(i.t), refldir, ray::RayType::REFLECTION);
        Vec3d reflection = traceRay(reflectionRay, thresh, depth - 1);
        Vec3d R = reflection;
        I += R;
    }
    return I;
} else {
    // No intersection.  This ray travels to infinity, so we color
    // it according to the background color, which in this (simple) case
    // is just black.
    return Vec3d(0.0, 0.0, 0.0);
}

The code above seems to work fine for most of the points on the sphere where the rays intersect, but for others it does not reflect as i expected

enter image description here

enter image description here

enter image description here





Aucun commentaire:

Enregistrer un commentaire