Exemplo n.º 1
0
double FindNearestTIntersectionWithSphere(Ray* ray, int* index, int noCheckID = NONE) {
    
    assert(noCheckID==NONE || (noCheckID>=0 && noCheckID<num_spheres));
    
    double nearestTIntersect = INFINITY;
    *index = NONE;
    
    /* (x_d^2 + y_d^2 + z_d^2)t^2 + 2((x_o-x_c)x_d +(y_o-y_c)y_d + (z_o-z_c)z_d)t
     *  + (x_o-x_c)^2 + (y_o-y_c)^2 + (z_o-z_c)^2 - r^2 = 0
     */
    unsigned int i;
    for (i = 0; i < num_spheres; i++) {
        
        if (i==noCheckID){
            continue;
        }
        
        Vector4* sphereCenter = new Vector4(spheres[i].position);
        
        Vector4* sphereRay = new Vector4(ray->source);
        sphereRay->Subtraction(sphereCenter);
        
        double A = pow(ray->dir->Mod(), 2);
        double B = 2 * (ray->dir->DotProduct(sphereRay));
        double C = pow(sphereRay->Mod(), 2) - pow(spheres[i].radius, 2);
        
        double soln1=0.0,soln2=0.0;
        SolveQuadraticEquation(A,B,C,&soln1,&soln2);       
        
        if (soln1 >= 0 && soln2 >= 0){
//            //For Debugging Purposes
//            printf("(%f,%f)\n",soln1,soln2);
            
            double candidateT = NONE;
            if(soln1<soln2){
                candidateT = soln1;
            }
            else{
                candidateT = soln2;
            }
                
            //assert(candidateT>=soln1 && candidateT>=soln2);
            if(nearestTIntersect > candidateT /*&& candidateT>(cameraZ-screenZ)*/) {
                nearestTIntersect = candidateT;            
                *index = i;           
            }
        }
        
        delete(sphereCenter);
        delete(sphereRay);
    }       
    
    return nearestTIntersect;
}
Exemplo n.º 2
0
// For Shading Purposes
void RT_shade(Ray* ray, int depth) {
    
    if (depth <= MAX_DEPTH){                
        
        // Color Coefficients
        Vector4* diffuseCoeff = new Vector4();
        Vector4* specularCoeff = new Vector4();
        double shininess;
        
        // Diffuse and Specular Terms
        double diffuseTerm[3] = {0.0, 0.0, 0.0};
        double specularTerm[3] = {0.0, 0.0, 0.0};
        
        if (ray->intersectedObject == SPHERE) {

            diffuseCoeff->ReInitialize(spheres[ray->intersectID].color_diffuse);
            specularCoeff->ReInitialize(spheres[ray->intersectID].color_specular);
            shininess = spheres[ray->intersectID].shininess;
        }
        else if (ray->intersectedObject == TRIANGLE) {

            // Interpolate diffuse and specular coefficients
            double alpha, beta;
            ObtainIntermediateTriangleIntersection(ray->intersectID, ray->intersectPoint, &alpha, &beta);

            diffuseCoeff->ReInitialize();
            InterpolateTriangleProperty(triangles[ray->intersectID].v[0].color_diffuse,
                    triangles[ray->intersectID].v[1].color_diffuse,
                    triangles[ray->intersectID].v[2].color_diffuse,
                    alpha, beta, diffuseCoeff, false);

            specularCoeff->ReInitialize();
            InterpolateTriangleProperty(triangles[ray->intersectID].v[0].color_specular,
                    triangles[ray->intersectID].v[1].color_specular,
                    triangles[ray->intersectID].v[2].color_specular,
                    alpha, beta, specularCoeff, false);

            // Interpolate shininess
            if (alpha > 0) {

                double intermediateShininess = beta * triangles[ray->intersectID].v[2].shininess
                        + (1 - beta) * triangles[ray->intersectID].v[1].shininess;

                shininess = ((alpha - 1) * triangles[ray->intersectID].v[0].shininess
                        + intermediateShininess) / alpha;
            } 
            else {
                shininess = triangles[ray->intersectID].v[0].shininess;
            }
        }

        // Boundary Checking        
        assert(diffuseCoeff->HasNonNegativeEntries());
        assert(!diffuseCoeff->HasGreaterThanOneEntries());
        assert(specularCoeff->HasNonNegativeEntries());
        assert(!specularCoeff->HasGreaterThanOneEntries());
        assert(shininess >= 0);
        
        // Normal Vector: N
        Vector4* N = new Vector4(ray->normal);
        N->ConvertToUnitVector();
        
        // Viewer Direction: V = ray->intersectedPoint - ray->source = -ray->dir
        Vector4* V = new Vector4(ray->dir);
        V->Scale(-1);
        V->ConvertToUnitVector();
        
        int dontCheckObject = NONE;
        int dontCheckObjectID = NONE;
        
        if (ray->intersectedObject == TRIANGLE) {
            dontCheckObject = ray->intersectedObject;
            dontCheckObjectID = ray->intersectID;
        }
        
                
        unsigned int i;
        for (i = 0; i < num_lights; i++) {            
            
            // Shoot a ray in the direction of the light
            Vector4* lightPos = new Vector4(lights[i].position);
            Ray* checkShadow = new Ray(ray->intersectPoint, lightPos);
            bool shadow = false;            
            
            double nearestTIntersect = FindNearestTIntersection(checkShadow,dontCheckObject,dontCheckObjectID);
            double point2LightDistance = FindDistanceOfIntersectedPointWithLight(ray,i);
            if (nearestTIntersect != INFINITY 
                && nearestTIntersect< point2LightDistance)
            {
                shadow = true;    
            }

            // Point to Light Vector: L = light_pos - intersectedPoint
            Vector4* L = new Vector4(lights[i].position);
            L->Subtraction(ray->intersectPoint);
            L->ConvertToUnitVector();            

            // Reflected Ray: R = 2(N.L)N - L
            Vector4* R = new Vector4(ray->normal);
            R->Scale(2 * N->DotProduct(L));
            R->Subtraction(L);
            R->ConvertToUnitVector();

            // Dot Product of N and L: NL
            double NL = N->DotProduct(L);
            if (NL < 0) {
                NL = 0;
            }

            // Dot Product of R and V: RV
            double RV = R->DotProduct(V);
            if (RV < 0) {
                RV = 0;
            }

            assert(NL <= 1 && RV <= 1);

            double attenuationTerm =  depth==1?1:1; 
            
            if (!shadow) {                
                unsigned int j;
                for (j = 0; j < 3; j++) {
                    diffuseTerm[j] += attenuationTerm * lights[i].color[j] * diffuseCoeff->vector[j] * NL;
                    specularTerm[j] += attenuationTerm * lights[i].color[j] * specularCoeff->vector[j] * pow(RV, shininess);
                }
            }

            
            
            delete(L);
            delete(R);

            delete(lightPos);
            delete(checkShadow);
        }

        // Adding diffused light
        Vector4* diffusedColor = new Vector4(diffuseTerm);
        //          //For Debugging Purposes
        //          if(ray->intersectedObject == SPHERE){                
        //            ray->color->Display();
        //            diffusedColor->Display();
        //            cout<<"................................................."<<endl;
        //          }
        ray->color->Addition(diffusedColor);
        delete(diffusedColor);

        // Adding specular light
        Vector4* specularColor = new Vector4(specularTerm);
        ray->color->Addition(specularColor);        
        delete(specularColor);

        //R = 2*(NI)N - I ; N = N; I = V = ray->source - ray->IntersectPoint
        Vector4* R_ = new Vector4(ray->normal);
        Vector4* I = new Vector4(ray->dir);
        I->Scale(-1);
        R_->Scale(2*N->DotProduct(I));
        R_->Subtraction(I);
        Vector4* end = new Vector4(ray->intersectPoint);
        end->Addition(R_);       
        
        
        Ray* reflectedRay = new Ray(ray->intersectPoint, end);
        delete(R_);
        delete(I);
        delete(end);
        assert(dontCheckObject!=SPHERE);
        RT_trace(reflectedRay, depth+1, dontCheckObject, dontCheckObjectID);

        //For Debugging
//        if(ray->intersectedObject==TRIANGLE/* && ray->intersectPoint->vector[1]<-2*screenX/4
//                && ray->intersectPoint->vector[1]>-3*screenX/4*/){
//            cout<<ray->intersectID;            
//            cout<<"---->";
//            ray->normal->Display();
//            cout<<"------>";
//            I->Display();
//            cout<<I->DotProduct(ray->normal)<<"\t";
//            cout<<reflectedRay->dir->DotProduct(ray->normal);
//            reflectedRay->dir->Display();
//            cout<<": "<<reflectedRay->tIntersect<<"\t";            
//            reflectedRay->color->Display();
//            cout<<endl;
//        }
        
        if(reflectedRay->tIntersect!=INFINITY){          
            
            reflectedRay->color->Scale(specularCoeff->vector[0], specularCoeff->vector[1], specularCoeff->vector[2]);                       
            ray->color->Addition(reflectedRay->color);
        }
        
        delete(reflectedRay);

        delete(N);
        delete(V);
        delete(specularCoeff);
        delete(diffuseCoeff);
    }    
}