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; }
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)); } } }
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; }
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; }
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(); }
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); }
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; }
// 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); }
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; }
//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; }
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; } }
// 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); } }
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); }
void GeomTree::TraceRay(const vector3f &start, const vector3f &dir, isect_t *isect) const { TraceRay(m_triTree->GetRoot(), start, dir, isect); }
// 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; }
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(); } }
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(); }
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; } } }