void RayTracer::traceOnePixel(int x, int y, int threadID) { //used for constructing viewport Vector2 tmp(m_settings.width, m_settings.height); Ray primaryRay; // If one ray per pixel: (kinda debugging mode with blue color for places with no surfel hit if (m_settings.raysPerPixel == 1){ //Get the primary ray from the pixel x,y primaryRay = m_camera->worldRay(x + 0.5f, y + 0.5f, Rect2D(tmp)); //Get the first surfel hit. //Can't call L_i unfortunately because we want the blue background for debugging const shared_ptr<Surfel>& s = RayTracer::castRay(primaryRay, finf(), 0); //If there is a surfel hit, get the direct illumination value and apply to the pixel if (s){ //Call L_scatteredDirect to get direct illumination. Invert primaryRay to get the direction for incident light m_image->set(Point2int32(x,y), L_o(s, -primaryRay.direction(), m_settings.recursiveBounces, *(m_rnd[threadID]))); } else{ //Set the pixels with no surfel hit. Include this line so we could make it a specific color for debug purposes. m_image->set(Point2int32(x,y), Color3(0,0,1)); } } else { Radiance3 L(0,0,0); //If more than one ray, randomly generate required number of rays within the pixel for (int i = 0; i < m_settings.raysPerPixel; ++i){ primaryRay = m_camera->worldRay(x + m_rnd[threadID]->uniform(), y + m_rnd[threadID]->uniform(), Rect2D(tmp)); L += L_i(primaryRay.origin(), primaryRay.direction(), m_settings.recursiveBounces, *(m_rnd[threadID])); } m_image->set(Point2int32(x,y), L/m_settings.raysPerPixel); } }
void RayTracer::maybeUpdatePhotonMap() { if ((m_scene->lastVisibleChangeTime() > m_photonMapUpdateTime) || (m_scene->lastLightChangeTime() > m_photonMapUpdateTime)) { app->drawMessage("Tracing Photons"); m_photonMap.clear(m_settings.photon.maxGatherRadius, 26500); m_buildPhotonMapTimeMilliseconds = 0; m_photonTraceTimeMilliseconds = 0; computeTotalIndirectProducingLightPower(); if ((m_settings.photon.numEmitted > 0) && m_totalIndirectProducingLightPower.nonZero()) { const int numThreads = m_settings.multithreaded ? System::numCores() : 1; m_photonList.clear(); m_photonList.resize(numThreads); { const RealTime start = System::time(); GThread::runConcurrently2D (Point2int32(0, 0), Point2int32(1, m_settings.photon.numEmitted), this, &RayTracer::traceOnePhoton, numThreads); m_photonTraceTimeMilliseconds = float((System::time() - start) / units::milliseconds()); } { const RealTime start = System::time(); for (int t = 0; t < numThreads; ++t) { m_photonMap.insert(m_photonList[t]); } m_buildPhotonMapTimeMilliseconds = float((System::time() - start) / units::milliseconds()); } } // If compute photons // Record the time at which we updated the photon map m_photonMapUpdateTime = System::time(); m_photonMap.debugPrintStatistics(); } }
void RayTracer::traceAllPixels(int numThreads) { for (int i = 0; i < m_lighting.lightArray.size(); ++i) { const shared_ptr<Light> light(m_lighting.lightArray[i]); debugAssertM(light->frame().translation.isFinite(), format("Light %s is not at a finite location", light->name().c_str())); } GThread::runConcurrently2D (Point2int32(0, 0), Point2int32(m_image->width(), m_image->height()), this, &RayTracer::traceOnePixel, numThreads); }
void App::rayTraceImage(float scale, int numRays) { int width = int(window()->width() * scale); int height = int(window()->height() * scale); if (isNull(m_currentImage) || (m_currentImage->width() != width) || (m_currentImage->height() != height)) { m_currentImage = Image3::createEmpty(width, height); } m_currentRays = numRays; GThread::runConcurrently2D(Point2int32(0, 0), Point2int32(width, height), this, &App::trace); // Post-process shared_ptr<Texture> src = Texture::fromImage("Source", m_currentImage); if (m_result) { m_result->resize(width, height); } m_film->exposeAndRender(renderDevice, m_debugCamera->filmSettings(), src, m_result); }
void App::pathTraceImage() { tick(); for (int i = 0; i < m_rng.size(); ++i) m_rng[i].reset(uint32(System::time()) ^ i); GThread::runConcurrently2D(Point2int32(0, 0), Point2int32(m_imgWidth, m_imgHeight), this, &App::samplePixel); float sampleAvg = m_featureData.getSamplesPerPixelAvg(); m_featureData.substractFromSampleBudget(sampleAvg); char numStr[20]; sprintf(numStr,"%2.2f",sampleAvg); m_sampleCountPtrString.setValue(String(numStr)); // Post-processing shared_ptr<Texture> src = Texture::fromImage("Source", m_featureData.getImageMean(CBFilter::FT_COLOR)); if (m_result) { m_result->resize(m_imgWidth, m_imgHeight); } m_film->exposeAndRender(renderDevice, m_debugCamera->filmSettings(), src, m_result); for (int j = 0; j < CBFilter::FT_SIZE; j++) { m_featureTextures[j][MEAN] = Texture::fromImage(m_featureNames[j]+String(" mean"),m_featureData.getImageMean(j,j == CBFilter::FT_DEPTH)); m_featureTextures[j][VAR] = Texture::fromImage(m_featureNames[j]+String(" variance"),m_featureData.getImageVar(j,false)); for (int k = 0 ; k < 2 ; k++) { m_textureBox[j][k]->setTexture(m_featureTextures[j][k]); m_textureBox[j][k]->zoomToFit(); } } tock("Path tracing"); }
void RayTracer::traceAllPixels(int numThreads) { //Trace the pixels concurrently GThread::runConcurrently2D(Point2int32(0,0), Point2int32(m_settings.width, m_settings.height), this, &RayTracer::traceOnePixel, numThreads); }