bool render(Scene *scene, RenderQueue *queue, const RenderJob *job, int sceneResID, int cameraResID, int unused) { ref<Scheduler> sched = Scheduler::getInstance(); ref<Camera> camera = scene->getCamera(); ref<Film> film = camera->getFilm(); size_t nCores = sched->getCoreCount(); Log(EInfo, "Starting render job (%ix%i, " SIZE_T_FMT " %s, " SSE_STR ") ..", film->getCropSize().x, film->getCropSize().y, nCores, nCores == 1 ? "core" : "cores"); Vector2i cropSize = film->getCropSize(); Point2i cropOffset = film->getCropOffset(); m_gatherBlocks.clear(); m_running = true; m_totalEmitted = 0; ref<Sampler> sampler = static_cast<Sampler *> (PluginManager::getInstance()-> createObject(MTS_CLASS(Sampler), Properties("independent"))); /* Allocate memory */ m_bitmap = new Bitmap(film->getSize().x, film->getSize().y, 128); m_bitmap->clear(); for (int yofs=0; yofs<cropSize.y; yofs += m_blockSize) { for (int xofs=0; xofs<cropSize.x; xofs += m_blockSize) { m_gatherBlocks.push_back(std::vector<GatherPoint>()); m_offset.push_back(Point2i(cropOffset.x + xofs, cropOffset.y + yofs)); std::vector<GatherPoint> &gatherPoints = m_gatherBlocks[m_gatherBlocks.size()-1]; int nPixels = std::min(m_blockSize, cropSize.y-yofs) * std::min(m_blockSize, cropSize.x-xofs); gatherPoints.resize(nPixels); for (int i=0; i<nPixels; ++i) gatherPoints[i].radius = m_initialRadius; } } /* Create a sampler instance for every core */ std::vector<SerializableObject *> samplers(sched->getCoreCount()); for (size_t i=0; i<sched->getCoreCount(); ++i) { ref<Sampler> clonedSampler = sampler->clone(); clonedSampler->incRef(); samplers[i] = clonedSampler.get(); } int samplerResID = sched->registerManifoldResource( static_cast<std::vector<SerializableObject*> &>(samplers)); #ifdef MTS_DEBUG_FP enableFPExceptions(); #endif int it=0; while (m_running) { distributedRTPass(scene, samplers); photonMapPass(++it, queue, job, film, sceneResID, cameraResID, samplerResID); } #ifdef MTS_DEBUG_FP disableFPExceptions(); #endif for (size_t i=0; i<sched->getCoreCount(); ++i) samplers[i]->decRef(); sched->unregisterResource(samplerResID); return true; }
bool render(Scene *scene, RenderQueue *queue, const RenderJob *job, int sceneResID, int cameraResID, int samplerResID) { ref<Scheduler> sched = Scheduler::getInstance(); ref<Camera> camera = scene->getCamera(); ref<Film> film = camera->getFilm(); size_t nCores = sched->getCoreCount(); Sampler *cameraSampler = (Sampler *) sched->getResource(samplerResID, 0); size_t sampleCount = cameraSampler->getSampleCount(); Log(EInfo, "Starting render job (%ix%i, " SIZE_T_FMT " %s, " SIZE_T_FMT " %s, " SSE_STR ") ..", film->getCropSize().x, film->getCropSize().y, sampleCount, sampleCount == 1 ? "sample" : "samples", nCores, nCores == 1 ? "core" : "cores"); Vector2i cropSize = film->getCropSize(); Point2i cropOffset = film->getCropOffset(); m_gatherPoints.clear(); m_running = true; for (size_t i=0; i<m_blocks.size(); ++i) m_blocks[i]->decRef(); m_blocks.clear(); m_totalEmitted = 0; bool needsLensSample = camera->needsLensSample(); bool needsTimeSample = camera->needsTimeSample(); Log(EInfo, "Creating approximately %i gather points", cropSize.x*cropSize.y*sampleCount); Point2 lensSample, sample; RayDifferential eyeRay; Float timeSample = 0; m_filter = camera->getFilm()->getTabulatedFilter(); Vector2 filterSize = m_filter->getFilterSize(); int borderSize = (int) std::ceil(std::max(filterSize.x, filterSize.y)); ref<Sampler> independentSampler = static_cast<Sampler *> (PluginManager::getInstance()-> createObject(MTS_CLASS(Sampler), Properties("independent"))); /* Create a sampler instance for every core */ std::vector<SerializableObject *> samplers(sched->getCoreCount()); for (size_t i=0; i<sched->getCoreCount(); ++i) { ref<Sampler> clonedSampler = independentSampler->clone(); clonedSampler->incRef(); samplers[i] = clonedSampler.get(); } int independentSamplerResID = sched->registerManifoldResource(samplers); for (size_t i=0; i<sched->getCoreCount(); ++i) samplers[i]->decRef(); #ifdef MTS_DEBUG_FP enableFPExceptions(); #endif /* Create gather points in blocks so that gathering can be parallelized later on */ for (int yofs=0; yofs<cropSize.y; yofs += m_blockSize) { for (int xofs=0; xofs<cropSize.x; xofs += m_blockSize) { ImageBlock *block = new ImageBlock(Vector2i(m_blockSize, m_blockSize), borderSize, true, true, false, false); block->setSize(Vector2i(m_blockSize, m_blockSize)); block->setOffset(Point2i(cropOffset.x + xofs, cropOffset.y + yofs)); block->incRef(); std::vector<GatherPoint> gatherPoints; gatherPoints.reserve(m_blockSize*m_blockSize*sampleCount); for (int yofsInt = 0; yofsInt < m_blockSize; ++yofsInt) { if (yofsInt + yofs >= cropSize.y) continue; for (int xofsInt = 0; xofsInt < m_blockSize; ++xofsInt) { if (xofsInt + xofs >= cropSize.x) continue; int y = cropOffset.y + yofs + yofsInt; int x = cropOffset.x + xofs + xofsInt; cameraSampler->generate(); for (size_t j = 0; j<sampleCount; j++) { if (needsLensSample) lensSample = cameraSampler->next2D(); if (needsTimeSample) timeSample = cameraSampler->next1D(); sample = cameraSampler->next2D(); sample.x += x; sample.y += y; camera->generateRayDifferential(sample, lensSample, timeSample, eyeRay); size_t offset = gatherPoints.size(); Float count = (Float) createGatherPoints(scene, eyeRay, sample, cameraSampler, Spectrum(1.0f), gatherPoints, 1); if (count > 1) { // necessary because of filter weight computation for (int i = 0; i<count; ++i) gatherPoints[offset+i].weight *= count; } cameraSampler->advance(); } } } m_blocks.push_back(block); m_gatherPoints.push_back(gatherPoints); } } int it=0; while (m_running) photonMapPass(++it, queue, job, film, sceneResID, cameraResID, independentSamplerResID); #ifdef MTS_DEBUG_FP disableFPExceptions(); #endif sched->unregisterResource(independentSamplerResID); return true; }