Exemple #1
0
//Outputs the color of the object as enlightened by at the point where `ray` hits it.
rt::color Object::render_direct(const Ray & ray, Scene & scene, const LightSource & light_source) {
    rt::color basic = compose(light_source.get_color(), color);
    Impact imp = get_impact(ray);
    Ray to_light(imp.point, light_source.get_origin());
    double scalar = -(ray.get_direction() | imp.normale);
    if (((light_source.get_origin()-imp.point) | imp.normale) <= 0) {
        return rt::color::BLACK;
    }
    std::list<Object *> others;
    Object* interceptor = scene.get_interceptor(to_light, &others);
    // In case there has been mixups due to rounding errors and the object catches
    // its own ray back to the light when it shouldn't (which is NOT always the case)
    // detect it
    if (interceptor) {
        if (interceptor != this && interceptor->intersects(ray) < (imp.point - light_source.get_origin()).norm())
            return rt::color::BLACK;
        if (intersects(to_light) >= OWNRAY_EPSILON)
            return rt::color::BLACK;
        if (others.size() > 1)
            return rt::color::BLACK;
    }
    return rt::color(
            static_cast<unsigned char>(scalar*basic.get_red()),
            static_cast<unsigned char>(scalar*basic.get_green()),
            static_cast<unsigned char>(scalar*basic.get_blue())
        );
}
Exemple #2
0
bool DSphere::randomPoint(const Vector3 &viewpoint, const Vector2 &seed, float time, Vector3 &light_point, Vector3 &N, float &pdf, Color &radiance) const {
    float d = (viewpoint - getCenter(0)).magnitude();
    if (d < radius) {return false;}
    float r = radius;
    //internal angle of cone surrounding light seen from viewpoint
    float sin_alpha_max = r / d;
    float cos_alpha_max = sqrt(1 - sin_alpha_max * sin_alpha_max);
    float q = 1.0 / (2*M_PI*(1 - cos_alpha_max));
    float cos_alpha = 1 + seed.x() * (cos_alpha_max - 1);
    float sin_alpha = sqrt(1 - cos_alpha * cos_alpha);
    float phi = 2*M_PI*seed.y();
    float cos_phi = cos(phi);
    float sin_phi = sin(phi);
    Vector3 k_i(cos_phi * sin_alpha, sin_phi * sin_alpha, cos_alpha);
    //construct local coordinate system UVW where viewpoint at origin and sphere at (0,0,d) in UVW
    ONB UVW;
    UVW.initFromW(getCenter(0) - viewpoint);
    Ray to_light(viewpoint, k_i.x() * UVW.u() + k_i.y() * UVW.v() + k_i.z() * UVW.w());
    
    IntersectRecord rec;
    if (this -> intersect(to_light, 0.00001, FLT_MAX, time, rec)) {
        light_point = rec.intersection;
        float cos_theta_prime = -dot(rec.uvw.w(), to_light.direction());
        pdf = q * cos_theta_prime / (light_point - viewpoint).squaredMagnitude();
        N = rec.uvw.w();
        radiance = mptr -> emittedRadiance(rec.uvw, -to_light.direction(), light_point, rec.uv);
        return true;
    }
    return false;
}