예제 #1
0
Colour Raytracer::getColorFromRay(
    const Matrix4x4& viewToWorld,
    const Point3D& imagePlane,
    const Point3D& eye)
#endif
{
    // create ray from eye to place in image plane
    Ray3D ray;
    ray.origin = viewToWorld * imagePlane;
    ray.dir = ray.origin - eye;

    ray.dir.normalize();

#if _DEBUG
    // keep track of where the ray shot out from... to help with debugging later on
    ray.y = i;
    ray.x = j;
#endif

    Colour col;
    //If Depth of field is ON, also shoot few random rays around the campera pin hole pixel to approximate depth of field
    //http://ray-tracer-concept.blogspot.ca/2011/12/depth-of-field.html
    if (DEPTH_OF_FIELD_FLAG) {
        //generate NUM_RAYS random rays around the position
//        printf(" >>>>>>> ADDING DEPTH OF FIELD <<<<<<<<< \n");
        for (int di = 0; di < NUM_RAYS; di++) {
            //generate a random number within 5 pixel radius
            float du = rand()/float(RAND_MAX+1);//generating random number
            float dv = rand()/float(RAND_MAX+1);

            // creating new camera position(or ray start using jittering)
            float x = imagePlane[0] + du;
            float y = imagePlane[1] + dv;
            float z = imagePlane[2];
            //set the new pixel at the imagePlane
            Point3D blurr_img = Point3D(x, y, z);
            ray.origin = viewToWorld * blurr_img;
            ray.dir = ray.origin - eye;
            ray.dir.normalize();
            // create ray from eye to place in image plane
            col = col + shadeRay(ray, 0, 0);
        }
        //normalize for NUM_RAYS pixel colours
        double col_r = col[0]/ NUM_RAYS;
        double col_g = col[1]/ NUM_RAYS;
        double col_b = col[2]/ NUM_RAYS;
        col = Colour(col_r, col_g, col_b);
    } else {
        // shade pixel based on ray data
        col = shadeRay(ray, 0, 0);
    }

    return col;
}
예제 #2
0
Colour Raytracer::anti_aliasing_helper(Point3D img_plane, Matrix4x4 view_to_world)
{
    Point3D origin(0,0,0);
    Ray3D ray;

    ray.origin = view_to_world * origin;

    ray.dir = view_to_world * img_plane - ray.origin;

    ray.dir.normalize();

    return shadeRay(ray);
}
예제 #3
0
void Raytracer::render( int width, int height, Point3D eye, Vector3D view,
		Vector3D up, double fov, char* fileName ) {
	Matrix4x4 viewToWorld;
	_scrWidth = width;
	_scrHeight = height;
	double factor = (double(height)/2)/tan(fov*M_PI/360.0);

	initPixelBuffer();
	viewToWorld = initInvViewMatrix(eye, view, up);
	//std::cout<<viewToWorld<<std::endl;
	// Construct a ray for each pixel.
	for (int i = 0; i < _scrHeight; i++) {
		for (int j = 0; j < _scrWidth; j++) {

				Colour col;

				if (antiAliasing) {
								col = anti_aliasing(viewToWorld, width, height, factor, i, j);
				}
				else	{
						// Sets up ray origin and direction in view space,
						// image plane is at z = -1.
						Point3D origin(0, 0, 0);
						Point3D imagePlane;
						imagePlane[0] = (-double(width)/2 + 0.5 + j)/factor;
						imagePlane[1] = (-double(height)/2 + 0.5 + i)/factor;
						imagePlane[2] = -1;
						Vector3D _dir (imagePlane[0],imagePlane[1],imagePlane[2]);
						Vector3D dir = viewToWorld * _dir;
						origin = viewToWorld * origin;;
						// TODO: Convert ray to world space and call
						// shadeRay(ray) to generate pixel colour.
						Ray3D ray;
						ray.origin = origin;
						ray.dir = dir;

						Colour col = shadeRay(ray);

						//std:: cout << "i:" <<i << "j:" << j <<"Hit: "<<ray.intersection.none<<std::endl;
					}

			_rbuffer[i*width+j] = int(col[0]*255);
			_gbuffer[i*width+j] = int(col[1]*255);
			_bbuffer[i*width+j] = int(col[2]*255);
		}
	}

	flushPixelBuffer(fileName);
}
예제 #4
0
void Raytracer::render( int width, int height, Point3D eye, Vector3D view, 
		Vector3D up, double fov, char* fileName) {
	Matrix4x4 viewToWorld;
	_scrWidth = width;
	_scrHeight = height;
	double factor = (double(height)/2)/tan(fov*M_PI/360.0);

	initPixelBuffer();
	viewToWorld = initInvViewMatrix(eye, view, up);

	// Construct a ray for each pixel.
	for (int i = 0; i < _scrHeight; i++) {
		for (int j = 0; j < _scrWidth; j++) {
			//perform antialiasing with a factor of 4 so ray is computed 4 times at a pixel
			//and multiplied by factor 1/4 and summed together for antialiased image
			 for(float fragmenti = i; fragmenti < i + 1.0f; fragmenti += 0.5f){
				for(float fragmentj = j; fragmentj < j + 1.0f; fragmentj += 0.5f){
					// Sets up ray origin and direction in view space, 
					// image plane is at z = -1.
					Point3D origin(0, 0, 0);
					Point3D imagePlane;
					imagePlane[0] = (-double(width)/2 + 0.5 + fragmentj)/factor;
					imagePlane[1] = (-double(height)/2 + 0.5 + fragmenti)/factor;
					imagePlane[2] = -1;

					// TODO: Convert ray to world space and call 
					// shadeRay(ray) to generate pixel colour. 
					//multiply each ray by 1/4	
					float coef = 0.25f; 
					Ray3D ray;
					// want ray to be in world frame
					ray.origin = viewToWorld*origin;
					ray.dir = viewToWorld*(imagePlane-origin);
					ray.dir.normalize();

					Colour col = shadeRay(ray); 
					//now sum the total contributions from 4 rays per pixel
					_rbuffer[i*width+j] += int(col[0]*255*coef);
					_gbuffer[i*width+j] += int(col[1]*255*coef);
					_bbuffer[i*width+j] += int(col[2]*255*coef);
				}
			}
		}
	}

	flushPixelBuffer(fileName);
}
예제 #5
0
void Raytracer::render( int width, int height, Point3D eye, Vector3D view,
        Vector3D up, double fov, std::string fileName ) {
    computeTransforms(_root);
    Matrix4x4 viewToWorld;
    _scrWidth = width;
    _scrHeight = height;
    double factor = (double(height)/2)/tan(fov*M_PI/360.0);

    initPixelBuffer();
    viewToWorld = initInvViewMatrix(eye, view, up);

    // Construct a ray for each pixel.
    for (int i = 0; i < _scrHeight; i++) {
      for (int j = 0; j < _scrWidth; j++) {
        // Sets up ray origin and direction in view space,
        // image plane is at z = -1.
        Point3D origin(0., 0., 0.);
				Point3D imagePlane;
				imagePlane[0] = (-double(width)/2 + 0.5 + j)/factor;
				imagePlane[1] = (-double(height)/2 + 0.5 + i)/factor;
				imagePlane[2] = -1;

				// TODO: Convert ray to world space and call
				// shadeRay(ray) to generate pixel colour.

				// ray -> world space
				Point3D rayOriginWorld = viewToWorld * imagePlane;
				Vector3D rayDir = imagePlane - origin;
				Vector3D rayDirWorld = viewToWorld * rayDir;

				Ray3D ray;

				ray.origin = rayOriginWorld;
				ray.dir = rayDirWorld;
				ray.dir.normalize();

				// pixel colour
				Colour col = shadeRay(ray);

				_rbuffer[i*width+j] = int(col[0]*255);
				_gbuffer[i*width+j] = int(col[1]*255);
				_bbuffer[i*width+j] = int(col[2]*255);
			}
		}

	flushPixelBuffer(fileName);
}
예제 #6
0
void Raytracer::render( int width, int height, Point3D eye, Vector3D view, 
			Vector3D up, double fov, char* fileName, char mode ) {
	Matrix4x4 viewToWorld;
	_scrWidth = width;
	_scrHeight = height;
	double factor = (double(height)/2)/tan(fov*M_PI/360.0);

	initPixelBuffer();
	viewToWorld = initInvViewMatrix(eye, view, up);

	// Construct a ray for each pixel.
	for (int i = 0; i < _scrHeight; i++) {
		for (int j = 0; j < _scrWidth; j++) {
			// Sets up ray origin and direction in view space, 
			// image plane is at z = -1.
			Point3D origin(0, 0, 0);
			Point3D imagePlane;
			imagePlane[0] = (-double(width)/2 + 0.5 + j)/factor;
			imagePlane[1] = (-double(height)/2 + 0.5 + i)/factor;
			imagePlane[2] = -1;

			// TODO: Convert ray to world space and call 
			// shadeRay(ray) to generate pixel colour. 		

			/////////////////////// OUR CODE ///////////////////////////////
			
			Vector3D d = Vector3D(imagePlane[0], imagePlane[1], imagePlane[2]);
			d = viewToWorld*d;
			origin = viewToWorld*origin;
			Ray3D ray = Ray3D( origin , d );
			if (mode == 'd'){
			  (*(ray.intersection.mat)).specular = Colour(0,0,0);
			}
			Colour col;
			col = shadeRay(ray, mode); 
			/////////////////////// OUR CODE ///////////////////////////////
			_rbuffer[i*width+j] = int(col[0]*255);
			_gbuffer[i*width+j] = int(col[1]*255);
			_bbuffer[i*width+j] = int(col[2]*255);
		}
	}

	flushPixelBuffer(fileName);
}
예제 #7
0
Colour Raytracer::shadeRay( Ray3D& ray ) {
	Colour col(0.0, 0.0, 0.0); 

	traverseScene(_root, ray); 
	
	// Don't bother shading if the ray didn't hit 
	// anything.
	if (!ray.intersection.none) {
		computeShading(ray);

        // You'll want to call shadeRay recursively (with a different ray, 
    	// of course) here to implement reflection/refraction effects.  
        float dampFactor = 0.0;

        // Calculate reflection ray
        Vector3D N = ray.intersection.normal;
        Vector3D D = ray.dir;
        Vector3D reflectionDir = -2*(D.dot(N))*N + D;
        reflectionDir.normalize();
        Point3D reflectionOrigin = ray.intersection.point + 0.01*reflectionDir;
        Ray3D reflectionRay = Ray3D(reflectionOrigin, reflectionDir);

        // calculate shade of reflected ray
        shadeRay(reflectionRay);

        // limit effective distance of reflections
        if (reflectionRay.intersection.t_value > 10.0 || reflectionRay.intersection.t_value <= 0.0) {
            col = ray.col;
        }
        else {
        dampFactor = fabs(1.0/reflectionRay.intersection.t_value);
        // contraint dampFactor to 0-0.9
        dampFactor = fmax(0, fmin(dampFactor,0.9));
        // Set colour to include reflection
        col = ray.col + dampFactor*reflectionRay.col;
        }

        col.clamp();
	}
	return col; 
}	
예제 #8
0
void Raytracer::render( int width, int height, Point3D eye, Vector3D view, 
		Vector3D up, double fov, char* fileName ) {
	Matrix4x4 viewToWorld;
	_scrWidth = width;
	_scrHeight = height;
	double factor = (double(height)/2)/tan(fov*M_PI/360.0);

	initPixelBuffer();
	viewToWorld = initInvViewMatrix(eye, view, up);

	// Construct a ray for each pixel.
	for (int i = 0; i < _scrHeight; i++) {
		for (int j = 0; j < _scrWidth; j++) {
			// Sets up ray origin and direction in view space, 
			// image plane is at z = -1.
			Point3D origin(0, 0, 0);
			Point3D imagePlane;
			imagePlane[0] = (-double(width)/2 + 0.5 + j)/factor;
			imagePlane[1] = (-double(height)/2 + 0.5 + i)/factor;
			imagePlane[2] = -1;

			// TODO: Convert ray to world space and call 
			// shadeRay(ray) to generate pixel colour. 	
		    Point3D ray_origin = viewToWorld * imagePlane;
            Vector3D ray_dir = ray_origin - eye;    
			Ray3D ray(ray_origin, ray_dir);

			Colour col = shadeRay(ray); 

			_rbuffer[i*width+j] = int(col[0]*255);
			_gbuffer[i*width+j] = int(col[1]*255);
			_bbuffer[i*width+j] = int(col[2]*255);
		}
	}

	flushPixelBuffer(fileName);
}
예제 #9
0
Colour Raytracer::shadeRay( Ray3D& ray, int depth ) {
	Colour col(0.0, 0.0, 0.0); 
	traverseScene(_root, ray); 
	
	Ray3D r;

	// Don't bother shading if the ray didn't hit 
	// anything.


	if (!ray.intersection.none) {
		computeShading(ray);
		col = ray.col;
		if (depth > 1) {
			if (ray.intersection.mat->specular_exp > 20) {
				Vector3D n = ray.intersection.normal;
				n.normalize();
				r.origin = ray.intersection.point;
				Vector3D refl = (-2 * ray.dir.dot(n)) * n + ray.dir;
				r.dir = refl;
				r.dir.normalize();
				r.col = shadeRay(r, depth-1);
				
				col = col + r.col;
				col.clamp();
			}
		}
	}



	// You'll want to call shadeRay recursively (with a different ray, 
	// of course) here to implement reflection/refraction effects.  

	return col; 
}	
예제 #10
0
void Raytracer::render( int width, int height, Point3D eye, Vector3D view,
                        Vector3D up, double fov, int AA_level, char* fileName, char renderStyle ) {
    Matrix4x4 viewToWorld;
    _scrWidth = width;
    _scrHeight = height;
    double factor = (double(_scrHeight)/2)/tan(fov*M_PI/360.0);

    initPixelBuffer();
    viewToWorld = initInvViewMatrix(eye, view, up);

    /**
     * Extension: Anti-aliasing level via supersampling method
     * Algorithm:
     * Generate an image of dimensions equal to a multiple of the original
     * dimensions (as specified by the AA level)
     * Then sample individual pixels and average them to compose a pixel
     * on the actual screen
     */
    _aaLevel = AA_level;
    initSuperPixelBuffer();

    /// A little print for the user
    fprintf(stderr, "Rendering %dx%d scene, AA-level %d\n", _scrWidth,
            _scrHeight, _aaLevel);

    int superi, superj;
    double offi, offj;
    // Construct a ray for each pixel.
    for (int i = 0; i < _scrHeight; i++) {
        for (int j = 0; j < _scrWidth; j++) {
            // Prepare to supersample for anti aliasing
            for (int m = 0; m < _aaLevel; m++) {
                for (int n = 0; n < _aaLevel; n++) {

                    // Sets up ray origin and direction in view space,
                    // image plane is at z = -1.
                    Point3D origin(0, 0, 0);
                    Point3D imagePlane;
                    offj = double(1)/(0.5 * _aaLevel) + double(n)/_aaLevel;
                    offi = double(1)/(0.5 * _aaLevel) + double(m)/_aaLevel;
                    imagePlane[0] = (-double((_scrWidth))/2 + offj + j)/factor;
                    imagePlane[1] = (-double((_scrHeight))/2 + offi + i)/factor;
                    imagePlane[2] = -1;

                    // Create the transformed ray and shoot it out (shadeRay)
                    Vector3D pixelVector = Vector3D(imagePlane[0], imagePlane[1],
                                                    imagePlane[2]);
                    Vector3D transformedPixelVector = viewToWorld * pixelVector;
                    Point3D transformedOrigin = viewToWorld * origin;

                    Ray3D ray = Ray3D(transformedOrigin, transformedPixelVector);

                    //Check for scene render style
                    Colour col = shadeRay(ray, renderStyle);

                    superi = i*_aaLevel + m;
                    superj = j*_aaLevel + n;

                    _superrbuffer[superi*(_aaLevel*_scrWidth)+superj] = int(col[0]*255);
                    _supergbuffer[superi*(_aaLevel*_scrWidth)+superj] = int(col[1]*255);
                    _superbbuffer[superi*(_aaLevel*_scrWidth)+superj] = int(col[2]*255);

                }
            }//End supersampling loop
        }
    }//finsihed pixel loop

    // Now average out the pixels from the super buffer (supersampling)
    factor = double(1)/(_aaLevel * _aaLevel);
    unsigned long rtemp;
    unsigned long gtemp;
    unsigned long btemp;
    for (int i = 0; i < _scrHeight; i++) {
        for (int j = 0; j < _scrWidth; j++) {
            rtemp = 0;
            gtemp = 0;
            btemp = 0;
            for (int m = 0; m < _aaLevel; m++) {
                superi = i*_aaLevel + m;
                for (int n = 0; n < _aaLevel; n++) {
                    superj = j*_aaLevel + n;

                    rtemp += _superrbuffer[superi*(_aaLevel*_scrWidth)+superj];
                    gtemp += _supergbuffer[superi*(_aaLevel*_scrWidth)+superj];
                    btemp += _superbbuffer[superi*(_aaLevel*_scrWidth)+superj];
                }
            }
            _rbuffer[i*_scrWidth+j] = factor * rtemp;
            _gbuffer[i*_scrWidth+j] = factor * gtemp;
            _bbuffer[i*_scrWidth+j] = factor * btemp;
        }
    }

    flushPixelBuffer(fileName);
}
예제 #11
0
Colour Raytracer::shadeRay( Ray3D& ray, char renderStyle ) {
    Colour col(0.0, 0.0, 0.0);
    traverseScene(_root, ray);

    // Don't bother shading if the ray didn't hit
    // anything.
    if (!ray.intersection.none) {
        //computeShading(ray);
        if (renderStyle != 's') {
            computeShading(ray, renderStyle);
            col = ray.col;

#ifdef USE_REFLECTIONS
            if ((ray.intersection.mat->reflectivity >= 0.01) && (ray.reflections < MAX_REFLECTIONS) && (renderStyle != 'd')) {
                // emit another ray
                Vector3D n = ray.intersection.normal;
                n.normalize();
                Vector3D d = ray.dir;
                d.normalize();



                double dot = n.dot(d);
                Vector3D newdir = d - (2 * dot * n);

                Ray3D newRay = Ray3D(ray.intersection.point + 0.01*newdir,
                                     newdir, ray.reflections+1, ray.refractions, ray.cLight);
                Colour secondaryColour = shadeRay(newRay, renderStyle);


                double ref = ray.intersection.mat->reflectivity;
                col = (1-ref)*ray.col + ref*secondaryColour;
            } else {
                col = ray.col;
            }
#else
            col = ray.col;
#endif
            // Check for refractions
            // Don't check for refractions of reflected rays
#ifdef USE_REFRACTIONS
            if((ray.intersection.mat->transitivity >= 0.1) && (ray.refractions < MAX_REFRACTIONS) && (renderStyle != 'd')) {
                double c1 = ray.cLight;
                double c2 = ray.intersection.mat->cLight;
                if (ray.cLight < 0.99) { //Ray leaves object to air/vacuum
                    c2= 1;
                }


                Vector3D n = ray.intersection.normal;
                n.normalize();
                Vector3D d = ray.dir;
                d.normalize();

                double dot = n.dot(d);
                Vector3D reflDir = d - (2 * dot * n);
                reflDir.normalize();

                //Now determine refraction direction
                //Depends on reflDir, c1, c2, n, as specified in the relation below
                double theta1 = acos( n.dot(-d) );
                if(dot > 0 ) { //Ray is leaving object
                    theta1 = acos( n.dot(d) );
                }
                double theta2 = asin(c2*sin(theta1)/c1);

                //Check for critical angle

                // Compute refraction direction
                Vector3D refractDir = (c2/c1)*ray.dir + ( (c2/c1)*cos(theta1) - cos(theta2))*n;
                if(dot > 0 ) { //Ray is leaving object     =====================changed sign
                    refractDir = (c2/c1)*ray.dir - ( (c2/c1)*cos(theta1) - cos(theta2))*n;
                }

                refractDir.normalize();

                Ray3D refractRay = Ray3D(ray.intersection.point + 0.0001*refractDir, refractDir,ray.reflections, ray.refractions+1, c2 );


                Colour colRefract = shadeRay(refractRay, renderStyle);
                double matTran = ray.intersection.mat->transitivity;
                if(!refractRay.intersection.none) { //Refracted ray does not go off into space
                    col = (1-matTran)*col + matTran*colRefract;
                }
            }//end of refractions
#endif

        }//End of check if(renderStyle != 's')
        else { //renderStyle == 's'
            col = (*(ray.intersection.mat)).diffuse;
        }
    }//End of check if (!ray.intersection.none)

    return col;
}// End of shadeRay
예제 #12
0
gml::vec3_t Scene::shadeRay(const RayTracing::Ray_t &ray, RayTracing::HitInfo_t &hitinfo, const int remainingRecursionDepth) const
{
	// TODO!

	// Calculate the shade/radiance/color of the given ray. Return the calculated color
	//  - Information about the ray's point of nearest intersection is located
	// in 'hitinfo'
	//  - If remainingRecursionDepth is 0, then _no_ recursive rays (mirror or indirect lighting) should be cast

	// Note: You will have to set up the values for a RayTracing::ShaderValues object, and then
	// pass the object to a shader object to do the appropriate shading.
	//   Use m_shaderManager.getShader() to get an appropriate Shader object for shading
	//  the point based on material properties of the object intersected.

	// When implementing shadows, then the direct lighting component of the
	// calculated ray color will be black if the point is in shadow.

	//ml::vec3_t shade(0.5, 0.5, 0.5);
	//RayTracing::ShaderValues sv(hitinfo.objHit->getMaterial());

	// Note: For debugging your rayIntersection() function, this function
	// returns some non-black constant color at first. When you actually implement
	// this function, then initialize shade to black (0,0,0).

	gml::vec3_t shade(0.0, 0.0, 0.0);
	gml::vec2_t texCoord;
	gml::vec3_t normal;

	hitinfo.objHit->hitProperties(hitinfo, normal, texCoord);

	RayTracing::ShaderValues shaderVal(hitinfo.objHit->getMaterial());
	shaderVal.n = normal;
	shaderVal.p = gml::add(ray.o, gml::scale(hitinfo.hitDist, ray.d));
	shaderVal.e = gml::normalize(gml::scale(-1.0f, ray.d));
	shaderVal.tex = texCoord;
	shaderVal.lightDir = gml::normalize(gml::sub(gml::extract3(m_lightPos), shaderVal.p));
	shaderVal.lightRad = m_lightRad;

	float distToLight = gml::length(gml::sub(gml::extract3(m_lightPos), shaderVal.p));

	// test if in shadow
	RayTracing::Ray_t shadowRay;
	shadowRay.o = shaderVal.p;
	shadowRay.d = shaderVal.lightDir;
	if (!shadowsRay(shadowRay, 0.001, distToLight))
	{
			// direct lighting
			shade = m_shaderManager.getShader(hitinfo.objHit->getMaterial())->shade(shaderVal);
	}
	else
	{
			shade = gml::vec3_t(0,0,0);

	}



	// Only proceed if the recursion depth limit has not been met.
	if (remainingRecursionDepth > 0)
	{
			// Mirror checks, and shading.
			if (hitinfo.objHit->getMaterial().isMirror())
			{
					// Ray for mirrors.
					RayTracing::Ray_t mirrorRay;
					mirrorRay.o = shaderVal.p;
					mirrorRay.d = gml::normalize(gml::scale(-1, gml::reflect(ray.d, normal)));

					RayTracing::HitInfo_t mirrorHitInfo;

					// If intersection, get the mirror shading color and apply it.
					if (this->rayIntersects(mirrorRay, 0.001f, FLT_MAX, mirrorHitInfo))
					{
							gml::vec3_t mirrorShade = shadeRay(mirrorRay, mirrorHitInfo, remainingRecursionDepth - 1);
							shade = gml::add(shade, gml::mul(hitinfo.objHit->getMaterial().getMirrorRefl(), mirrorShade));
					}
			}

			// Setup indirect lighting.
			RayTracing::Ray_t indirectRay;
			indirectRay.o = shaderVal.p;
			indirectRay.randomDirection(shaderVal.n);

			RayTracing::HitInfo_t indirectHitInfo;

			// If intersection, apply indirect ray for indirect lighting.
			if (this->rayIntersects(indirectRay, 0.001f, FLT_MAX, indirectHitInfo))
			{

					shaderVal.lightDir = indirectRay.d;
					shaderVal.lightRad = shadeRay(indirectRay, indirectHitInfo, remainingRecursionDepth - 1);

					gml::vec3_t indirectShade = m_shaderManager.getShader(hitinfo.objHit->getMaterial())->shade(shaderVal);

					// Add together to the cumulative color.
					shade = gml::add(shade, indirectShade);
			}
	}

	// Note: For debugging your rayIntersection() function, this function
	// returns some non-black constant color at first. When you actually implement
	// this function, then initialize shade to black (0,0,0).

	// Return the cumulative color for the point.
	return shade;

}
예제 #13
0
void Raytracer::render( int width, int height, Point3D eye, Vector3D view, 
		Vector3D up, double fov, const char* fileName ) {
    /*****************anti-aliasing************************/
    Matrix4x4 viewToWorld;
    _scrWidth = width;
    _scrHeight = height;
    double factor = (double(height)/2)/tan(fov*M_PI/360.0);
    Colour totalCol(0.0,0.0,0.0);
    
    initPixelBuffer();
    viewToWorld = initInvViewMatrix(eye, view, up);
    scfCache(_root);
    // Construct a ray for each pixel.
    
    for (int i = 0; i < _scrHeight; i++) {
        for (int j = 0; j < _scrWidth; j++) {
            //anti-aliasing, each pixel can have 4 rays, the pixel color determined by the avgerage
            for(double a = i; a < i+1 ; a += 0.5){
                for(double b = j; b < j+1;b += 0.5){
                    
                    // Sets up ray origin and direction in view space,
                    // image plane is at z = -1.
                    Point3D origin(0, 0, 0);
                    Point3D imagePlane;
                    imagePlane[0] = (-double(width)/2 + 0.5 + b)/factor;
                    imagePlane[1] = (-double(height)/2 + 0.5 + a)/factor;
                    imagePlane[2] = -1;
                    
                    // TODO: Convert ray to world space and call
                    // shadeRay(ray) to generate pixel colour.
                    Point3D originW = viewToWorld * imagePlane;
                    Vector3D directionW = viewToWorld * (imagePlane -origin);
                    directionW.normalize();
                    
                    Ray3D ray(originW, directionW);
                    Colour col = shadeRay(ray,0,0);
                    
                    //each ray contributed 0.25 color to the final rending color for the pixel
                    _rbuffer[i*width+j] += int(col[0]*255*0.25);
                    _gbuffer[i*width+j] += int(col[1]*255*0.25);
                    _bbuffer[i*width+j] += int(col[2]*255*0.25);
                }
            }
        }
    
    }
/********************anti-aliasing**************************/
   
//	Matrix4x4 viewToWorld;
//	_scrWidth = width;
//	_scrHeight = height;
//	double factor = (double(height)/2)/tan(fov*M_PI/360.0);
//
//	initPixelBuffer();
//	viewToWorld = initInvViewMatrix(eye, view, up);
//    scfCache(_root);
//	// Construct a ray for each pixel.
//	for (int i = 0; i < _scrHeight; i++) {
//		for (int j = 0; j < _scrWidth; j++) {
//			// Sets up ray origin and direction in view space, 
//			// image plane is at z = -1.
//			Point3D origin(0, 0, 0);
//			Point3D imagePlane;
//			imagePlane[0] = (-double(width)/2 + 0.5 + j)/factor;
//			imagePlane[1] = (-double(height)/2 + 0.5 + i)/factor;
//			imagePlane[2] = -1;
//
//			// TODO: Convert ray to world space and call 
//			// shadeRay(ray) to generate pixel colour.
//            
//            //Vector3D dir = imagePlane-origin;
//            Ray3D ray(origin,imagePlane-origin);
//            /*my dode here*/
//            ray.origin = viewToWorld*ray.origin;
//            ray.dir = viewToWorld*ray.dir;
//            ray.dir.normalize();
//			Colour col = shadeRay(ray,0,0);//the original is shadeRay(ray)
//
//			_rbuffer[i*width+j] = int(col[0]*255);
//			_gbuffer[i*width+j] = int(col[1]*255);
//			_bbuffer[i*width+j] = int(col[2]*255);
//		}
//	}

	flushPixelBuffer(fileName);
}
예제 #14
0
// After intersection, calculate the colour of the ray by shading it
// with all light sources in the scene.
Colour Raytracer::shadeRay( Ray3D& ray,int times_reflec,int times_refrac ) {//(reflection)*   shadeRay
	Colour col(0.0, 0.0, 0.0);
    
	traverseScene(_root, ray);
    
    //for reflextion here
    
	// Don't bother shading if the ray didn't hit 
	// anything.
//	if (!ray.intersection.none) {
//		computeShading(ray); 
//		col = ray.col;  
//	}
//    return col;
    
    /*******************Reflection&Refraction********************/
    Colour reflColour(0.0, 0.0, 0.0);
    Colour refraColour;
    if (!ray.intersection.none) {
        computeShading(ray);
        col = ray.col*Colour((1-ray.intersection.mat->transparency_coef), (1-ray.intersection.mat->transparency_coef), (1-ray.intersection.mat->transparency_coef));
        //for flection
        if(times_reflec < 3 && ray.intersection.mat->reflect_coef != 0&&ray.intersection.mat->transparency_coef==0){
            Ray3D reflect_ray;
            reflect_ray.dir = ray.dir - (2 * (ray.dir.dot(ray.intersection.normal)) * ray.intersection.normal);
            reflect_ray.dir.normalize();
            reflect_ray.origin = ray.intersection.point+(1e-6) * reflect_ray.dir;
            
            
            times_reflec = times_reflec + 1;
            //Colour refl = shadeRay(reflect_ray,times);
            reflColour = reflColour + ray.intersection.mat->reflect_coef*shadeRay(reflect_ray,times_reflec,times_reflec);
        }
        //for refraction
        if(times_refrac<3&&ray.intersection.mat->transparency_coef>0){
            Ray3D refraction_ray;
            double n;
            Vector3D N =ray.intersection.normal;
            if(ray.intersection.insideCrash){
                n =ray.intersection.mat->R_index;
                N = (-1)*N;
            }else{
                n=1/ray.intersection.mat->R_index;
                
            }
            double cosI = (-1.0)*N.dot(ray.dir);
            double cosT2 = 1.0 - (n*n)*(1.0- cosI*cosI );
            if(cosT2>0.0){//whether can have refraction or not
                
                double cosT = sqrt(cosT2);
                //  double tmp1 = sqrt(1.0-(R_index*ray.dir.dot(ray.intersection.normal)*ray.dir.dot(ray.intersection.normal)));
                refraction_ray.dir =n*ray.dir+(n*cosI-cosT)*N;
                
                refraction_ray.dir.normalize();
                //refraction_ray.dir =n*ray.dir+(n*tmp2-tmp1)*(ray.intersection.normal);
                refraction_ray.origin = ray.intersection.point+(1e-6)*refraction_ray.dir;
                times_refrac++;
                refraColour = refraColour+ray.intersection.mat->transparency_coef*shadeRay(refraction_ray,  times_refrac, times_refrac);
            }
            
            }
    }
    
    
    col = col + reflColour+refraColour;
    col.clamp();
    
    return col;
     /***************END OF Reflection&Refraction***********************/
    
    /*******************Reflection********************
    Colour reflColour(0.0, 0.0, 0.0);
     if (!ray.intersection.none) {
     computeShading(ray);
     col = ray.col;
     if(times < 3 && ray.intersection.mat->reflect_coef != 0){
     Ray3D reflect_ray;
     
     reflect_ray.dir = ray.dir - (2 * (ray.dir.dot(ray.intersection.normal)) * ray.intersection.normal);
     reflect_ray.dir.normalize();
     reflect_ray.origin = ray.intersection.point+(1e-6) * reflect_ray.dir;
     
     times = times + 1;
     //Colour refl = shadeRay(reflect_ray,times);
     reflColour = reflColour + ray.intersection.mat->reflect_coef*shadeRay(reflect_ray,times);
     }
     }
     col = col + reflColour;
     col.clamp();
     
     return col;
    ***************END OF Reflection***********************/
    /*******************Glossy********************
    Colour reflColour(0.0, 0.0, 0.0);
     
     if (!ray.intersection.none) {
     computeShading(ray);
     col = ray.col;
     if (times < 3 && ray.intersection.mat->reflect_coef != 0) {
     
     Ray3D reflect_ray;
     reflect_ray.dir = (ray.dir - ((2*(ray.dir.dot(ray.intersection.normal)))*ray.intersection.normal));
     reflect_ray.dir.normalize();
     reflect_ray.origin = ray.intersection.point + 1e-6*reflect_ray.dir;
     
     double L = 0.5; // roughness
     
     for (int i = 0; i < 4; i++) {
     //r(i) = normalize(r+(0.5-xi)Lu + (0.5-yi)Lv)
     double xi = (double)rand() / (double)RAND_MAX;
     double yi = (double)rand() / (double)RAND_MAX;
     
     reflect_ray.dir[0] += (0.5-xi)*L;
     reflect_ray.dir[1] += (0.5-yi)*L;
     
     reflect_ray.dir.normalize();
     
     times = times + 1;
     reflColour = reflColour + ray.intersection.mat->reflect_coef*shadeRay(reflect_ray , times);
     }
     reflColour = (1.0/4.0)*reflColour;
     }
     col = col + reflColour;
     col.clamp();
     }
     
     return col;
    ****************END OF GLOSSY********************************/
    
	// You'll want to call shadeRay recursively (with a different ray,
	// of course) here to implement reflection/refraction effects.  ...........................

	
}
예제 #15
0
void Raytracer::render( int width, int height, Point3D eye, Vector3D view, 
		Vector3D up, double fov, char* fileName, int aa, int fl, bool dof ) {
	Matrix4x4 viewToWorld;

	width = width * aa;
	height = height * aa;
	double factor = (double(height)/2)/tan(fov*M_PI/360.0);

	viewToWorld = initInvViewMatrix(eye, view, up);

	initAABuffer(aa, width, height);

	_scrWidth = width / aa;
	_scrHeight = height / aa;

	initPixelBuffer();

	// Construct a ray for each pixel.
	for (int i = 0; i < height; i++) {
		for (int j = 0; j < width; j++) {
			// Sets up ray origin and direction in view space, 
			// image plane is at z = -1.
			Point3D origin(0, 0, 0);
			Point3D imagePlane;
			imagePlane[0] = (-double(width)/2 + 0.5 + j)/factor;
			imagePlane[1] = (-double(height)/2 + 0.5 + i)/factor;
			imagePlane[2] = -1;
			
			Ray3D ray;

			ray.origin = viewToWorld * origin;
            ray.dir = viewToWorld * imagePlane - ray.origin;
			ray.dir.normalize();
			Colour col(0,0,0);

			//implement depth of field if true
			if (dof == true) {
				//generate a point in the scene as part of the focal plane
				Vector3D pointAimed = (ray.origin + fl * ray.dir) - Point3D(0,0,0);
				float r = 1;
				Colour pc(0,0,0);

				for (int px=0; px < 15; px++) {
					float du = ((float) rand())/(float(RAND_MAX));
					float dv = ((float) rand())/(float(RAND_MAX));
					//x and y axis of camera/eye
					Vector4D u = viewToWorld.getColumn(1);
					Vector4D v = viewToWorld.getColumn(0);
					//convert them to 3d vectors;
					Vector3D u2(u[0],u[1],u[2]);
					Vector3D v2(v[0],v[1],v[2]);
					//convert ray.origin to vector for vector operation;
					Vector3D tempv(ray.origin[0], ray.origin[1], ray.origin[2]);
					//generate random point around the eye (vector is used for operation)
					Vector3D eyev = tempv - (r/2)*u2 - (r/2)*v2 + r*(du)*u2 + r*(dv)*v2;
					//generate a ray from random point to pointAimed
					Ray3D dovr;
					dovr.dir = pointAimed - eyev;
					dovr.origin = Point3D(eyev[0], eyev[1], eyev[2]);
					dovr.dir.normalize();
					//bounce ray into the scene and get its color
					Colour dovCol = shadeRay(dovr, 2);
					pc = pc + dovCol;

				}
				//average the pixel colors to get the blurriness effect
				col = (1/15.0) * pc;
			} else {
				col = shadeRay(ray, 2);
			}
			col.clamp();

			if (aa == 1) {
				_rbuffer[i*width+j] = int(col[0]*255);
				_gbuffer[i*width+j] = int(col[1]*255);
				_bbuffer[i*width+j] = int(col[2]*255);
			} else {
				re[i*width+j] = int(col[0]*255);
				gr[i*width+j] = int(col[1]*255);
				bl[i*width+j] = int(col[2]*255);
			}

		}
	}

	if (aa == 1) {
		flushPixelBuffer(fileName);
	} else {
		aarender(width, height, aa, fileName);
		delete re;
		delete gr;
		delete bl;
	}
}
예제 #16
0
Colour Raytracer::shadeRay( Ray3D& ray, int reflectionDepth, int refractionDepth ) {
    Colour col(0.0, 0.0, 0.0);
    traverseScene(_root, ray);

    // Don't bother shading if the ray didn't hit
    // anything.
    if (REFRACTION_FLAG_DEBUG) {
        printf("\n\n            checking intersection       \n");
        printf("          incident ray: (%f, %f, %f) \n", ray.dir[0], ray.dir[1], ray.dir[2]);
    }

    Intersection inter = ray.intersection;
    if ( !inter.none ) {
        computeShading(ray);
        if (REFRACTION_FLAG_DEBUG) {
            printf("\n\n    ----------------------  INTERSECTION WITH OBJECT ------------------------------   \n\n");
        }

        //Spawn a ray for reflection
        if ( reflectionDepth < getReflDepth() ) {
            Vector3D n = inter.normal;
            Vector3D de = -ray.dir;
            Vector3D m = 2 * de.dot(n) * n - de; // reflect across normal

            // http://www.cdf.toronto.edu/~moore/csc418/Notes/Phong.pdf
            // reflection
            if ( inter.mat->refl_amt > 0.0f ) {
                if (REFRACTION_FLAG_DEBUG) {
                    printf("\n\n     ........  DOING REFLECTION ........   \n");
                }

                Ray3D refl_ray;
                refl_ray.origin = inter.point;// + (DBL_0_UPPER * m);
                refl_ray.dir = m;

                Colour rCol(0.0, 0.0, 0.0);
                rCol = shadeRay(refl_ray, reflectionDepth + 1, refractionDepth);

                ray.col = ray.col + (inter.mat->refl_amt * rCol);
            }

            // Spawn a seperate ray for refraction
            if ( inter.mat->transparency > 0.0f ) {
                double th_1 = std::abs(de.dot(n));

                double c1, c2;
                if ( th_1 >= 0 ) {
                    c1 = inter.mat->IOR;
                    c2 = ray._cur_speed;

                    ray._cur_speed = c1;
                } else {
                    c2 = inter.mat->IOR;
                    c1 = ray._cur_speed;

                    ray._cur_speed = c2;
                }

                double IOR = c2 / c1;
                //				double IOR = 1; // will make it transparent, for testing

                double th_2 = sqrt(1.0 - (IOR * IOR) * (1.0 - (th_1 * th_1)));

                Ray3D refr_ray;
                refr_ray.dir = -de + IOR * (th_1 * n) + (-th_2 * n);
                refr_ray.origin = (inter.point) + (DBL_EPSILON * refr_ray.dir);

                Colour rCol(0.0, 0.0, 0.0);
                rCol = shadeRay(refr_ray, reflectionDepth + 1, refractionDepth + 1);

                ray.col = ray.col + (inter.mat->transparency * rCol);
            }

        }

        col = ray.col;
    } else {
        // env map
        if ( getEnvMapMode() == ENV_MAP_CUBE_SKYBOX ) {
            col = getEnvMap().getColorForRay(ray.dir);
        }
    }

    col.clamp();
    return col;
}