Esempio n. 1
0
void DisplayClass::traceRay(glm::vec3* color, int depth, glm::vec3 P, glm::vec3 V, float currentRI, float oldRI, glm::vec3 lcol) {
	if (depth > 5) {
		color->x = rayAmbientCol->x;
		color->y = rayAmbientCol->y;
		color->z = rayAmbientCol->z;
		return;
	}
	Node* n = getIntersectionObject(P, V);
	if (n == NULL) {
		color->x = rayAmbientCol->x;
		color->y = rayAmbientCol->y;
		color->z = rayAmbientCol->z;
		return;
	}

	//find intersection
	glm::vec3 intersection = P + (((float) *n->t) * V);

	//get material
	float* mt;
	switch(*n->mtl) {
	case 1:
		mt = mtl1;
		break;
	case 2:
		mt = mtl2;
		break;
	case 3:
		mt = mtl3;
		break;
	case 4:
		mt = mtlf;
		break;
	}

	glm::vec3 N = glm::normalize(*n->normal); //compute normal at intersection point
	//if (N.x < 0.0001f && N.x > -0.0001f && N.y < 0.0001f && N.y > -0.0001f && N.z < 1.0001f && N.z > 0.9999f) {
	//	std::cout << "Noisy!" << std::endl;
	//}
	glm::vec3 Rd = glm::normalize(glm::reflect(V, N)); //compute reflected ray direction
	float RI = mt[6];
	glm::vec3 Rfn = N;

	//if reflective, make recursive call
	glm::vec3 spec(0.0f, 0.0f, 0.0f);
	if (mt[4] > 0.0f) {
		glm::vec3* reflectedColor = new glm::vec3();
		traceRay(reflectedColor, depth + 1, intersection + 0.001f * Rd, Rd, currentRI, oldRI, glm::vec3(lcol.x * mt[0], lcol.y * mt[1], lcol.z * mt[2]));
		spec = *reflectedColor;
		delete reflectedColor;
	}

	glm::vec3 refr(0.0f, 0.0f, 0.0f);
	glm::vec3 Rf;
	glm::vec3 tcol;
	float insFl = -1.0f;
	if (mt[5] > 0.0f) {
		insFl = glm::dot(N, V);
		tcol = glm::vec3(lcol.x * mt[0], lcol.y * mt[1], lcol.z * mt[2]);
		if (insFl > -0.0001f) {
			Rfn = -1.0f * N;
			//tcol = lcol;
			//RI = 1.0f;
		}
		if (currentRI == 1.0f) {
			oldRI = RI;
		}
		float eta = currentRI/oldRI;
		Rf = glm::normalize(glm::refract(V, Rfn, eta));
		glm::vec3* refractedColor = new glm::vec3();
		traceRay(refractedColor, depth + 1, intersection + 0.001f * Rf, Rf, oldRI, currentRI, glm::vec3(lcol.x * mt[0], lcol.y * mt[1], lcol.z * mt[2]));
		refr = *refractedColor;
		delete refractedColor;
	}

	//ambient color
	color->x = rayAmbientCol->x * mt[0];
	color->y = rayAmbientCol->y * mt[1];
	color->z = rayAmbientCol->z * mt[2];

	//*color = *color * 0.2f;

	*color = glm::clamp(*color, 0.0f, 1.0f);
	
	if (mt[5] > 0.0f) {
		*color = *color + refr;
		*color = ((1.0f - mt[4]) * glm::clamp(*color, 0.0f, 1.0f)) + (mt[4] * glm::clamp(spec, 0.0f, 1.0f));
		/*float cosT = glm::dot(Rf, V); //2.0f * glm::dot(-1.0f * Rfn, V);
		float rcoef = glm::clamp(pow(1.0f - cosT, 5), 0.0f, 1.0f);
		*color = glm::clamp(((1.0f - rcoef) * *color) + (rcoef * tcol), 0.0f, 1.0f);*/
		return;
	}
	
	//light ray
	glm::vec3 L;
	glm::vec3 R;
	glm::vec3 finalCol;
	glm::vec3 ambientCol = *color;
	glm::vec3 totalCol(0.0f, 0.0f, 0.0f);
	for (int lc = 0; lc < 3; lc++) {
		L = glm::normalize(*rayLightPos->at(lc) - intersection);
		R = glm::reflect(-1.0f * L, N);

		//cast ray for shadow
		glm::vec3 blockob;
		Node* blocker = getIntersectionObject(*rayLightPos->at(lc), -1.0f * L);
		if (blocker != NULL) {
			blockob = *rayLightPos->at(lc) - (((float) *blocker->t) * L);
		}
		float di = glm::length(blockob - intersection);
		//if not shadowed, add more color
		if (blocker == NULL || (di < 0.0001f && di > -0.0001f)) {

			//diffuse color
			glm::vec3 diffuseColor = glm::clamp(glm::vec3(mt[0] * rayLightCol->at(lc)->x, mt[1] * rayLightCol->at(lc)->y, mt[2] * rayLightCol->at(lc)->z), 0.0f, 1.0f);

			//specular term
			float specTerm = glm::clamp(pow(glm::dot(V, R), mt[3]), 0.0f, 1.0f);

			//diffuse term
			float diffuseTerm = glm::clamp(glm::dot(N, L), 0.0f, 1.0f);

			//final color weighted calculation
			//blinn-phong
			finalCol = ambientCol + (glm::clamp(diffuseTerm * diffuseColor, 0.0f, 1.0f) * 0.6f) + (glm::clamp(spec + specTerm * *rayLightCol->at(lc), 0.0f, 1.0f) * 0.2f);
			totalCol = totalCol + finalCol;
			*color = totalCol;
		}
	}
	//reflectivity-weighted
	*color = ((1.0f - mt[4]) * glm::clamp(*color, 0.0f, 1.0f)) + (mt[4] * glm::clamp(spec, 0.0f, 1.0f));

}
Esempio n. 2
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);
}