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);
    }
}
Esempio n. 2
0
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();
    }
}
Esempio n. 3
0
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);
}
Esempio n. 4
0
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);
}
Esempio n. 5
0
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);
}