bool RayTrace(HitInfo &hitInfo, Node* curnode, Ray ray, int PixIndex) { Node* node = curnode; bool hitTest = false; const Object *obj = node->GetObject(); ray = curnode->ToNodeCoords(ray); if(obj){ // cout<<"Transforming to..."<<endl; HitInfo tempHitInfo; tempHitInfo.Init(); tempHitInfo.node = node; tempHitInfo.z = hitInfo.z; hitTest = obj->IntersectRay(ray, tempHitInfo); node->FromNodeCoords(tempHitInfo); if(hitTest && tempHitInfo.z < hitInfo.z){ hitInfo = tempHitInfo; //cout<<hitInfo.z<<endl; } //else hitTest=false; } if(node->GetNumChild()>0) { //cout<<"Children "<<node->GetNumChild()<<endl; for(int i=0;i<curnode->GetNumChild();++i) { // cout<<"Child "<<i<<endl; node = curnode->GetChild(i); HitInfo temp; temp.Init(); temp = hitInfo; if(RayTrace(hitInfo, node, ray, PixIndex)){ curnode->FromNodeCoords(hitInfo); // cout<<"Transforming from "<<curnode->GetNumChild()<<endl; if(temp.z > hitInfo.z) hitTest = true; else{ // hitInfo = temp; hitTest = false; continue; } } } } if(hitTest) return true; else return false; }
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"); }
void BeginRender() { cout<<"\nBeginning Render..."; float alpha = camera.fov; float l = 1.0; float h = l * tan(alpha/2.0 *(M_PI/180)); float aspectRatio = (float)camera.imgWidth/camera.imgHeight; float s = aspectRatio * h; float dx = (2 * s)/camera.imgWidth; float dy = -(2 * h)/camera.imgHeight; float dxx = dx/2,dyy=dy/2; Point3 K(-s,h,-l); K.x += dxx; K.y += dyy; for(int i = 0; i< camera.imgHeight; i++){ for(int j = 0; j<camera.imgWidth; j++){ K.x += dx; Matrix3 RotMat; Point3 dvec = camera.dir - camera.pos; Point3 svec = camera.up.Cross(dvec); dvec.Normalize(); svec.Normalize(); camera.up.Normalize(); RotMat.Set(svec,camera.up, dvec); Ray r(camera.pos, K); r.dir=r.dir*RotMat; r.dir.Normalize(); HitInfo hInfo; hInfo.Init(); if(rootNode.GetNumChild()>0){ // for(int k=0; k < rootNode.GetNumChild(); ++k){ // RayTrace(rootNode.GetChild(k),r,i * camera.imgWidth + j); // } if(RayTrace_2(r, hInfo)) { renderImage.PutPixel(i *camera.imgWidth+j, white, hInfo.z); } else renderImage.PutPixel(i *camera.imgWidth+j, black, BIGFLOAT); } } K.x = -s; K.x += dxx; K.y += dy; } cout<<"Render Complete"<<endl; renderImage.ComputeZBufferImage(); renderImage.SaveZImage("/Users/varunk/Desktop/RayTracerProj1/RayTracerProj1/zbuffer.ppm"); renderImage.SaveImage("/Users/varunk/Desktop/RayTracerProj1/RayTracerProj1/renderimage.ppm"); }
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(); }
void doRender(void* arg){ RenderParams rarg = *((RenderParams *)arg); //cout<<"Do render...."<<endl; bool pixelHit=false; HitInfo hitInfo; hitInfo.Init(); Point2 pixLoc = rarg.pixLocation; Ray r = rarg.ray; int PixIndex = rarg.pixIndex; Color shade(255,255,255); if(rootNode.GetNumChild()>0){ if(RayTrace_2(r, hitInfo)) { pixelHit=true; // cout<<"Shading...."<<endl; shade = hitInfo.node->GetMaterial()->Shade(r, hitInfo, lights, 5); } renderImage.PutPixel(PixIndex, shade, hitInfo.z); } if(!pixelHit){ renderImage.PutPixel(PixIndex, black, BIGFLOAT); } // RenderParams renderArg = giveMeAPixelToRender(); // if(renderArg.renderComplete != 1){ // doRender(&renderArg); // } // }
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); }
Color MtlBlinn::Shade(const Cone &ray, const HitInfo &hInfo, const LightList &lights, int bounceCount) const{ float bias = BIAS_SHADING; Color shade; Color rShade = Color(0,0,0); Color tShade = Color(0,0,0); const Material *mat; mat = hInfo.node->GetMaterial(); const MtlBlinn* mb =static_cast<const MtlBlinn*>(mat); // cout<<"HInfo front: "<<hInfo.front<<endl; /* local copy */ Point3 P; P.Set(hInfo.p.x,hInfo.p.y,hInfo.p.z); Cone iRay = ray; Color ambInt = mb->diffuse.Sample(hInfo.uvw, hInfo.duvw); Color allOther = Color(0,0,0); Color diffuse = mb->diffuse.Sample(hInfo.uvw, hInfo.duvw); Color ambComponent = Color(0,0,0); Point3 newN = hInfo.N; for ( unsigned int i=0; i<lights.size(); i++ ) { if(lights[i]->IsAmbient()){ // cout<<"ambient "<<endl; Color intensity = lights[i]->Illuminate(hInfo.p); ambComponent += (ambInt * intensity); continue; } else{ // cout<<"other lighting "<<endl; Point3 L = -lights[i]->Direction(P); L.Normalize(); Point3 V = ray.p - P; V.Normalize(); Point3 LplusV = L + V; Point3 H = (L+V)/LplusV.Length(); H.Normalize(); float alpha = mb->glossiness; // Point3 N = hInfo.N; Point3 N = newN; float S = H.Dot(N); S = pow(S,alpha); float costheta = L.Dot(N)/(L.Length() * N.Length()); Color intensity = lights[i]->Illuminate(P); // cout<<"costheta "<<endl; allOther += intensity * (costheta>0?costheta:0) * (diffuse + S * (mb->specular.Sample(hInfo.uvw, hInfo.duvw))) ; } /* finally add inta*cola + intall*costheta*(cold + s* colS)*/ shade = ambComponent + allOther; } /* Calculate refraction */ if(refraction.GetColor().r>0 && bounceCount>0){ //compute new jittered normal float gloss = refractionGlossiness; if(gloss){ float random = rand()/(float)RAND_MAX; float rRadius = sqrtf(random) * gloss; random = rand()/(float)RAND_MAX; float rAngle = random * 2.0 * M_PI; float x = rRadius * cos(rAngle); float y = rRadius * sin(rAngle); Point3 xAxis(1,0,0), yAxis(0,1,0), v1, v2, normalDir; normalDir = hInfo.N; // normalDir.Normalize(); if(normalDir.Dot(xAxis) > 0.7) v1 = normalDir.Cross(yAxis); else v1 = normalDir.Cross(xAxis); v2 = v1.Cross(normalDir); v1.Normalize(); v2.Normalize(); v1 *= x; v2 *= y; newN = hInfo.N + v1.Length() + v2.Length(); newN.Normalize(); } else{ newN = hInfo.N; } //------------------------------------- Color reflShade = Color(0,0,0); float R0, Refl = 0.0f, Trans = 0.0f; HitInfo temp; temp.Init(); // Point3 N = hInfo.N; Point3 N = newN; // Point3 V = Point3(iRay.p.x - hInfo.p.x, iRay.p.y - hInfo.p.y, iRay.p.z - hInfo.p.z); Point3 V = Point3(hInfo.p.x - iRay.p.x, hInfo.p.y - iRay.p.y, hInfo.p.z - iRay.p.z); V.Normalize(); float n1 = 1, n2 = 1; if(hInfo.front){ /* Hitting from outside */ // temp.front = false; n2 = ior; // cout<<"outside "<<endl; } else if(!hInfo.front){ /* Transmission from the inside */ // temp.front = true; n1 = ior; // cout<<"intside... "<<endl; // N = -hInfo.N; N *= -1; } float ratio_n = n1 / n2; float costheta_v = -V.Dot(N); /* refer: http://graphics.stanford.edu/courses/cs148-10-summer/docs/2006--degreve--reflection_refraction.pdf */ float sin2theta_t = ratio_n * ratio_n * (1 - costheta_v * costheta_v); Point3 T = ratio_n * V + (ratio_n * costheta_v - sqrtf(1 - sin2theta_t)) * N ; // cout<<ratio_n<<" "<<"cos_v "<<costheta_v<<" sin2theta_t "<<sin2theta_t<<endl; Cone tRay = Cone(hInfo.p,T); //tRay.dir.Normalize(); tRay.p.x = tRay.p.x + bias *tRay.dir.x; /* add bias */ tRay.p.y = tRay.p.y + bias *tRay.dir.y; tRay.p.z = tRay.p.z + bias *tRay.dir.z; // cout<<"B temp front: "<< temp.front<<endl; temp.timeInstance = hInfo.timeInstance; if(sin2theta_t <= 1){ if(RayTrace_2(tRay, temp)){ /* ray tracing after refraction */ // bounceCount--; tShade = temp.node->GetMaterial()->Shade(tRay,temp,lights,bounceCount); } else{ /* no hit after refraction */ tShade = environment.SampleEnvironment(tRay.dir); } /* Calculate Schlick's approximation */ R0 = (n1 - n2)/(n1 + n2); R0 *= R0; double X = 0.0; // if(n1 > n2){ // X = 1.0 - sqrtf(1.0 - sin2theta_t); // } // else{ X = 1.0 - costheta_v; } X = 1.0 - costheta_v; Refl = R0 + (1.0 - R0) * X * X * X * X * X; Trans = 1.0 - Refl; tShade.r *= exp(-absorption.r * temp.z); tShade.g *= exp(-absorption.g * temp.z); tShade.b *= exp(-absorption.b * temp.z); } else {/* Total internal reflection */ Refl = 1.0f; } /* Calculate reflection due to reflectance */ if(bounceCount >0){ // N = hInfo.N; N = newN; Point3 V = Point3(iRay.p.x - P.x, iRay.p.y - P.y, iRay.p.z - P.z); //V.Normalize(); Point3 VR = 2 * V.Dot(N) * N - V; //VR.Normalize(); Cone rRay = Cone(P + BIAS_SHADING * VR, VR); rRay.dir.Normalize(); HitInfo temp1; temp1.Init(); temp.timeInstance = hInfo.timeInstance; if(rootNode.GetNumChild()>0){ if(RayTrace_2(rRay, temp1)){ bounceCount --; reflShade = temp1.node->GetMaterial()->Shade(rRay, temp1, lights, bounceCount); } else{ reflShade = environment.SampleEnvironment(rRay.dir); // reflShade = Color(1,100,1); } } } // cout<<"Refl: "<<Refl<<"Trans "<<Trans<<endl; tShade = refraction.GetColor().r * (Trans * tShade + Refl * reflShade); } /* calculate reflection*/ if(reflection.GetColor().r>0 && bounceCount > 0){ //compute new jittered normal float gloss = reflectionGlossiness; if(gloss){ float random = rand()/(float)RAND_MAX; float rRadius = sqrtf(random) * gloss; random = rand()/(float)RAND_MAX; float rAngle = random * 2.0 * M_PI; float x = rRadius * cos(rAngle); float y = rRadius * sin(rAngle); Point3 xAxis(1,0,0), yAxis(0,1,0), v1, v2, normalDir; normalDir = hInfo.N; // normalDir.Normalize(); if(normalDir.Dot(xAxis) > 0.7) v1 = normalDir.Cross(yAxis); else v1 = normalDir.Cross(xAxis); v2 = v1.Cross(normalDir); v1.Normalize(); v2.Normalize(); v1 *= x; v2 *= y; newN = hInfo.N + v1+ v2; newN.Normalize(); } else{ newN = hInfo.N; } //------------------------------------- Point3 N = newN;//hInfo.N; Point3 V = Point3(iRay.p.x - P.x, iRay.p.y - P.y, iRay.p.z - P.z); // V.Normalize(); Point3 VR = 2 * V.Dot(N) * N - V; Cone rRay = Cone(P + BIAS_SHADING * VR, VR); rRay.dir.Normalize(); HitInfo temp; temp.Init(); temp.timeInstance=hInfo.timeInstance; if(rootNode.GetNumChild()>0){ if(RayTrace_2(rRay, temp)){ bounceCount--; rShade = reflection.GetColor().r * temp.node->GetMaterial()->Shade(rRay, temp, lights, bounceCount); } else{ rShade = reflection.GetColor().r *environment.SampleEnvironment(rRay.dir); // rShade = Color(1,111,1); } } } /* Add shade with reflected and refracted colors */ shade += (rShade + tShade); return shade; };
void doRender(void* arg){ RenderParams rarg = *((RenderParams *)arg); //cout<<"Do render...."<<endl; bool pixelHit=false; HitInfo hitInfo; hitInfo.Init(); Point2 pixLoc = rarg.pixLocation; Cone r = rarg.ray; int PixIndex = rarg.pixIndex; Color shade(0,0,0); vector<Point2> haltonXY; float dx = rarg.PixParams.x; float dy = rarg.PixParams.y; float x=0; float y=0; _f.Normalize(); _s.Normalize(); const float pts[9]={_s.x,_u.x,-_f.x,_s.y,_u.y,-_f.y,_s.z,_u.z,-_f.z}; Matrix3 RotMat; RotMat.Set(pts); for(int i=0; i < MIN_N_SAMPLES; i++){ x = dx * Halton(i+1, H_BASE_1); y = dy * Halton(i+1, H_BASE_2); if(x > dx * 0.5) { x -= dx; } if(y < dy * 0.5) { y -= dy; } x += rarg.K.x; y += rarg.K.y; Point2 sampleLoc = Point2(x,y); haltonXY.push_back(sampleLoc); } vector<Color> shades; if(rootNode.GetNumChild()>0){ for(int i=0; i< MIN_N_SAMPLES;i++){ Point3 sampleDir = Point3(haltonXY.at(i).x, haltonXY.at(i).y, rarg.K.z); int rindex = rand() % MAX_N_SAMPLES; //rindex = i; Point3 randPos = rarg.ConfCirclePts.at(rindex); Cone sampleRay = Cone(randPos, sampleDir); sampleRay.dir = sampleRay.dir * RotMat; sampleRay.dir -= randPos - camera.pos; sampleRay.dir.Normalize(); sampleRay.radius = r.radius; sampleRay.tanAngle = r.tanAngle; r = sampleRay; if(RayTrace_2(r, hitInfo)) { pixelHit=true; shade = hitInfo.node->GetMaterial()->Shade(r, hitInfo, lights, 8); shades.push_back(shade); } hitInfo.Init(); } if(VarianceOverThreshold(shades)){ renderImage.SetSampleCountPixel(PixIndex, 255); hitInfo.Init(); for(int i=MIN_N_SAMPLES; i < MAX_N_SAMPLES; i++){ x = dx * Halton(i+1, H_BASE_1); y = dy * Halton(i+1, H_BASE_2); if(x > dx * 0.5) { x -= dx;} if(y < dy * 0.5) { y -= dy;} x += rarg.K.x; y += rarg.K.y; Point2 sampleLoc = Point2(x,y); haltonXY.push_back(sampleLoc); Point3 sampleDir = Point3(haltonXY.at(i).x, haltonXY.at(i).y, rarg.K.z); int rindex = rand() % MAX_N_SAMPLES; //rindex = i; Point3 randPos = rarg.ConfCirclePts.at(rindex); Cone sampleRay = Cone(randPos, sampleDir); sampleRay.dir = sampleRay.dir * RotMat; sampleRay.dir -= randPos - camera.pos; sampleRay.dir.Normalize(); sampleRay.radius = r.radius; sampleRay.tanAngle = r.tanAngle; r = sampleRay; if(RayTrace_2(r, hitInfo)) { pixelHit=true; shade = hitInfo.node->GetMaterial()->Shade(r, hitInfo, lights, 5); shades.push_back(shade); } hitInfo.Init(); } shade = AverageShades(shades, (int)shades.size()); } else{ shade = AverageShades(shades, (int)shades.size()); renderImage.SetSampleCountPixel(PixIndex, 0); } renderImage.PutPixel(PixIndex, shade, hitInfo.z); } if(!pixelHit){ Point3 uvw(pixLoc.x/ camera.imgWidth,pixLoc.y/camera.imgHeight,0); shade = background.Sample(uvw); renderImage.PutPixel(PixIndex, shade, BIGFLOAT); } pthread_mutex_lock(&setPix_mutex); renderImage.IncrementNumRenderPixel(1); pthread_mutex_unlock(&setPix_mutex); }
Color MtlBlinn::Shade(const Ray &ray, const HitInfo &hInfo, const LightList &lights, int bounceCount) const{ float bias = BIAS_SHADING; Color shade; Color rShade = Color(0,0,0); Color tShade = Color(0,0,0); const Material *mat; mat = hInfo.node->GetMaterial(); const MtlBlinn* mb =static_cast<const MtlBlinn*>(mat); // cout<<"HInfo front: "<<hInfo.front<<endl; /* local copy */ Point3 P; P.Set(hInfo.p.x,hInfo.p.y,hInfo.p.z); Ray iRay = ray; Color ambInt = mb->diffuse; Color allOther = Color(0,0,0); Color diffuse = mb->diffuse;; Color ambComponent = Color(0,0,0); for ( unsigned int i=0; i<lights.size(); i++ ) { if(lights[i]->IsAmbient()){ // cout<<"ambient "<<endl; Color intensity = lights[i]->Illuminate(hInfo.p); ambComponent += (ambInt * intensity); continue; } else{ // cout<<"other lighting "<<endl; Point3 L = -lights[i]->Direction(P); L.Normalize(); Point3 V = ray.p - P; V.Normalize(); Point3 LplusV = L + V; Point3 H = (L+V)/LplusV.Length(); H.Normalize(); float alpha = mb->glossiness; Point3 N = hInfo.N; float S = H.Dot(N); S = pow(S,alpha); float costheta = L.Dot(N)/(L.Length() * N.Length()); Color intensity = lights[i]->Illuminate(P); // cout<<"costheta "<<endl; allOther += intensity * (costheta>0?costheta:0) * (diffuse + S * (mb->specular)) ; } /* finally add inta*cola + intall*costheta*(cold + s* colS)*/ shade = ambComponent + allOther; } /* Calculate refraction */ if(refraction.Grey()>0 && bounceCount>0){ Color reflShade = Color(0,0,0); float R0, Refl = 0.0f, Trans = 0.0f; HitInfo temp; temp.Init(); Point3 N = hInfo.N; // Point3 V = Point3(iRay.p.x - hInfo.p.x, iRay.p.y - hInfo.p.y, iRay.p.z - hInfo.p.z); Point3 V = Point3(hInfo.p.x - iRay.p.x, hInfo.p.y - iRay.p.y, hInfo.p.z - iRay.p.z); V.Normalize(); float n1 = 1, n2 = 1; if(hInfo.front){ /* Hitting from outside */ // temp.front = false; n2 = ior; // cout<<"outside "<<endl; } else if(!hInfo.front){ /* Transmission from the inside */ // temp.front = true; n1 = ior; // cout<<"intside... "<<endl; N = -hInfo.N; } float ratio_n = n1 / n2; float costheta_v = -V.Dot(N); /* refer: http://graphics.stanford.edu/courses/cs148-10-summer/docs/2006--degreve--reflection_refraction.pdf */ float sin2theta_t = ratio_n * ratio_n * (1 - costheta_v * costheta_v); Point3 T = ratio_n * V + (ratio_n * costheta_v - sqrtf(1 - sin2theta_t)) * N ; // cout<<ratio_n<<" "<<"cos_v "<<costheta_v<<" sin2theta_t "<<sin2theta_t<<endl; Ray tRay = Ray(hInfo.p,T); //tRay.dir.Normalize(); tRay.p.x = tRay.p.x + bias *tRay.dir.x; /* add bias */ tRay.p.y = tRay.p.y + bias *tRay.dir.y; tRay.p.z = tRay.p.z + bias *tRay.dir.z; // cout<<"B temp front: "<< temp.front<<endl; if(sin2theta_t <= 1){ if(RayTrace_2(tRay, temp)){ // bounceCount--; // cout<<"A temp front: "<< temp.front<<endl; tShade = temp.node->GetMaterial()->Shade(tRay,temp,lights,bounceCount); tShade.r *= exp(-absorption.r * temp.z); tShade.g *= exp(-absorption.g * temp.z); tShade.b *= exp(-absorption.b * temp.z); // shade = tShade; /* remove later */ // return shade; /* Calculate Schlick's approximation */ R0 = (n1 - n2)/(n1 + n2); R0 *= R0; double X = 0.0; // if(n1 > n2){ // X = 1.0 - sqrtf(1.0 - sin2theta_t); // } // else{ X = 1.0 - costheta_v; } X = 1.0 - costheta_v; Refl = R0 + (1.0 - R0) * X * X * X * X * X; Trans = 1.0 - Refl; } } else {/* Total internal reflection */ Refl = 1.0f; } /* Calculate reflection due to reflectance */ if(bounceCount >0){ N = hInfo.N; Point3 V = Point3(iRay.p.x - P.x, iRay.p.y - P.y, iRay.p.z - P.z); //V.Normalize(); Point3 VR = 2 * V.Dot(N) * N - V; //VR.Normalize(); Ray rRay = Ray(P, VR); //rRay.dir.Normalize(); rRay.p.x = rRay.p.x + bias *rRay.dir.x; rRay.p.y = rRay.p.y + bias *rRay.dir.y; rRay.p.z = rRay.p.z + bias *rRay.dir.z; HitInfo temp1; temp1.Init(); if(rootNode.GetNumChild()>0){ if(RayTrace_2(rRay, temp1)){ bounceCount --; reflShade = temp1.node->GetMaterial()->Shade(rRay, temp1, lights, bounceCount); } } } // cout<<"Refl: "<<Refl<<"Trans "<<Trans<<endl; tShade = refraction * (Trans * tShade + Refl * reflShade); } /* calculate reflection*/ if(reflection.Grey()>0 && bounceCount > 0){ Point3 N = hInfo.N; Point3 V = Point3(iRay.p.x - P.x, iRay.p.y - P.y, iRay.p.z - P.z); // V.Normalize(); Point3 VR = 2 * V.Dot(N) * N - V; Ray rRay = Ray(hInfo.p, VR); //rRay.dir.Normalize(); rRay.p.x = rRay.p.x + bias *rRay.dir.x; rRay.p.y = rRay.p.y + bias *rRay.dir.y; rRay.p.z = rRay.p.z + bias *rRay.dir.z; HitInfo temp; temp.Init(); if(rootNode.GetNumChild()>0){ if(RayTrace_2(rRay, temp)){ bounceCount--; rShade = reflection * temp.node->GetMaterial()->Shade(rRay, temp, lights, bounceCount); } } } /* Add shade with reflected and refracted colors */ shade += (rShade + tShade); return shade; };
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(); }