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; 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); }