예제 #1
0
Vec3f RayTracer::reflection(const Ray &start_ray, int bounce_count) const
{
	Ray ray(start_ray);
	Hit h;
	Vec3f answer = TraceRay(ray, h, bounce_count);
	while (h.getT() < SURFACE_EPSILON) {
		ray = Ray(ray.pointAtParameter(SURFACE_EPSILON),
				ray.getDirection());
		answer = TraceRay(ray, h, bounce_count);
	}
	return answer;
}
예제 #2
0
void RayTracer::RenderScene(Scene * scene, Camera * camera, QImage * buffer)
{
    buffer->fill(QColor(Qt::white).rgb());

    double fov   = camera->GetFOV();
    double fov_2 = fov / 2.0;

    double largestDim = std::max(camera->getXRes(), camera->getYRes());
    double cameraPlaneDist = 0.5 * largestDim * tan((90 - fov_2) * DEGREE_TO_RAD);

    // Assumes camera location is negative
    // TODO: Fix this assumption
    QVector3D cameraPlaneLocation = QVector3D(0, 0, camera->GetZPos() + cameraPlaneDist);

    int y_2 = camera->getYRes() / 2;
    int x_2 = camera->getXRes() / 2;

    QVector3D cp = QVector3D(0, 0, camera->GetZPos());

    for (int y = -y_2; y < y_2; ++y)
    {
        for (int x = - x_2; x < x_2; ++x)
        {
            // Compute the vector from the eye
            QVector3D rayDirection = QVector3D(x, y, cameraPlaneLocation.z());
            QVector3D color = TraceRay(scene, cp, rayDirection, 0);
            buffer->setPixel(x + x_2, y + y_2, qRgb(color.x() * 255, color.y()* 255, color.z() * 255));
        }
    }
}
예제 #3
0
void BeginRender()
{
	Color24 *temp;
	temp = renderImage.GetPixels();
	float *zBuffer = renderImage.GetZBuffer();
	Color materialColor;
	Color24 newColor;
	for (int i = 0; i < camera.imgWidth; i++)
	{
		for (int j = 0; j < camera.imgHeight; j++)
		{
			Ray currentRay = ComputeCameraRay(i, j);
			HitInfo hInfo;
			hInfo.Init();
			bool value = TraceRay(currentRay, hInfo, &rootNode);
			if (value) {
				hInfo.node->FromNodeCoords(hInfo);
				const Material *m = hInfo.node->GetMaterial();
				materialColor = m->Shade(currentRay, hInfo, lights);
				temp[camera.imgWidth*j + i].r = (materialColor.r)*255;
				temp[camera.imgWidth*j + i].g = (materialColor.g)*255;
				temp[camera.imgWidth*j + i].b = (materialColor.b)*255;
			}
			else {
				temp[camera.imgWidth*j + i].r = 0;
				temp[camera.imgWidth*j + i].g = 0;
				temp[camera.imgWidth*j + i].b = 0;
			}
			zBuffer[camera.imgWidth*j + i] = hInfo.z;
		}
	}
	renderImage.ComputeZBufferImage();
	renderImage.SaveImage("Output");
}
// Scan through the image from the lower left corner across each row
// and then up to the top right.  Initially the image is sampled very
// coarsely.  Increment the static variables that track the progress
// through the scans
int GLCanvas::DrawPixel() {
  if (raytracing_x > args->width) {
    raytracing_x = raytracing_skip/2;
    raytracing_y += raytracing_skip;
  }
  if (raytracing_y > args->height) {
    if (raytracing_skip == 1) return 0;
    raytracing_skip = raytracing_skip / 2;
    if (raytracing_skip % 2 == 0) raytracing_skip++;
    assert (raytracing_skip >= 1);
    raytracing_x = raytracing_skip/2;
    raytracing_y = raytracing_skip/2;
    glEnd();
    glPointSize(raytracing_skip);
    glBegin(GL_POINTS);
  }

  // compute the color and position of intersection
  Vec3f color= TraceRay(raytracing_x, raytracing_y);
  double r = linear_to_srgb(color.x());
  double g = linear_to_srgb(color.y());
  double b = linear_to_srgb(color.z());
  glColor3f(r,g,b);
  //  glColor3f(1,0,0);
  double x = 2 * (raytracing_x/double(args->width)) - 1;
  double y = 2 * (raytracing_y/double(args->height)) - 1;
  glVertex3f(x,y,-1);
  raytracing_x += raytracing_skip;
  return 1;
}
예제 #5
0
float GenLight::Shadow(Ray ray, float t_max)
{
	HitInfo hInfo;
	hInfo.Init();
	hInfo.z = t_max;
	if (TraceRay(&rootNode, ray, hInfo, HIT_FRONT))
		return 0.0f;
	return 1.0f;
}
예제 #6
0
void Renderer::calculatePixelColor(Node &i_rootNode, LightList &i_lightList, int offsetAlongWidth, int offsetAlongHeight)
{
	HitInfo hitInfo;
	Color noHitPixelColor = { 0,0,0 };
	Color finalColor = { 0,0,0 };
	RandomSampler sampler = RandomSampler(MIN_SAMPLE_COUNT, MAX_SAMPLE_COUNT, MIN_VARIANCE, MAX_VARIANCE);

	while (sampler.needMoreSamples())
	{
		sampler.generateSamples(offsetAlongWidth, offsetAlongHeight);
		for (int k = 0; k < sampler.getSampleBucketSize(); ++k)
		{
			hitInfo.Init();
			Ray sampleRay = sampler.getSampleRay(k);
			if (TraceRay(&i_rootNode, sampleRay, hitInfo))
			{
				finalColor = hitInfo.node->GetMaterial()->Shade(sampleRay, hitInfo, 
					i_lightList, REFLECTION_BOUNCE_COUNT, GI_BOUNCE_COUNT);
				/*finalColor.r = pow(finalColor.r, 1/2.2);
				finalColor.g = pow(finalColor.g, 1/2.2);
				finalColor.b = pow(finalColor.b, 1/2.2);*/
				sampler.setSampleColor(k, finalColor);
				sampler.setIsSampleHit(k, true);				
			}
			else
			{				
				sampler.setSampleColor(k, background.Sample(sampleRay.dir));
			}
			sampler.setHitInfo(k, hitInfo);
		}
	}

	Color tempColor = sampler.getAveragedSampleListColor();
	tempColor.r = pow(tempColor.r, 1 / 2.2);
	tempColor.g = pow(tempColor.g, 1 / 2.2);
	tempColor.b = pow(tempColor.b, 1 / 2.2);
	float depth = sampler.getAveragedDepth();
	int sampleCount = sampler.getSampleBucketSize();
	int pixel = offsetAlongHeight * imageWidth + offsetAlongWidth;

	TCHAR* mutexName = __T("WritingMutex");
	static HANDLE mutexHandle = NULL;
	if( mutexHandle == NULL )
		mutexHandle = OpenMutex(MUTEX_ALL_ACCESS, FALSE, mutexName);
	DWORD dSuccess = WaitForSingleObject(mutexHandle, INFINITE);
	assert(dSuccess == WAIT_OBJECT_0);
	renderingImage[pixel] = tempColor; 
	operationCountImage[pixel] = Color(1.0f,0.0f,0.0f) * static_cast<float>(hitInfo.operationCount/BIGFLOAT);
	zBufferImage[pixel] = depth;
	sampleCountImage[pixel] = sampleCount;
	bool bSuccess = ReleaseMutex(mutexHandle);
	assert(bSuccess == true);
	sampler.resetSampler();
}
예제 #7
0
inline ColorFloat CalculateReflection(Ray &ray, Vector &intersection, Vector &normal, int currPrimitiveNum, Primitive *primitives, int numPrimitives, LightSource *lightSources, int numLightSources, int depth)
{
  // R = I - 2(N.I)*N
  Ray reflectedRay;
  float nDotI = 2*((normal.x * ray.direction.x) + (normal.y * ray.direction.y) + (normal.z * ray.direction.z)); 
  reflectedRay.direction.x = ray.direction.x - (nDotI * normal.x);					
  reflectedRay.direction.y = ray.direction.y - (nDotI * normal.y); 
  reflectedRay.direction.z = ray.direction.z - (nDotI * normal.z);
  reflectedRay.origin = intersection;
    
  return TraceRay(currPrimitiveNum, reflectedRay, primitives, numPrimitives, lightSources, numLightSources, depth + 1);
}
예제 #8
0
DWORD WINAPI ThreadFunc(void * arg)
{
	tVals* vars = (tVals*)arg;
	int i=0;
	while(true)
	{
		i++;
		double rayx,rayy;
 	    int tempSkip;
	    WaitForSingleObject(*(vars->rayLock),INFINITE);

	    if ((*vars->raytracing_x) >= vars->args->width) {
		    (*vars->raytracing_x) = (*vars->raytracing_skip)/2;
		    (*vars->raytracing_y) += (*vars->raytracing_skip);
	    }
	    if ((*vars->raytracing_y) >= vars->args->height) {
		  if ((*vars->raytracing_skip) == 1) break;
		  (*vars->raytracing_skip) = *(vars->raytracing_skip) / 2;
		  if (*(vars->raytracing_skip) % 2 == 0) (*vars->raytracing_skip)++;
			assert (*(vars->raytracing_skip) >= 1);
			(*vars->raytracing_x) = (*vars->raytracing_skip)/2;
			(*vars->raytracing_y) = (*vars->raytracing_skip)/2;

	    }
	    rayx=*(vars->raytracing_x);
	    rayy=*(vars->raytracing_y);
		tempSkip=(*vars->raytracing_skip);
		(*vars->raytracing_x) += *(vars->raytracing_skip);
		(*vars->pixels)+=1;


		ReleaseMutex(*(vars->rayLock));

		// compute the color and position of intersection
		glm::vec3 color= TraceRay(rayx, rayy,vars);
		double r = linear_to_srgb(color.r);
		double g = linear_to_srgb(color.g);
		double b = linear_to_srgb(color.b);

		WaitForSingleObject(*(vars->glLock),INFINITE);
		globalR=r;globalG=g;globalB=b;
		globalX=rayx;globalY=rayy;
		globalSkip=tempSkip;
		//if ((*vars->pixels)<10000)
		globalIsPoint=true;
		while (globalIsPoint);
		ReleaseMutex(*(vars->glLock));
	}
	std::cout<<"Thread terminated"<<std::endl;
	return 0;
}
예제 #9
0
// Scan through the image from the lower left corner across each row
// and then up to the top right. Initially the image is sampled very
// coarsely. Increment the static variables that track the progress
// through the scans
void GLCanvas::DrawPixel(
	int ray_x, 
	int ray_y, 
	std::vector<Triple<double, double, double> > & colors,
	std::vector<Triple<double, double, double> > & vertices
) {
	// compute the color and position of intersection
	Vec3f color= TraceRay(ray_x, ray_y);
	double r = linear_to_srgb(color.x());
	double g = linear_to_srgb(color.y());
	double b = linear_to_srgb(color.z());
	
	colors.push_back(make_triple(r,g,b));
	//glColor3f(r,g,b);
	
	double x = 2 * (ray_x/double(args->width)) - 1;
	double y = 2 * (ray_y/double(args->height)) - 1;
	vertices.push_back(make_triple(x,y,(double)(-1)));
	//glVertex3f(x,y,-1);
}
예제 #10
0
bool TraceRay(const Ray &ray, HitInfo &hitinfo, const Node *node)
{
	//move ray transform here
	Ray newRay = node->ToNodeCoords(ray);
	bool hit = false;

	if (node->GetNodeObj())
	{
		hit = node->GetNodeObj()->IntersectRay(newRay, hitinfo);
		if (hit)
			hitinfo.node = node;
	}
	for (int i = 0; i < node->GetNumChild(); i++)
	{
		hit |= TraceRay(newRay, hitinfo, node->GetChild(i));
	}

	return hit;

}
예제 #11
0
//Write the image to a file
void GLCanvas::WriteToFile()
{
	//ORIGINAL CODE COMMENT
	//PLEASE BE UNIQUE
	std::cout << "Only in new folder!\n";
	//Open file
	Image newfile("");
	newfile.Allocate(args->width, args->height);
	//Write to file
	for (int i = 0; i < args->width; i++)
	{
		for (int j = 0; j < args->height; j++)
		{
			glm::vec3 color = TraceRay((i + 0.5),(j + 0.5));
			//std::cout << color.r << "\t" << color.g << "\t" << color.b << "\n";
			double r = linear_to_srgb(color.r);
			double g = linear_to_srgb(color.g);
			double b = linear_to_srgb(color.b);

			r *= 255;
			if (r > 255)
				r = 255;
			g *= 255;
			if (g > 255)
				g = 255;
			b *= 255;
			if (b > 255)
				b = 255;


			int ri, gi, bi;
			Color pixelcolor(r,g,b);
			//std::cout << r << "\t" << g << "\t" << b << "\n";
			newfile.SetPixel(i, j, pixelcolor);
		}
	}

	//Save and close file
	newfile.Save("Rendering.ppm");
	return;
}
예제 #12
0
void RayTracer::Render()
{

	for (int y = 0; y < mRenderTarget->GetHeight(); y++)
	{

		mCurrentX = mViewPlaneX1;


		for (int x = 0; x < mRenderTarget->GetWidth(); x++)
		{

			Vector3f direction = Vector3f(mCurrentX, mCurrentY, 0) - mEyePosition;
			direction.Normalize();

			Ray ray(mEyePosition, direction);


			Colour pixelColour = TraceRay(ray, 1);


			mRenderTarget->SetPixel(mBufferIndex++, pixelColour.CreatePixel());


			mCurrentX += mDeltaX;
		}


		mCurrentY += mDeltaY;






	}


}
예제 #13
0
// ray tracing
Colour RayTracer::TraceRay(Ray& ray, int traceDepth)
{
	if (traceDepth > MAXTRACEDEPTH)
		return Colour();

	Colour		litColour, reflectedColour;
	float		distanceToIntersect = MAXDISTANCE;
	Vector3f		intersectionPoint;
	Primitive*	nearestPrimitive = 0;

	nearestPrimitive = mScene->GetFirstPrimitive(ray, distanceToIntersect);

	if (!nearestPrimitive)
		return Colour();

	else
	{
		// Ambient,Specular lighting
		intersectionPoint = ray.GetOrigin() + ray.GetDirection() * distanceToIntersect;
		litColour = mScene->CalculatePrimitiveLightingAtPoint((*nearestPrimitive), intersectionPoint, ray.GetDirection());

		//  reflection
		float reflectionFactor = nearestPrimitive->GetMaterial()->Reflection;

		if (reflectionFactor > 0.0f)
		{
			Vector3f normal = nearestPrimitive->GetNormal(intersectionPoint);
			Vector3f reflected = ray.GetDirection() - normal * (2.0f * (ray.GetDirection()*normal));

			Ray reflectedRay = Ray(intersectionPoint , reflected);
			reflectedColour = TraceRay(reflectedRay, traceDepth + 1) * reflectionFactor;
		}

		return litColour + reflectedColour;
	}
}
void GLCanvas::keyboard(unsigned char key, int x, int y) {
  args->raytracing_animation = false;
  switch (key) {
    // RAYTRACING STUFF
  case 'r':  case 'R':
    // animate raytracing of the scene
    args->gather_indirect=false;
    args->raytracing_animation = !args->raytracing_animation;
    if (args->raytracing_animation) {
      raytracing_skip = my_max(args->width,args->height) / 10;
      if (raytracing_skip % 2 == 0) raytracing_skip++;
      assert (raytracing_skip >= 1);
      raytracing_x = raytracing_skip/2;
      raytracing_y = raytracing_skip/2;
      display(); // clear out any old rendering
      printf ("raytracing animation started, press 'R' to stop\n");
    } else
      printf ("raytracing animation stopped, press 'R' to start\n");    
    break;
  case 't':  case 'T': {
    // visualize the ray tree for the pixel at the current mouse position
    int i = x;
    int j = glutGet(GLUT_WINDOW_HEIGHT)-y;
    RayTree::Activate();
    raytracing_skip = 1;
    TraceRay(i,j);
    RayTree::Deactivate();
    // redraw
  RayTree::setupVBOs();
  radiosity->setupVBOs();
  photon_mapping->setupVBOs();


  glutPostRedisplay();
    break; }

  case 'l':  case 'L': { 
    // toggle photon rendering
    args->render_photons = !args->render_photons;
    glutPostRedisplay();
    break; }
  case 'k':  case 'K': { 
    // toggle photon rendering
    args->render_kdtree = !args->render_kdtree;
    glutPostRedisplay();
    break; }
  case 'p':  case 'P': { 
    // toggle photon rendering
    photon_mapping->TracePhotons();
    photon_mapping->setupVBOs();
    glutPostRedisplay();
    break; }
  case 'g':  case 'G': { 
    args->gather_indirect = true;
    args->raytracing_animation = !args->raytracing_animation;
    if (args->raytracing_animation) {
      raytracing_skip = my_max(args->width,args->height) / 10;
      if (raytracing_skip % 2 == 0) raytracing_skip++;
      assert (raytracing_skip >= 1);
      raytracing_x = raytracing_skip/2;
      raytracing_y = raytracing_skip/2;
      display(); // clear out any old rendering
      printf ("photon mapping animation started, press 'G' to stop\n");
    } else
      printf ("photon mapping animation stopped, press 'G' to start\n");    
    break; 
  }
    
    // RADIOSITY STUFF
  case ' ': 
    // a single step of radiosity
    radiosity->Iterate();
    radiosity->setupVBOs();
    glutPostRedisplay();
    break;
  case 'a': case 'A':
    // animate radiosity solution
    args->radiosity_animation = !args->radiosity_animation;
    if (args->radiosity_animation) 
      printf ("radiosity animation started, press 'A' to stop\n");
    else
      printf ("radiosity animation stopped, press 'A' to start\n");
    break;
  case 's': case 'S':
    // subdivide the mesh for radiosity
    radiosity->Cleanup();
    radiosity->getMesh()->Subdivision();
    radiosity->Reset();
    radiosity->setupVBOs();
    glutPostRedisplay();
    break;
  case 'c': case 'C':
    // clear the radiosity solution
    radiosity->Reset();
    radiosity->setupVBOs();
    glutPostRedisplay();
    break;

    // VISUALIZATIONS
  case 'w':  case 'W':
    // render wireframe mode
    args->wireframe = !args->wireframe;
    glutPostRedisplay();
    break;
  case 'v': case 'V':
    // toggle the different visualization modes
    args->render_mode = RENDER_MODE((args->render_mode+1)%NUM_RENDER_MODES);
    switch (args->render_mode) {
    case RENDER_MATERIALS: std::cout << "RENDER_MATERIALS\n"; fflush(stdout); break;
    case RENDER_LIGHTS: std::cout << "RENDER_LIGHTS\n"; fflush(stdout); break;
    case RENDER_UNDISTRIBUTED: std::cout << "RENDER_UNDISTRIBUTED\n"; fflush(stdout); break;
    case RENDER_ABSORBED: std::cout << "RENDER_ABSORBED\n"; fflush(stdout); break;
    case RENDER_RADIANCE: std::cout << "RENDER_RADIANCE\n"; fflush(stdout); break;
    case RENDER_FORM_FACTORS: std::cout << "RENDER_FORM_FACTORS\n"; fflush(stdout); break;
    default: assert(0); }
    radiosity->setupVBOs();
    glutPostRedisplay();
    break;
  case 'i':  case 'I':
    // interpolate patch illumination values
    args->interpolate = !args->interpolate;
    radiosity->setupVBOs();
    glutPostRedisplay();
    break;
  case 'b':  case 'B':
    // interpolate patch illumination values
    args->intersect_backfacing = !args->intersect_backfacing;
    glutPostRedisplay();
    break;

  case 'q':  case 'Q':
    // quit
    delete GLCanvas::photon_mapping;
    delete GLCanvas::raytracer;
    delete GLCanvas::radiosity;
    delete GLCanvas::mesh;
    exit(0);
    break;
  default:
    printf("UNKNOWN KEYBOARD INPUT  '%c'\n", key);
  }
}
예제 #15
0
Color MtlBlinn::Shade(const Ray &ray, const HitInfo &hInfo, const LightList &lights, int reflection_bounceCount, int gi_bounceCount) const
{
	Color ambientComp, diffuseComp, specularComp, reflectiveComp, refractiveComp, reflectionTotal, refractionTotal, noColor, diffuseReflection;
	diffuseReflection = ambientComp = diffuseComp = specularComp = reflectiveComp = refractiveComp  = noColor = reflectionTotal = refractionTotal = Color(0.0f, 0.0f, 0.0f);
	Color fromReflection = Color(0.0f, 0.0f, 0.0f);
	Color fromRefraction = Color(0.0f, 0.0f, 0.0f);
	Point3 viewDirection = -ray.dir;
	float schlicksConstant, ratioOfRefraction;
	Color kd = diffuse.Sample(hInfo.uvw);

	int hitside = HIT_FRONT;
	float n1 = 1;
	float n2 = ior;

	for (int i = 0; i < lights.size(); i++)
	{
		Color lightColor = lights[i]->Illuminate(hInfo.p, hInfo.N);
		/*if (lightColor != noColor)
		{*/
			if (lights[i]->IsAmbient())
			{
				ambientComp = ambientComponent(lights[i], lightColor, hInfo, diffuse.Sample(hInfo.uvw));
			}
			else
			{
				//lightColor.ClampMinMax();
				Point3 rayDir = ray.dir;
				globalPhotonMap.EstimateIrradiance<50>(lightColor, rayDir, 2.0f, hInfo.p, &hInfo.N);
				diffuseComp = diffuseComponent(lights[i], lightColor, hInfo, diffuse.Sample(hInfo.uvw));
				specularComp = specularComponent(lights[i], lightColor, viewDirection, hInfo, specular.Sample(hInfo.uvw), glossiness);
			}
		//}
	}
			/************************Refraction************************************************************/
	if(refraction.Sample(hInfo.uvw) != noColor && reflection_bounceCount > 0)
	{
		Ray refractionRay;
		HitInfo refractionRayHit;
		refractionRayHit.Init();
		refractionRay.p = hInfo.p;
		if (hInfo.front == HIT_FRONT)
		{
			refractionRay.dir = getRefractionVector(viewDirection, getPerturbedNormal(hInfo.N, hInfo.p, refractionGlossiness), n1, n2);
		}
		else
		{
			refractionRay.dir = getRefractionVector(viewDirection, getPerturbedNormal( -hInfo.N, hInfo.p, refractionGlossiness), n2, n1);
		}
				
		if(TraceRay(&rootNode, refractionRay, refractionRayHit, hitside))
		{
			Point3 refractionDir = refractionRay.dir;
			refractiveComp += refractionRayHit.node->GetMaterial()->Shade(refractionRay, refractionRayHit, 
				lights, --reflection_bounceCount);
			refractiveComp *= refraction.Sample(hInfo.uvw);
		}
		else
		{
			refractiveComp =  environment.SampleEnvironment(refractionRay.dir);
		}				
	}


	/********************Schlick's Approximation - Fresnel Reflection***************************/
	schlicksConstant = pow(((n1 - n2) / (n1 + n2)), 2);
	ratioOfRefraction = schlicksConstant + (1 - schlicksConstant) * pow((1 - viewDirection.Dot(hInfo.N)), 5);
	reflectionTotal = ratioOfRefraction*refraction.Sample(hInfo.uvw);
	refractionTotal = (1 - ratioOfRefraction)*refraction.Sample(hInfo.uvw);
	///*******************************************************************************************/
	//refractiv    eComp *= refractionTotal; //It = (1-R) * KT'
	reflectionTotal += reflection.Sample(hInfo.uvw); //Doing outside in case refraction didn't occured at all
	/*********************************************************************************************/

	/**********************Reflection*************************************************************/
	if(reflectionTotal != noColor && reflection_bounceCount > 0)
	{
		Ray reflectionViewVector;
		reflectionViewVector.dir = getReflectionVector(viewDirection, 
			getPerturbedNormal(hInfo.N, hInfo.p, reflectionGlossiness));
		reflectionViewVector.p = hInfo.p;
		HitInfo reflectionRayHit;
		reflectionRayHit.Init();
		//--reflection_bounceCount;
		if (TraceRay(&rootNode, reflectionViewVector, reflectionRayHit, HIT_FRONT))
		{
			fromReflection += reflectionRayHit.node->GetMaterial()->Shade(reflectionViewVector, 
				reflectionRayHit, lights, --reflection_bounceCount);
			reflectiveComp = reflectionTotal * fromReflection;
		}
		else
		{
			reflectiveComp = environment.SampleEnvironment(reflectionViewVector.dir);
		}
	}
	/****************************************************************************************************/
	if(GI_ALGO)
	{
		if (kd != noColor && gi_bounceCount > 0)
		{
			HemiSphereSampler giHemiSampler = HemiSphereSampler(__gi_sampleCount, __gi_sampleCount, 1);
			giHemiSampler.generateSamples();
			Point3 randomDirectionAtHitPoint = Point3(0.0f, 0.0f, 0.0f);
			HitInfo diffuseReflectionHitInfo;
			Ray diffuseReflectionRay;
			for (int i = 0; i < giHemiSampler.getCurrentSampleCount(); ++i)
			{
				randomDirectionAtHitPoint = giHemiSampler.getSample(getRandomNumber(0, giHemiSampler.getCurrentSampleCount())).getOffset();
				diffuseReflectionRay.p = hInfo.p;
				Point3 u = Point3(0.0f, 0.0f, 0.0f);
				Point3 v = Point3(0.0f, 0.0f, 0.0f);
				Point3 w = Point3(0.0f, 0.0f, 0.0f);
				w = hInfo.N;
				getOrthoNormalBasisVector(w, u, v);
				diffuseReflectionRay.dir = randomDirectionAtHitPoint.x * u +
					randomDirectionAtHitPoint.y * v +
					randomDirectionAtHitPoint.z *w;
				diffuseReflectionHitInfo.Init();
				if (TraceRay(&rootNode, diffuseReflectionRay, diffuseReflectionHitInfo, HIT_FRONT))
				{
					diffuseReflection = diffuseReflectionHitInfo.node->GetMaterial()->Shade(diffuseReflectionRay,
						diffuseReflectionHitInfo, lights, 0, gi_bounceCount - 1);					
				}
				else
				{
					diffuseReflection = environment.SampleEnvironment(diffuseReflectionRay.dir);
				}
				giHemiSampler.setSampleColor(i, diffuseReflection);
				giHemiSampler.setIsSampleHit(i, true);
			}

			diffuseReflection = giHemiSampler.getAveragedSampleListColor() * diffuseReflection * kd * M_PI;
		}
	}
	else
	{
		if (kd != noColor && gi_bounceCount > 0)
		{
			HemiSphereSampler giHemiSampler = HemiSphereSampler(__gi_sampleCount, __gi_sampleCount, 1);
			giHemiSampler.generateSamples();
			Point3 randomDirectionAtHitPoint = Point3(0.0f, 0.0f, 0.0f);
			HitInfo diffuseReflectionHitInfo;
			Ray diffuseReflectionRay;
			
			randomDirectionAtHitPoint = giHemiSampler.getSample(getRandomNumber(0, giHemiSampler.getCurrentSampleCount())).getOffset();
			diffuseReflectionRay.p = hInfo.p;
			Point3 u = Point3(0.0f, 0.0f, 0.0f);
			Point3 v = Point3(0.0f, 0.0f, 0.0f);
			Point3 w = Point3(0.0f, 0.0f, 0.0f);
			w = hInfo.N;
			getOrthoNormalBasisVector(w, u, v);
			diffuseReflectionRay.dir = randomDirectionAtHitPoint.x * u +
				randomDirectionAtHitPoint.y * v +
				randomDirectionAtHitPoint.z *w;
			
			diffuseReflectionHitInfo.Init();
			if (TraceRay(&rootNode, diffuseReflectionRay, diffuseReflectionHitInfo, HIT_FRONT))
			{
				diffuseReflection += diffuseReflectionHitInfo.node->GetMaterial()->Shade(diffuseReflectionRay,
					diffuseReflectionHitInfo, lights, 0, gi_bounceCount - 1);	
				diffuseReflection = diffuseReflection * kd;
			}
			else
			{
				diffuseReflection = environment.SampleEnvironment(diffuseReflectionRay.dir);
			}			
		}
	}
			
	return (ambientComp + diffuseComp + specularComp+ reflectiveComp + refractiveComp + diffuseReflection);
}
예제 #16
0
void GeomTree::TraceRay(const vector3f &start, const vector3f &dir, isect_t *isect) const
{
	TraceRay(m_triTree->GetRoot(), start, dir, isect);
}
예제 #17
0
// Scan through the image from the lower left corner across each row
// and then up to the top right.  Initially the image is sampled very
// coarsely.  Increment the static variables that track the progress
// through the scans
int GLCanvas::DrawPixel() {
  if (raytracing_x >= raytracing_divs_x) {
    // end of row
    raytracing_x = 0; 
    raytracing_y += 1;
  }
  if (raytracing_y >= raytracing_divs_y) {
    // last row
    if (raytracing_divs_x >= args->width ||
        raytracing_divs_y >= args->height) {
      // stop rendering, matches resolution of current camera
      return 0; 
    }
    // else decrease pixel size & start over again in the bottom left corner
    raytracing_divs_x *= 6;
    raytracing_divs_y *= 6;
    if (raytracing_divs_x > args->width * 0.51 ||
        raytracing_divs_x > args->height * 0.51) {
      raytracing_divs_x = args->width;
      raytracing_divs_y = args->height;
    }
    raytracing_x = 0;
    raytracing_y = 0;
    if (raytracer->render_to_a) {
      raytracer->pixels_b.clear();
      raytracer->pixels_indices_b.clear();
     raytracer->render_to_a = false;
    } else {
      raytracer->pixels_a.clear();
      raytracer->pixels_indices_a.clear();
      raytracer->render_to_a = true;
    }
  }

  double x_spacing = args->width / double (raytracing_divs_x);
  double y_spacing = args->height / double (raytracing_divs_y);

  // compute the color and position of intersection
  glm::vec3 pos1 =  GetPos((raytracing_x  )*x_spacing, (raytracing_y  )*y_spacing);
  glm::vec3 pos2 =  GetPos((raytracing_x+1)*x_spacing, (raytracing_y  )*y_spacing);
  glm::vec3 pos3 =  GetPos((raytracing_x+1)*x_spacing, (raytracing_y+1)*y_spacing);
  glm::vec3 pos4 =  GetPos((raytracing_x  )*x_spacing, (raytracing_y+1)*y_spacing);
  
  glm::vec3 color = TraceRay((raytracing_x+0.5)*x_spacing, (raytracing_y+0.5)*y_spacing);

  double r = linear_to_srgb(color.r);
  double g = linear_to_srgb(color.g);
  double b = linear_to_srgb(color.b);
  if (raytracer->render_to_a) {
    int start = raytracer->pixels_a.size();
    raytracer->pixels_a.push_back(VBOPosNormalColor(pos1,glm::vec3(0,0,0),glm::vec4(r,g,b,1.0)));
    raytracer->pixels_a.push_back(VBOPosNormalColor(pos2,glm::vec3(0,0,0),glm::vec4(r,g,b,1.0)));
    raytracer->pixels_a.push_back(VBOPosNormalColor(pos3,glm::vec3(0,0,0),glm::vec4(r,g,b,1.0)));
    raytracer->pixels_a.push_back(VBOPosNormalColor(pos4,glm::vec3(0,0,0),glm::vec4(r,g,b,1.0)));
    raytracer->pixels_indices_a.push_back(VBOIndexedTri(start+0,start+1,start+2));
    raytracer->pixels_indices_a.push_back(VBOIndexedTri(start+0,start+2,start+3));
  } else {
    int start = raytracer->pixels_b.size();
    raytracer->pixels_b.push_back(VBOPosNormalColor(pos1,glm::vec3(0,0,0),glm::vec4(r,g,b,1.0)));
    raytracer->pixels_b.push_back(VBOPosNormalColor(pos2,glm::vec3(0,0,0),glm::vec4(r,g,b,1.0)));
    raytracer->pixels_b.push_back(VBOPosNormalColor(pos3,glm::vec3(0,0,0),glm::vec4(r,g,b,1.0)));
    raytracer->pixels_b.push_back(VBOPosNormalColor(pos4,glm::vec3(0,0,0),glm::vec4(r,g,b,1.0)));
    raytracer->pixels_indices_b.push_back(VBOIndexedTri(start+0,start+1,start+2));
    raytracer->pixels_indices_b.push_back(VBOIndexedTri(start+0,start+2,start+3));
  }  

  raytracing_x += 1;
  return 1;
}
예제 #18
0
void GLCanvas::keyboardCB(GLFWwindow* window, int key, int scancode, int action, int mods) {
  // store the modifier keys
  shiftKeyPressed = (GLFW_MOD_SHIFT & mods);
  controlKeyPressed = (GLFW_MOD_CONTROL & mods);
  altKeyPressed = (GLFW_MOD_ALT & mods);
  superKeyPressed = (GLFW_MOD_SUPER & mods);
  // non modifier key actions

  if (key == GLFW_KEY_ESCAPE || key == 'q' || key == 'Q') {
    glfwSetWindowShouldClose(GLCanvas::window, GL_TRUE);
  }

  // other normal ascii keys...
  if ( (action == GLFW_PRESS || action == GLFW_REPEAT) && key < 256) {
    switch (key) {
    // RAYTRACING STUFF
    case 'r':  case 'R':  case 'g':  case 'G': { 
      args->raytracing_animation = !args->raytracing_animation;
      glfwGetWindowSize(window, &args->width, &args->height);
      // animate raytracing of the scene
      if (args->raytracing_animation) {
        if (key == 'r' || key == 'R') {
          args->gather_indirect = false;
          printf ("raytracing animation started, press 'R' to stop\n");
        } else {
          args->gather_indirect = true; 
          printf ("photon mapping animation started, press 'G' to stop\n");
        }
        if (args->width <= args->height) {
          raytracing_divs_x = 10;
          raytracing_divs_y = 10 * args->height / float (args->width);
        } else {
          raytracing_divs_x = 10 * args->width / float (args->height);
          raytracing_divs_y = 10;
        }
        raytracing_x = 0;
        raytracing_y = 0;
        raytracer->resetVBOs();
      } else
        printf ("raytracing animation stopped, press 'R' to start\n");    
      break;
    }
    case 't':  case 'T': {
      // visualize the ray tree for the pixel at the current mouse position
      glfwGetWindowSize(window, &args->width, &args->height);
      RayTree::Activate();
      raytracing_divs_x = -1;
      raytracing_divs_y = -1;
      TraceRay(mouseX,args->height-mouseY);
      RayTree::Deactivate();
      glm::vec3 cp = camera->camera_position;
      glm::vec3 poi = camera->point_of_interest;
      float distance = glm::length((cp-poi)/2.0f);
      RayTree::setupVBOs(distance / 500.0); 
      radiosity->setupVBOs();
      photon_mapping->setupVBOs();
      break; }
    case 'l':  case 'L': { 
      // toggle photon rendering
      args->render_photons = !args->render_photons;
      break; }
    case 'k':  case 'K': { 
      // toggle photon rendering
      args->render_kdtree = !args->render_kdtree;
      break; }
    case 'p':  case 'P': { 
      // toggle photon rendering
      photon_mapping->TracePhotons();
      photon_mapping->setupVBOs();
      break; }
    
      // RADIOSITY STUFF
    case ' ': 
      // a single step of radiosity
      radiosity->Iterate();
      radiosity->setupVBOs();
      break;
    case 'a': case 'A':
      // animate radiosity solution
      args->radiosity_animation = !args->radiosity_animation;
      if (args->radiosity_animation) 
        printf ("radiosity animation started, press 'A' to stop\n");
      else
        printf ("radiosity animation stopped, press 'A' to start\n");
      break;
    case 's': case 'S':
      // subdivide the mesh for radiosity
      radiosity->Cleanup();
      radiosity->getMesh()->Subdivision();
      radiosity->Reset();
      radiosity->setupVBOs();
      break;
    case 'c': case 'C':
      // clear the raytracing visualization
      args->raytracing_animation = false;
      raytracer->resetVBOs();
      raytracer->setupVBOs();
      // clear the radiosity solution
      args->radiosity_animation = false;
      radiosity->Reset();
      radiosity->setupVBOs();
      break;
      
      // VISUALIZATIONS
    case 'w':  case 'W':
      // render wireframe mode
      args->wireframe = !args->wireframe;
      break;
    case 'v': case 'V':
      // toggle the different visualization modes
      args->render_mode = RENDER_MODE((args->render_mode+1)%NUM_RENDER_MODES);
      switch (args->render_mode) {
      case RENDER_MATERIALS: std::cout << "RENDER_MATERIALS\n"; fflush(stdout); break;
      case RENDER_LIGHTS: std::cout << "RENDER_LIGHTS\n"; fflush(stdout); break;
      case RENDER_UNDISTRIBUTED: std::cout << "RENDER_UNDISTRIBUTED\n"; fflush(stdout); break;
      case RENDER_ABSORBED: std::cout << "RENDER_ABSORBED\n"; fflush(stdout); break;
      case RENDER_RADIANCE: std::cout << "RENDER_RADIANCE\n"; fflush(stdout); break;
      case RENDER_FORM_FACTORS: std::cout << "RENDER_FORM_FACTORS\n"; fflush(stdout); break;
      default: assert(0); }
      radiosity->setupVBOs();
      break;
    case 'i':  case 'I':
      // interpolate patch illumination values
      args->interpolate = !args->interpolate;
      radiosity->setupVBOs();
      break;
    case 'b':  case 'B':
      // interpolate patch illumination values
      args->intersect_backfacing = !args->intersect_backfacing;
      break;
      
    case 'x':  case 'X':
      std::cout << "CURRENT CAMERA" << std::endl;
      std::cout << *camera << std::endl;
      break;

    case 'q':  case 'Q':
      // quit
      glfwSetWindowShouldClose(GLCanvas::window, GL_TRUE);
      break;
    default:
      std::cout << "UNKNOWN KEYBOARD INPUT  '" << (char)key << "'" << std::endl;
    }
    setupVBOs();
  }
}
예제 #19
0
int main(void)
{
	myEngine::Timing::Clock *clock = myEngine::Timing::Clock::createAndStart();
	int temp = LoadScene(LOAD_FILE);
	Point3 cameraRight = (camera.dir ^ camera.up).GetNormalized();
	double aspectRatio = static_cast<double>(camera.imgWidth) / static_cast<double>(camera.imgHeight);
	float camera_l = 1 / (tan((camera.fov / 2) * (M_PI/ 180)));
	
	Point3 Sx = cameraRight;
	Point3 Sy = (-1.0f) * camera.up;
	
	Point3 pixel;
	Point3 k = camera.pos + camera_l* camera.dir;// -cameraRight + camera.up;

	HitInfo hitInfo;
	

	//Color24 hitPixelColor = { 255,255,255 };
	Color noHitPixelColor = { 0,0,0 };
	Color24* temp_image = renderImage.GetPixels();

	float* temp_zBuffer = renderImage.GetZBuffer();

	
	for (int i = 0;i < camera.imgHeight; i++)
	{
		//printf("%d\n",i);
		for (int j = 0; j < camera.imgWidth; j++)
		{
			hitInfo.Init();
			float flipped_i = camera.imgHeight - i - 1;
			pixel = k + (((2.0f*aspectRatio * (j + 0.5f)) / camera.imgWidth) - aspectRatio)*Sx + ((((flipped_i + 0.5) * 2) / camera.imgHeight) - 1)* Sy;
			pixelRay.p = camera.pos;
			pixelRay.dir = (pixel - camera.pos).GetNormalized();
			
			if (TraceRay(&rootNode, pixelRay, hitInfo))
			{
#ifdef  RELEASE_DEBUG
				temp_image[i*camera.imgWidth + j] = normalColor(hitInfo);
#else
				temp_image[i*camera.imgWidth + j] = hitInfo.node->GetMaterial()->Shade(pixelRay, hitInfo, lights, 7);
#endif
				temp_zBuffer[i*camera.imgWidth + j] = hitInfo.z;
			}
			else
			{

				temp_image[i*camera.imgWidth + j] = noHitPixelColor;
				temp_zBuffer[i*camera.imgWidth + j] = hitInfo.z;
			}
		}
	}

	renderImage.SaveImage("RayCasted.ppm");
	renderImage.ComputeZBufferImage();
	renderImage.SaveZImage("RayCastWithZ.ppm");
	
	clock->updateDeltaTime();
	double time = clock->getdeltaTime();
	printf("Time to render ray casting  %f", clock->getdeltaTime());
	printf("Time to render zBuffer Image  %f", clock->getdeltaTime());

	ShowViewport();
	
}
예제 #20
0
void CTracer::RenderImage(Params & params)
{
	// Reading input texture sample
	CImage* pImage = LoadImageFromFile("data/disk_32.png");
	if (!pImage) {
		std::cout << "Received NULL pointer when loading texture. Probably wrong file." << std::endl;
		return;
	}
	saved_images.push_back(pImage);
	image_shapes.push_back(img_shape(0));
	// Reading background (stars) texture
	CImage* stars = LoadImageFromFile("data/stars.jpg");
	if (!stars) {
		std::cout << "Received NULL pointer when loading texture. Probably wrong file." << std::endl;
		return;
	}
	saved_images.push_back(stars);
	image_shapes.push_back(img_shape(1));

	// Filling in properties
	m_camera.m_resolution = glm::uvec2(params.xRes, params.yRes);
	m_camera.m_pixels.resize(params.xRes * params.yRes);
	m_camera.m_pos = params.camera_pos;
	params.up /= glm::length(params.up);
	params.up *= params.yRes;
	m_camera.m_up = params.up;
	params.right /= glm::length(params.right);
	params.right *= params.xRes;
	m_camera.m_right = params.right;
	params.view_dir /= glm::length(params.view_dir);
	params.view_dir *= params.yRes / (2.0 * tan(params.view_angle.y / 2.0));
	m_camera.m_forward = params.view_dir;
	m_camera.m_viewAngle = params.view_angle;
	double black_hole_radius = 2 * grav_const * params.black_hole_mass / light_speed / light_speed;
	black_hole.center = glm::dvec3(0, 0, 0);
	black_hole.radius = black_hole_radius;
	black_hole.mass = params.black_hole_mass;
	// setting disk params
	disk.center = glm::dvec3(0, 0, 0);
	disk.in_rad = black_hole_radius;
	disk.out_rad = black_hole_radius * params.disk_bh_rad_ratio;
	disk.normal = glm::vec3(0, 0, 1);
	for (int i = 0; i < 2; ++i) {
		planet_enable[i] = params.planet_enable[i];
		planets[i].center = params.planet_center[i];
		planets[i].radius = params.planet_rad[i];
		planet_colors[i] = params.planet_color[i];
	}
	alpha_blending_enable = params.alpha_blending_enable;
	antialiasing_rays = params.antialiasing_rays;
	
	// Rendering
	double gap, x_shift, y_shift;
	glm::vec3 rays_accum(0, 0, 0);
	SRay ray;
	for (int i = 0; i < params.yRes; i++) {
		for (int j = 0; j < params.xRes; j++)
		{
			rays_accum.r = rays_accum.b = rays_accum.g = 0;
			x_shift = y_shift = gap = 1.0 / (antialiasing_rays + 1);
			for (int x_rays = 0; x_rays < antialiasing_rays; ++x_rays, x_shift += gap) {
				for (int y_rays = 0; y_rays < antialiasing_rays; ++y_rays, y_shift += gap) {
					ray = MakeRay(glm::uvec2(j, i), x_shift, y_shift);
					rays_accum += TraceRay(ray);
				}
			}
			rays_accum /= (antialiasing_rays * antialiasing_rays);
			m_camera.m_pixels[i * params.xRes + j] = rays_accum;
			//m_camera.m_pixels[i * params.xRes + j] = rgb_cut(img_get_pxl_rgba(1, i, j)) / 255.0f;
		}
	}
}