RGBColor
RenderEngine::trace_ray(const Ray& ray, int rayDepth)
{

    Vector3D normal; // don't need until lighting and shading is added
    Vector3D local_hit_point;
    float	tmin 			= kHugeValue;
    int 	num_objects 	= world_ptr->objects.size();
    RGBColor pixel_color(0,0,0);

    ShadeRec sr;  // stores information about the closest object (so far) that has been it. Look at sphere.cpp to see what is stored.
    sr.t = 100000;   //  need to initialize to a value larger than any expected hit so that this value of t is rejected.

    // PART 1:  JUST NEED TO IMPLEMENT THE LOOP OVER OBJECTS:
    // loop over objects in the scene
    //   Remember, the objects are stored in the World in a vector object (look up vector class) and also use
    //        the variable above num_objects
    // For each object, check to see if the ray intersects it:
            // ShadeRec srObject = world_ptr->objects[j]->hit(ray); // compare with sr
            // if this is closer than anything else previously seen, update  sr
            // and set pixel color:
            //        pixel_color = world_ptr->objects[j]->color; // only used until lights and materials are implemented

    for (int i = 0; i<num_objects; i++){
        ShadeRec srObject = world_ptr->objects[i]->hit(ray);
        if (srObject.t < sr.t && srObject.hit_an_object){
                sr = srObject;
                pixel_color = world_ptr->objects[i]->color;
            }
    }
    // Now, check to see if there has been a hit.  If so, sr should contain the information
    // about the closest hit. Use the pixel_color above and sr to determine the final pixel color.
    //  (Nothing to do below here for PART 1 since we aren't implementing shading yet.
    if (sr.hit_an_object)
    {
        // PART 1:Nothing to do here

        // PART 2:
        //    Need to implement calc_shade
        pixel_color =  calc_shade(ray, sr);
        // PART 3:   need to implement reflected color here
    }
    else
    {
        // If nothing is hit, use the background color.
        pixel_color = world_ptr->background_color;
    }

    return pixel_color;
}
Beispiel #2
0
Datei: crt.c Projekt: arader/crt
color* trace( ray *aray, primitive *scene, int depth, float refr, float *dist,
        int shadows ){
    intersection *isect;
    primitive *prim, *iter;
    vector isect_pt, pn, lv, ln, tmpv1, tmpv2;
    ray tmpr;
    float tmpf1, tmpf2, tmpf3, shade;
    color *tmpc;
    color *c = (color*)malloc( sizeof( color ) );
    if( c == NULL ) {
        fprintf( stderr, "*** error: could not allocate color memory\n" );
        exit( 1 );
    }

    c->x = 0.0f;
    c->y = 0.0f;
    c->z = 0.0f;

    isect = intersect( aray, scene );

    if( isect == NULL ) {
        return c;
    }

    *dist = isect->dist;

    prim = isect->prim;

    if( prim->is_light ) {
        vect_copy( c, &(isect->prim->mat.col) );
        free( isect );
        return c;
    }

    vect_copy( &isect_pt, aray->dir );
    vect_multf( &isect_pt, isect->dist );
    vect_add( &isect_pt, aray->origin );

    prim->normal( prim, &isect_pt, &pn );

    iter = scene;
    while( iter != NULL ) {
        if( iter->is_light ) {
            vect_copy( &lv, &iter->center );
            vect_sub( &lv, &isect_pt );

            vect_copy( &ln, &lv );
            vect_normalize( &ln );

            shade = calc_shade( iter, &isect_pt, &lv, &ln, scene, shadows );

            if( shade > 0.0f ) {
                /* determine the diffuse component */
                tmpf1 = prim->mat.diffuse;
                if( tmpf1 > 0.0f ) {
                    tmpf2 = vect_dot( &pn, &ln );
                    if( tmpf2 > 0.0f ) {
                        tmpf1 *= tmpf2 * shade;
                        vect_copy( &tmpv1, &prim->mat.col );
                        vect_mult( &tmpv1, &iter->mat.col );
                        vect_multf( &tmpv1, tmpf1 );
                        vect_add( c, &tmpv1 );
                    }
                }

                /* determine the specular component */
                tmpf1 = prim->mat.specular;
                if( tmpf1 > 0.0f ) {
                    vect_copy( &tmpv1, &pn );
                    vect_copy( &tmpv2, &ln );
                    tmpf2 = 2.0f * vect_dot( &ln, &pn );
                    vect_multf( &tmpv1, tmpf2 );
                    vect_sub( &tmpv2, &tmpv1 );
                    tmpf2 = vect_dot( aray->dir, &tmpv2 );
                    if( tmpf2 > 0.0f ) {
                        tmpf1 = powf( tmpf2, 20.0f ) * tmpf1 * shade;
                        vect_copy( &tmpv1, &iter->mat.col );
                        vect_multf( &tmpv1, tmpf1 );
                        vect_add( c, &tmpv1 );
                    }
                }
            }
        }

        iter = iter->next;
    }

    /* calculate reflection */
    if( prim->mat.refl > 0.0f && depth < TRACE_DEPTH ) {
        vect_copy( &tmpv1, &pn );
        vect_multf( &tmpv1, 2.0f * vect_dot( &pn, aray->dir ) );
        vect_copy( &tmpv2, aray->dir );
        vect_sub( &tmpv2, &tmpv1 );

        vect_copy( &tmpv1, &tmpv2 );
        vect_multf( &tmpv1, EPSILON );
        vect_add( &tmpv1, &isect_pt );

        tmpr.origin = &tmpv1;
        tmpr.dir = &tmpv2;

        tmpc = trace( &tmpr, scene, depth + 1, refr, &tmpf1, shadows );
        vect_multf( tmpc, prim->mat.refl );

        vect_copy( &tmpv1, &prim->mat.col );
        vect_mult( &tmpv1, tmpc );
        vect_add( c, &tmpv1 );

        free( tmpc );
    }

    /* calculate refraction */
    if( prim->mat.is_refr && depth < TRACE_DEPTH ) {
        vect_copy( &tmpv1, &pn );
        if( isect->inside ) {
            vect_multf( &tmpv1, -1.0f );
        }

        tmpf1 = refr / prim->mat.refr;
        tmpf2 = -( vect_dot( &tmpv1, aray->dir ) );
        tmpf3 = 1.0f - tmpf1 * tmpf1 * (1.0f - tmpf2 * tmpf2);
        if( tmpf3 > 0.0f ) {
            vect_copy( &tmpv2, aray->dir );
            vect_multf( &tmpv2, tmpf1 );
            vect_multf( &tmpv1, tmpf1 * tmpf2 - sqrtf( tmpf3 ) );
            vect_add( &tmpv1, &tmpv2 );

            vect_copy( &tmpv2, &tmpv1 );
            vect_multf( &tmpv2, EPSILON );
            vect_add( &tmpv2, &isect_pt );

            tmpr.origin = &tmpv2;
            tmpr.dir = &tmpv1;

            tmpc = trace( &tmpr, scene, depth + 1, refr, &tmpf1, shadows );

            vect_copy( &tmpv1, &prim->mat.col );
            vect_multf( &tmpv1, prim->mat.absorb * tmpf1 );

            tmpv2.x = expf( -tmpv1.x );
            tmpv2.y = expf( -tmpv1.y );
            tmpv2.z = expf( -tmpv1.z );

            vect_mult( tmpc, &tmpv2 );
            vect_add( c, tmpc );

            free( tmpc );
        }
    }

    free( isect );

    if( c->x > 1.0f ) {
        c->x = 1.0f;
    }
    else if( c->x < 0.0f ) {
        c->x = 0.0f;
    }

    if( c->y > 1.0f ) {
        c->y = 1.0f;
    }
    else if( c->y < 0.0f ) {
        c->y = 0.0f;
    }

    if( c->z > 1.0f ) {
        c->z = 1.0f;
    }
    else if( c->z < 0.0f ) {
        c->z = 0.0f;
    }

    return c;
}