Example #1
0
vector<vec3f> PhotonMap::renderPixels(const Camera& camera){
	uint width = camera.width, height = camera.height;
	std::vector<vec3f> pixelColors(width * height, vec3f(0,0,0));
		
	omp_init_lock(&surfaceHashGridLock);
	omp_init_lock(&volumeHashGridLock);
	omp_init_lock(&debugPrintLock);

	//std::vector<int> pixelMaps(pixelColors.size(), 0);

	preprocessEmissionSampler();
		
	mRadius = mBaseRadius;

	clock_t startTime = clock();

	for(uint s = 0; s < spp; s++){
		std::cout << "iteration : " << s << std::endl;
		
		std::vector<vec3f> oneIterColors(pixelColors.size(), vec3f(0,0,0));
#ifdef PPM
		//if (renderer->scene.getTotalVolume() > 1e-6f)
		if (true)
		{
			rayMarching = true;
			mRadius = MAX(mBaseRadius * powf(powf(s+1 , mAlpha-1) , 1.f / 3.f) , EPSILON);
		}
		else
		{
			rayMarching = false;
			mRadius = MAX(mBaseRadius * sqrt(powf(s+1, mAlpha-1)), EPSILON);
		}
#endif
		std::vector<Path*> pixelLightPaths(mPhotonsNum, NULL);
		std::vector<LightPoint> surfaceLightVertices(0);
		std::vector<LightPoint> volumeLightVertices(0);

		surfaceHashGrid.Reserve(pixelColors.size());
		volumeHashGrid.Reserve(pixelColors.size());

#pragma omp parallel for
		// step1: sample light paths and build range search struct independently for surface and volume
		for(int p = 0; p < mPhotonsNum; p++){
			Ray lightRay = genEmissiveSurfaceSample(true , false);
			pixelLightPaths[p] = new Path;
			Path &lightPath = *pixelLightPaths[p];
			samplePath(lightPath, lightRay);
			for(int i = 1; i < lightPath.size(); i++){
				// light is not reflective
				if(lightPath[i].contactObject && lightPath[i].contactObject->emissive())
					break;
				// only store particles non-specular
				if(lightPath[i].directionSampleType == Ray::DEFINITE)
					continue;
				LightPoint lightPoint;
				lightPoint.position = lightPath[i].origin;
				lightPoint.indexInThePath = i;
				lightPoint.pathThePointIn = &lightPath;
				lightPoint.photonType = lightPath[i].photonType;
				if(lightPoint.photonType == Ray::OUTVOL){
					omp_set_lock(&surfaceHashGridLock);
					surfaceLightVertices.push_back(lightPoint);
					omp_unset_lock(&surfaceHashGridLock);
				}
				if(lightPoint.photonType == Ray::INVOL){
					omp_set_lock(&volumeHashGridLock);
					volumeLightVertices.push_back(lightPoint);
					omp_unset_lock(&volumeHashGridLock);
				}
			}
		}
		std::cout<< "vol vertices= " << volumeLightVertices.size() << " sur vertices= " << surfaceLightVertices.size() << std::endl;
			
		surfaceHashGrid.Build(surfaceLightVertices, mRadius);
		volumeHashGrid.Build(volumeLightVertices, mRadius);

		std::cout<< "finish building hashgrid" << std::endl;

		// step2: calculate pixel colors by progressive photon mapping
#pragma omp parallel for
		for(int p = 0; p < pixelColors.size(); p++){
			Path eyePath;
			if (rayMarching)
				sampleMergePath(eyePath, camera.generateRay(p), 0);
			else
				samplePath(eyePath, camera.generateRay(p));

			//fprintf(fp , "===================\n");
			//for (int i = 0; i < eyePath.size(); i++)
			//{
			//	fprintf(fp , "l=%d, bsdf=(%.8f,%.8f,%.8f), originPdf=%.8f, dirPdf=%.8f\n" , i , eyePath[i].color.x ,
			//		eyePath[i].color.y , eyePath[i].color.z , eyePath[i].originProb , eyePath[i].directionProb);
			//}

			/*if(eyePath[1].contactObj && eyePath[1].contactObj->anisotropic()){
				pixelMaps[p] = 1;
			}*/
			throughputByDensityEstimation(oneIterColors[p], eyePath, surfaceLightVertices, volumeLightVertices);
		}
		/*std::ofstream fout(engine->renderer->name + engine->scene.name+"pixelMap.txt");
		for(int p = 0; p < pixelMaps.size(); p++)
			fout << pixelMaps[p] << ' ' ;
		fout << std::endl;
		fout.close();*/

		std::cout << "calculation done" << std::endl;

		for(uint i = 0; i < pixelColors.size(); i++){
			pixelColors[i] *= s / float(s+1);
			pixelColors[i] += camera.eliminateVignetting(oneIterColors[i], i) / (s + 1);
			delete pixelLightPaths[i];
		}

		unsigned nowTime = (float)(clock() - startTime) / 1000;
		//if (nowTime > recordTime)
		if (s % outputIter == 0)
		{
			showCurrentResult(pixelColors , &nowTime , &s);
			//showCurrentResult(pixelColors , &lastTime , &s);
			//recordTime += timeInterval;
		}
		else
			showCurrentResult(pixelColors);
	}
	return pixelColors;
}
Example #2
0
void IptTracer::genIntermediatePaths(omp_lock_t& cmdLock , vector<Path*>& interPathList)
{
#pragma omp parallel for
	for(int p=0; p<interPathNum; p++)
	{
		if (!renderer->scene.usingGPU())
		{
			Ray interRay = genIntermediateSamples(renderer->scene);
			interPathList[p] = new Path;
			samplePath(*interPathList[p] , interRay);
		}

		Path& interPath = *interPathList[p];

		//fprintf(fp , "=================\n");
		partPathMergeIndex[p].clear();

		if (interPath.size() <= 1)
			continue;

		IptPathState interState;
		interState.originRay = &interPath[0];

		interState.throughput = interPath[0].color * interPath[0].getCosineTerm() / 
			(interPath[0].originProb * interPath[0].directionProb * interPath[1].originProb);
		interState.indirContrib = vec3f(0.f);
		interState.mergedPath = 0;

		//if (intensity(interState.throughput) > 30.f)
		//	continue;

		/*
		fprintf(fp , "====================\n");
		vec3f decay = interPath[0].getRadianceDecay((interPath[0].origin - interPath[1].origin).length());
		fprintf(fp , "l = 0 , thr = (%.8f,%.8f,%.8f) , color = (%.8f,%.8f,%.8f)\ncosine = %.8f , dirPdf = %.8f , oPdf = %.8f\ndecay=(%.8f,%.8f,%.8f)\n" , 
			interState.throughput.x , interState.throughput.y , interState.throughput.z ,
			interPath[0].color[0] , interPath[0].color[1] , interPath[0].color[2] ,
			interPath[0].getCosineTerm() , interPath[0].directionProb , interPath[1].originProb ,
			decay.x , decay.y , decay.z);
		*/

		for(unsigned i = 1; i < interPath.size(); i++)
		//for (unsigned i = 1; i < 2; i++)
		{
			Real dist = std::max((interPath[i].origin - interPath[i - 1].origin).length() , 1e-5f);
			interState.throughput *= interPath[i - 1].getRadianceDecay(dist);

			if(interPath[i].contactObject && interPath[i].contactObject->emissive())
				break;

			interState.pos = interPath[i].origin;
			interState.lastRay = &interPath[i - 1];
			interState.ray = &interPath[i];
			interState.pathLen = i;
			
			if(interPath[i].directionSampleType != Ray::DEFINITE &&
				(interPath[i].insideObject != NULL || interPath[i].contactObject != NULL) &&
				(interPath[i].origin != interPath[i - 1].origin))
				//(interPath[i].insideObject && !interPath[i].contactObject)) // only volume
			{
				//fprintf(fp , "path length = %d, dirContrib = (%.8f,%.8f,%.8f)\n" , 
				//	i , interState.dirContrib[0] , interState.dirContrib[1] , interState.dirContrib[2]);

				omp_set_lock(&cmdLock);
				partialSubPathList.push_back(interState);
				partPathMergeIndex[p].push_back(partialSubPathList.size() - 1);
				omp_unset_lock(&cmdLock);
			}

			if (i == interPath.size() - 1)
				break;
			if (interPath[i].direction.length() < 0.5f)
				break;

			vec3f scatterFactor = (interPath[i].color * interPath[i].getCosineTerm() / 
				(interPath[i + 1].originProb * interPath[i].directionProb));

			interState.throughput *= scatterFactor;
			
			/*
			vec3f decay = interPath[i].getRadianceDecay((interPath[i].origin - interPath[i + 1].origin).length());
			fprintf(fp , "l = %d , thr = (%.8f,%.8f,%.8f) , color = (%.8f,%.8f,%.8f)\ncosine = %.8f , dirPdf = %.8f , oPdf = %.8f\ndecay=(%.8f,%.8f,%.8f)\n" , 
				i , interState.throughput.x , interState.throughput.y , interState.throughput.z ,
				interPath[i].color[0] , interPath[i].color[1] , interPath[i].color[2] ,
				interPath[i].getCosineTerm() , interPath[i].directionProb , interPath[i + 1].originProb ,
				decay.x , decay.y , decay.z);
			*/

			if (interPath[i].directionSampleType != Ray::DEFINITE && useWeight)
			{
				Real pdf = interPath[i].directionProb;
				if (pdf < 1e-7f)
					break;

				Real weightFactor;

				Real volMergeScale = 1.f;
				Real originProb;
				Real dirProb;
				if (interPath[i].contactObject)
				{
					if (useUniformSur)
						originProb = 1.f / totArea;
					else
						originProb = interPath[i].contactObject->getOriginProb(interPath[i].contactObjectTriangleID);
					if (useUniformDir)
						dirProb = INV_2_PI;
					else
						dirProb = interPath[i].getCosineTerm() / M_PI;
				}

				//if (interPath[i].insideObject && interPath[i].contactObject)
				//	printf("!!!\n");
				if (interPath[i].insideObject && !interPath[i].contactObject && interPath[i].insideObject->isVolumetric())
				{
					volMergeScale = 4.f / 3.f * mergeRadius;
					if (useUniformVol)
						originProb = 1.f / totVol;
					else
						originProb = interPath[i].insideObject->getOriginProb(interPath[i].origin);
					dirProb = 0.25f / M_PI;
				}
				
				weightFactor = connectFactor(pdf) /
					(connectFactor(pdf) + mergeFactor(&volMergeScale , &originProb , &dirProb , &partialPathNum));

				if (_isnan(weightFactor) || abs(pdf) < 1e-6f)
				{
					fprintf(err , "sample inter path error, %.8f , %.8f\n" , connectFactor(pdf) , 
						mergeFactor(&volMergeScale , &originProb , &dirProb , &partialPathNum));
				}

				//if (interPath[i].contactObject && interPath[i].contactObject->objectIndex == 7)
				interState.throughput *= weightFactor;
			}
		}
	}

	partialPhotonNum = partialSubPathList.size();
}
Example #3
0
void IptTracer::genLightPaths(omp_lock_t& cmdLock , vector<Path*>& lightPathList , bool isFirstIter)
{
#pragma omp parallel for
	for(int p=0; p<lightPathNum; p++)
	{
		if (!renderer->scene.usingGPU())
		{
			Ray lightRay = genEmissiveSurfaceSample(true , false);
			lightPathList[p] = new Path;
			samplePath(*lightPathList[p] , lightRay);
		}
		
		Path& lightPath = *lightPathList[p];

		if (lightPath.size() <= 1)
			continue;

		IptPathState lightState;
		lightState.originRay = &lightPath[0];

		Real cosAtLight = lightPath[0].getCosineTerm();

		lightState.throughput = lightPath[0].color * cosAtLight / 
			(lightPath[0].originProb * lightPath[0].directionProb *
			lightPath[1].originProb);
		lightState.indirContrib = vec3f(0.0);
		lightState.mergedPath = 1;
		/*
		fprintf(fp , "====================\n");
		vec3f decay = lightPath[0].getRadianceDecay((lightPath[0].origin - lightPath[1].origin).length());
		fprintf(fp , "l = 0 , thr = (%.8f,%.8f,%.8f) , color = (%.8f,%.8f,%.8f)\ncosine = %.8f , dirPdf = %.8f , oPdf = %.8f\ndecay=(%.8f,%.8f,%.8f)\n" , 
			lightState.throughput.x , lightState.throughput.y , lightState.throughput.z ,
			lightPath[0].color[0] , lightPath[0].color[1] , lightPath[0].color[2] ,
			lightPath[0].getCosineTerm() , lightPath[0].directionProb , lightPath[1].originProb ,
			decay.x , decay.y , decay.z);
		*/
		int nonSpecPathLength = 0;

		for(unsigned i = 1; i < lightPath.size(); i++)
		//for (unsigned i = 1; i < 2; i++)
		{
			Real dist = std::max((lightPath[i].origin - lightPath[i - 1].origin).length() , 1e-5f);
			vec3f decayFactor = lightPath[i - 1].getRadianceDecay(dist);
			lightState.throughput *= decayFactor;

			if(lightPath[i].contactObject && lightPath[i].contactObject->emissive())
				break;

			lightState.pos = lightPath[i].origin;
			lightState.lastRay = &lightPath[i - 1];
			lightState.ray = &lightPath[i];
			lightState.pathLen = i;

			if(lightPath[i].directionSampleType == Ray::RANDOM &&
				(lightPath[i].insideObject != NULL || lightPath[i].contactObject != NULL) && 
				(lightPath[i].origin != lightPath[i - 1].origin))
			{
				//if (lightPath[i].insideObject && !lightPath[i].contactObject)
				//	fprintf(fp , "path length = %d, dirContrib = (%.8f,%.8f,%.8f)\n" , 
				//		i , lightState.dirContrib[0] , lightState.dirContrib[1] , lightState.dirContrib[2]);

				omp_set_lock(&cmdLock);
				partialSubPathList.push_back(lightState);
				omp_unset_lock(&cmdLock);
			}

			if (i == lightPath.size() - 1)
				break;
			if (lightPath[i].direction.length() < 0.5f)
				break;

			vec3f scatterFactor = (lightPath[i].color * lightPath[i].getCosineTerm() / 
				(lightPath[i + 1].originProb * lightPath[i].directionProb));

			lightState.throughput *= scatterFactor;
			/*
			vec3f decay = lightPath[i].getRadianceDecay((lightPath[i].origin - lightPath[i + 1].origin).length());
			fprintf(fp , "l = %d , thr = (%.8f,%.8f,%.8f) , color = (%.8f,%.8f,%.8f)\ncosine = %.8f , dirPdf = %.8f , oPdf = %.8f\ndecay=(%.8f,%.8f,%.8f)\n" , 
				i , lightState.throughput.x , lightState.throughput.y , lightState.throughput.z ,
				lightPath[i].color[0] , lightPath[i].color[1] , lightPath[i].color[2] ,
				lightPath[i].getCosineTerm() , lightPath[i].directionProb , lightPath[i + 1].originProb ,
				decay.x , decay.y , decay.z);
			*/
			if (lightPath[i].directionSampleType == Ray::RANDOM && useWeight)
			{
				Real pdf = lightPath[i].directionProb;
				if (pdf < 1e-7f)
					break;

				Real weightFactor;

				Real volMergeScale = 1;
				Real originProb;
				Real dirProb;
				if (lightPath[i].contactObject)
				{
					if (isFirstIter || useUniformSur)
						originProb = 1.f / totArea;
					else
						originProb = lightPath[i].contactObject->getOriginProb(lightPath[i].contactObjectTriangleID);
					if (useUniformDir)
						dirProb = INV_2_PI;
					else
						dirProb = lightPath[i].getCosineTerm() / M_PI;
				}

				//if (lightPath[i].insideObject && lightPath[i].contactObject)
				//	printf("!!!\n");
				if (lightPath[i].insideObject && !lightPath[i].contactObject && lightPath[i].insideObject->isVolumetric())
				{
					volMergeScale = 4.f / 3.f * mergeRadius;

					if (isFirstIter || useUniformVol)
						originProb = 1.f / totVol;
					else
						originProb = lightPath[i].insideObject->getOriginProb(lightPath[i].origin);
					
					dirProb = 0.25f / M_PI;
				}

				weightFactor = connectFactor(pdf) /
					(connectFactor(pdf) + mergeFactor(&volMergeScale , &originProb , &dirProb , &lightPathNum));

				if (_isnan(weightFactor) || abs(pdf) < 1e-6f)
				{
					fprintf(err , "sample light path error, %.8f , %.8f\n" , connectFactor(pdf) , 
						mergeFactor(&volMergeScale , &originProb , &dirProb , &lightPathNum));
				}
				/*
				if (abs(volMergeScale - 1.f) < 1e-6)
					printf("surface %.8f\n" , weightFactor);
				else
					printf("volume %.8f %.8f\n" , weightFactor);
				*/

				//if (lightPath[i].contactObject && lightPath[i].contactObject->objectIndex == 7)
				lightState.throughput *= weightFactor;
			}
		}
	}

	lightPhotonNum = partialPhotonNum = partialSubPathList.size();
}
Example #4
0
 bool transform1(IHypergraph<Arc> const& i, IMutableHypergraph<Arc>* o) {
   UniformInArcSampler<Arc> sampler;
   samplePath(i, sampler, o);
   return true;
 }
Example #5
0
	std::vector<vec3f> PathTracer::renderPixels(){
		Camera &camera = getCamera();
		uint width = camera.mResolution.x, height = camera.mResolution.y;
		std::vector<vec3f> pixelColors(width * height, vec3f(0,0,0));
		
		if(useNextEventEstimation)
			prepareForLightSampling();

		for(uint s = 0; s < spp; s++){
			std::cout << "iteration : " << s << std::endl;
			
			engine->scene.updateSceneForMotionBlur();

#pragma omp parallel for
			for(int p = 0; p < pixelColors.size(); p++){
				Path eyePath;
				samplePath(eyePath, camera.generateRay(p));
				pixelColors[p] *= s / float(s+1);
				vec3f color = vec3f(1,1,1);

				bool hasToConnect = eyePath[eyePath.size()-1].radiance.length() <= 0;

				if(!useNextEventEstimation || !hasToConnect){
					for(int i = 0; i < eyePath.size(); i++){
						if(i != eyePath.size() - 1){
							color *= eyePath[i].cosineTerm();
							float dist = (eyePath[i+1].origin - eyePath[i].origin).length();
							color *= eyePath[i].radianceDecay(dist);
						}
						color *= eyePath[i].radiance / eyePath[i].originProb / eyePath[i].directionProb;
					}
				}
				else{
					int endIndex = (eyePath.back().contactObj || eyePath.back().insideObj) ? -1 : eyePath.size()-2;
					if(endIndex <= 0)											continue;

					Ray &endRay = eyePath[endIndex], lightRay = genLightSample();
					if(endRay.contactObj && endRay.contactObj->isEmissive())	continue;
					if(endRay.contactObj && !endRay.contactObj->nonSpecular())	continue;

					endRay.direction = lightRay.origin - endRay.origin;
					endRay.direction.normalize();
					lightRay.direction = -endRay.direction;

					float connectDist = MAX((lightRay.origin - endRay.origin).length(), EPSILON);
					
					if(endRay.direction.dot(lightRay.contactNormal()) >= 0)		continue;
					
					if(!visibilityTest(endRay, lightRay))						continue;
					
					for(int i = 0; i < endIndex; i++){
						color *= eyePath[i].radiance / eyePath[i].originProb / eyePath[i].directionProb;
						color *= eyePath[i].cosineTerm();
						float dist = (eyePath[i+1].origin - eyePath[i].origin).length();
						color *= eyePath[i].radianceDecay(dist);
					}
					color *= eyePath[endIndex-1].evalBSDF(endRay) * lightRay.radiance * endRay.radianceDecay(connectDist)
						* lightRay.cosineTerm() * endRay.cosineTerm() / (connectDist * connectDist);
					color /= eyePath[endIndex].originProb * lightRay.originProb;
				}
				if(!isLegalColor(color))
					color = vec3f(0,0,0);
				pixelColors[p] += camera.fixVignetting(color, p) / (s+1);
			}
			camera.mFilm.setBuffer(pixelColors);
			std::string filename = engine->renderer->name + engine->scene.name + ".pfm";
			camera.mFilm.savePFM(filename);
		}
		return pixelColors;
	}
Example #6
0
vector<vec3f> PathTracer::renderPixels(const Camera& camera)
{
	int t_start = clock();
	vector<vec3f> pixelColors(camera.width*camera.height, vec3f(0, 0, 0));

	if(useConnection)
		renderer->scene.preprocessEmissionSampler();

	if(!renderer->scene.usingGPU())
	{
		for(unsigned s=0; s<spp; s++)
		{
			int t = clock();
#pragma omp parallel for
			for(int p=0; p<pixelColors.size(); p++)
			{
				Path eyePath;
				samplePath(eyePath, camera.generateRay(p));

				pixelColors[p] *= s/float(s+1);

				if (!(eyePath.back().contactObject && eyePath.back().contactObject->emissive()))
					continue;

				vec3f color = vec3f(1, 1, 1);
				for(unsigned i=0; i<eyePath.size(); i++)
				{
					color *= eyePath[i].color / eyePath[i].directionProb / eyePath[i].originProb;
				
					if(i!=eyePath.size()-1)
					{
						color *= eyePath[i].getCosineTerm();
						float dist = (eyePath[i+1].origin - eyePath[i].origin).length();
						// NOTE: Must multiply the decay !!!!!!!!!
						color *= eyePath[i].getRadianceDecay(dist);
					}
				}

				pixelColors[p] += renderer->camera.eliminateVignetting(color, p)/(s+1);//*camera.width*camera.height;
				//pixelColors[p] += color * eyePath[0].directionProb / (s+1);
			}

			//if (clock() / 1000 >= lastTime)
			if (s % outputIter == 0)
			{
				unsigned nowTime = (clock()) / 1000;
				showCurrentResult(pixelColors , &nowTime , &s);
				//showCurrentResult(pixelColors , &lastTime , &s);
				//lastTime += timeInterval;
			}
			else
				showCurrentResult(pixelColors);
			printf("Iter: %d  IterTime: %ds  TotalTime: %ds\n", s+1, (clock()-t)/1000, (clock()-t_start)/1000);
		}
	}
	else
	{
		
		for(unsigned s=0; s<spp; s++)
		{
			int t = clock();
			vector<Ray> eyeRays(pixelColors.size());

#pragma omp parallel for
			for(int p=0; p<pixelColors.size(); p++)
			{
				eyeRays[p] = camera.generateRay(p);
			}

			int clk = clock();
			vector<Path> pathList = samplePathList(eyeRays);

			vector<Path> lightPathList;
			vector<vector<unsigned>> visList;

			if(useConnection)
			{
				lightPathList.resize(pathList.size());
				for(unsigned i=0; i<pathList.size(); i++)
					lightPathList[i].push_back(genEmissiveSurfaceSample(true , false));
				visList = testPathListVisibility(pathList, lightPathList);
			}

#pragma omp parallel for
			for(int p=0; p<pathList.size(); p++)
			{
				pixelColors[p] *= s/float(s+1);

				vec3f color = vec3f(0, 0, 0);

				//pathList[p][0].directionProb = 1.f;

				//if(!useConnection || mustUsePT(pathList[p]) || 
				//	pathList[p].size()==2 && pathList[p].back().contactObject && pathList[p].back().contactObject->emissive())
				if (pathList[p].back().contactObject && pathList[p].back().contactObject->emissive())
				{
					vec3f c(1, 1, 1);
					for(unsigned i=0; i<pathList[p].size(); i++)
					{
						c *= pathList[p][i].color / pathList[p][i].directionProb / pathList[p][i].originProb;

						if(i!=pathList[p].size()-1)
						{
							c *= pathList[p][i].getCosineTerm();
							float dist = (pathList[p][i+1].origin - pathList[p][i].origin).length();
							// NOTE: Must multiply the decay !!!!!!!!!
							c *= pathList[p][i].getRadianceDecay(dist);
						}
					}
					color += c;
				}
				/*
				else
				{
					Ray &lightRay = lightPathList[p][0];
					for(unsigned i=1; i<pathList[p].size(); i++)
					{
						if(!((visList[p][i/32]>>(i%32)) & 1))
							continue;
						Path connectedPath;
						connectedPath.push_back(lightRay);
						Path &eyePath = pathList[p];
						if(eyePath[i].contactObject && eyePath[i].contactObject->emissive())
							break;
						if(eyePath[i].directionSampleType != Ray::RANDOM)
							continue;
						for(unsigned k=0; k<=i; k++)
							connectedPath.push_back(eyePath[i-k]);
						connectRays(connectedPath, 0);
						vec4f color_prob = connectColorProb(connectedPath, 0);
						if(vec3f(color_prob).length()>0 && color_prob.w > 0)
							color += vec3f(color_prob) / color_prob.w;// / camera.width / camera.height;
					}
				}
				*/
				pixelColors[p] += renderer->camera.eliminateVignetting(color, p)/(s+1);//*camera.width*camera.height;
				//pixelColors[p] += color / (s+1);
			}

			//if (clock() / 1000 >= lastTime)
			if (s % outputIter == 0)
			{
				unsigned nowTime = (clock()) / 1000;
				showCurrentResult(pixelColors , &nowTime , &s);
				//showCurrentResult(pixelColors , &lastTime , &s);
				//lastTime += timeInterval;
			}
			else
				showCurrentResult(pixelColors);
			printf("Iter: %d  IterTime: %ds  TotalTime: %ds\n", s+1, (clock()-t)/1000, (clock()-t_start)/1000);
		}
	}
	return pixelColors;
}