Пример #1
0
    double intersect(Ray r) {
        double n_dot_u = normal.dot(r.direction);

        if ((n_dot_u > -0.00001L) && (n_dot_u < 0.00001L)) {
            return -1.0L;
        }

        double n_dot_p0 = normal.dot(center.sub(r.origin));

        return n_dot_p0 / n_dot_u;
    }
Пример #2
0
    double intersect(Ray r) {
        // cout << "Sphere intersect()" << endl;
        V3 distance = r.origin.sub(center);
        double b = distance.dot(r.direction);
        double c = distance.dot(distance) - radius2;
        double d = (b * b) - c;

        if (d > 0.0L) {
            return -b - sqrt(d);
        } else {
            return -1.0L;
        }
    }
Пример #3
0
bool isInMandelbox2(V3 curr_point) {
    V3 Zn = V3(0, 0, 0);
    float dZn = 1.0;

    bool foundFractal = true;

    for (int i = 0; i < DEPTH; i++) {

        boxFold(&Zn);
        sphereFold(&Zn, dZn);

        Zn = Scale * Zn + curr_point;
        dZn = Scale * dZn + 1.0;

        if (Zn.dot(Zn) > BREAK) {
            foundFractal = false;
            break;
        }
    }
    return foundFractal;
}
Пример #4
0
    V3 trace(Ray ray, int n, vector <HitRecord>* hits) {
        if (n > 4) {
            return V3();
        }

        Body *hit = NULL;
        double mint = DBL_MAX;
        // cout << "Body count: " << scene.body_count << endl;
        for (int i = 0; i < scene.body_count; i++) {
            Body *candidate = scene.objects[i];
            // cout << candidate->shape->intersect(ray) << endl;
            double t = candidate->shape->intersect(ray);
            if ((t > 0) && (t <= mint)) {
                mint = t;
                hit = candidate;
            }
        }

        if (hit == NULL) {
            return V3();
        }

        // cout << "hit";

        V3 point = ray.origin.add(ray.direction.muls(mint));
        V3 normal = hit->shape->getNormal(point);
        V3 direction = hit->material->bounce(ray, normal);
        if (direction.dot(ray.direction) > 0.0f) {
            // if the ray is refractedmove the intersection point a bit in
            point = ray.origin.add(ray.direction.muls(mint*1.0000001L));
        } else {
            // otherwise move it out to prevent problems with doubleing point
            // accuracy
            point = ray.origin.add(ray.direction.muls(mint*0.9999999L));
        }
        hits->push_back(HitRecord(point, hit));

        Ray newray = Ray(point, direction);
        return trace(newray, n+1, hits).mul(hit->material->color).add(hit->material->emission);
    }
Пример #5
0
bool isInMandelbox(V3 curr_point, float *dist) {
    V3 Zn = V3(0, 0, 0);
    float dZn = 1.0;
    V3 offset = curr_point;

    bool foundFractal = true;

    for (int i = 0; i < DEPTH; i++) {

        boxFold(&Zn);
        sphereFold(&Zn, dZn);

        Zn = Scale * Zn + offset;
        dZn = Scale * dZn + 1.0;

        if (Zn.dot(Zn) > BREAK) {
            foundFractal = false;
            break;
        }
    }
    *dist = Zn.length() * log((Zn.length())) / fabs(dZn);
    return foundFractal;
}
Пример #6
0
// Moeller-Trumbore
bool Triangle::hit(const Ray& ray, const Ray_Tracer* rt,
                    float t_min, float t_max, Ray_Hit& rh, bool shadow) const {

    // Absolute Triangle Vertex Positions
    V3& v0 = m->verts[inds[0]];
    V3& v1 = m->verts[inds[1]];
    V3& v2 = m->verts[inds[2]];

    // Two edges of triangle
    V3 e0, e1;
    e0 = v1 - v0;
    e1 = v2 - v0; 

    V3 p = ray.s.cross(e1);
    float deter = e0.dot(p);

    if (deter  > -EPSILON && deter < EPSILON)
        return false; 

    V3 t = ray.o - v0;
    
    // Store the inverse to reduce divisions
    float inv_deter = 1.0 / deter;
    float u = t.dot(p) * inv_deter;

    if (u < 0.0 || u > 1.0)
        return false;

    V3 q = t.cross(e0);
    float v = ray.s.dot(q) * inv_deter;

    if (v < 0.0 || u + v > 1.0)
        return false;

    float t_inter = e1.dot(q) * inv_deter;

    if (t_inter < t_min || t_inter > t_max) {
        //std::cout << "Cull: " << t_inter << '\t' <<t_min<< '\t' <<t_max<<  std::endl;
        return false;
    }

    rh.t = t_inter;
    rh.col = 0.2*m->mat.col;
    rh.shape = m;

    if (shadow || ray.depth >= rt->depth_limit)
        return true;

/*
    if (is_light) {     
        rh.col = Color(1.0, 1.0, 1.0);
        return true;
    }
*/

    V3 int_loc = ray.at(t_inter);
    // Shadow
    for (Shape* light : rt->lights) {

        // BIG ASSUMPTION THAT ALL LIGHTS ARE SPHERES
        Sphere* sph = static_cast<Sphere*>(light);

        // Make ray from intersection to light
        V3 int_to_light = sph->c - int_loc; 
        float dist_to_light = int_to_light.norm();
        int_to_light.normalize();
        Ray shadow_ray(int_loc + EPSILON*int_to_light, int_to_light, ray.depth + 1);
        Ray_Hit shadow_hit;
        if (rt->kd->hit_helper(true, rt->kd->root, shadow_ray, rt,
                EPSILON, dist_to_light, shadow_hit, true, 0)) {
            if (!shadow_hit.shape->is_light) {
                continue;
            }
        }

        float inner = int_to_light.dot(normal);
        if (inner > 0.0) {
            rh.col += sph->mat.col *inner* m->mat.diff * m->mat.col;
        }
    }

    // Reflection 
    V3 refl_dir = ray.s - 2.0f * (normal.dot(ray.s)) * normal;
    Ray refl_ray(int_loc + EPSILON*refl_dir, refl_dir, ray.depth + 1);
    Ray_Hit refl_hit;
    if (rt->kd->hit_helper(true, rt->kd->root, refl_ray, rt,
            EPSILON, FLT_MAX, refl_hit, false, 0)) {
    //if (rt->trace(refl_ray, EPSILON, FLT_MAX, refl_hit, false)) {
        rh.col += m->mat.refl*refl_hit.col * refl_hit.shape->mat.col;
    }

    return true;  
}