void SamplingIntegrator::renderBlock(const Scene *scene, const Sensor *sensor, Sampler *sampler, ImageBlock *block, const bool &stop, const std::vector< TPoint2<uint8_t> > &points) const { Float diffScaleFactor = 1.0f / std::sqrt((Float) sampler->getSampleCount()); bool needsApertureSample = sensor->needsApertureSample(); bool needsTimeSample = sensor->needsTimeSample(); RadianceQueryRecord rRec(scene, sampler); Point2 apertureSample(0.5f); Float timeSample = 0.5f; RayDifferential sensorRay; block->clear(); uint32_t queryType = RadianceQueryRecord::ESensorRay; if (!sensor->getFilm()->hasAlpha()) /* Don't compute an alpha channel if we don't have to */ queryType &= ~RadianceQueryRecord::EOpacity; for (size_t i = 0; i<points.size(); ++i) { Point2i offset = Point2i(points[i]) + Vector2i(block->getOffset()); if (stop) break; sampler->generate(offset); for (size_t j = 0; j<sampler->getSampleCount(); j++) { rRec.newQuery(queryType, sensor->getMedium()); Point2 samplePos(Point2(offset) + Vector2(rRec.nextSample2D())); if (needsApertureSample) apertureSample = rRec.nextSample2D(); if (needsTimeSample) timeSample = rRec.nextSample1D(); Spectrum spec = sensor->sampleRayDifferential( sensorRay, samplePos, apertureSample, timeSample); sensorRay.scaleDifferential(diffScaleFactor); spec *= Li(sensorRay, rRec); block->put(samplePos, spec, rRec.alpha); sampler->advance(); } } }
void handleMiss(RayDifferential ray, const RadianceQueryRecord &rRec, Spectrum &E) const { /* Handle an irradiance cache miss */ HemisphereSampler *hs = m_hemisphereSampler.get(); Sampler *sampler = m_sampleGenerator.get(); RadianceQueryRecord rRec2; if (hs == NULL) { Properties props("independent"); sampler = static_cast<Sampler *> (PluginManager::getInstance()-> createObject(MTS_CLASS(Sampler), props)); hs = new HemisphereSampler(m_resolution, 2 * m_resolution); m_hemisphereSampler.set(hs); m_sampleGenerator.set(sampler); } /* Generate stratified cosine-weighted samples and compute rotational + translational gradients */ hs->generateDirections(rRec.its); sampler->generate(Point2i(0)); for (unsigned int j=0; j<hs->getM(); j++) { for (unsigned int k=0; k<hs->getN(); k++) { HemisphereSampler::SampleEntry &entry = (*hs)(j, k); entry.dist = std::numeric_limits<Float>::infinity(); rRec2.recursiveQuery(rRec, RadianceQueryRecord::ERadianceNoEmission | RadianceQueryRecord::EDistance); rRec2.extra = 1; rRec2.sampler = sampler; entry.L = m_subIntegrator->Li(RayDifferential(rRec.its.p, entry.d, ray.time), rRec2); entry.dist = rRec2.dist; sampler->advance(); } } hs->process(rRec.its); /* Undo ray differential scaling done by the integrator */ if (ray.hasDifferentials) ray.scaleDifferential(m_diffScaleFactor); m_irrCache->put(ray, rRec.its, *hs); E = hs->getIrradiance(); }
void SampleIntegrator::renderBlock(const Scene *scene, const Camera *camera, Sampler *sampler, ImageBlock *block, const bool &stop, const std::vector<Point2i> *points) const { Point2 sample, lensSample; RayDifferential eyeRay; Float timeSample = 0; Spectrum spec; block->clear(); RadianceQueryRecord rRec(scene, sampler); bool needsLensSample = camera->needsLensSample(); bool needsTimeSample = camera->needsTimeSample(); const TabulatedFilter *filter = camera->getFilm()->getTabulatedFilter(); Float scaleFactor = 1.0f/std::sqrt((Float) sampler->getSampleCount()); if (points) { /* Use a prescribed traversal order (e.g. using a space-filling curve) */ if (!block->collectStatistics()) { for (size_t i=0; i<points->size(); ++i) { Point2i offset = (*points)[i] + Vector2i(block->getOffset()); if (stop) break; sampler->generate(); for (size_t j = 0; j<sampler->getSampleCount(); j++) { rRec.newQuery(RadianceQueryRecord::ECameraRay, camera->getMedium()); if (needsLensSample) lensSample = rRec.nextSample2D(); if (needsTimeSample) timeSample = rRec.nextSample1D(); sample = rRec.nextSample2D(); sample.x += offset.x; sample.y += offset.y; camera->generateRayDifferential(sample, lensSample, timeSample, eyeRay); eyeRay.scaleDifferential(scaleFactor); spec = Li(eyeRay, rRec); block->putSample(sample, spec, rRec.alpha, filter); sampler->advance(); } } } else { Spectrum mean, meanSqr; for (size_t i=0; i<points->size(); ++i) { Point2i offset = (*points)[i] + Vector2i(block->getOffset()); if (stop) break; sampler->generate(); mean = meanSqr = Spectrum(0.0f); for (size_t j = 0; j<sampler->getSampleCount(); j++) { rRec.newQuery(RadianceQueryRecord::ECameraRay, camera->getMedium()); if (needsLensSample) lensSample = rRec.nextSample2D(); if (needsTimeSample) timeSample = rRec.nextSample1D(); sample = rRec.nextSample2D(); sample.x += offset.x; sample.y += offset.y; camera->generateRayDifferential(sample, lensSample, timeSample, eyeRay); eyeRay.scaleDifferential(scaleFactor); spec = Li(eyeRay, rRec); /* Numerically robust online variance estimation using an algorithm proposed by Donald Knuth (TAOCP vol.2, 3rd ed., p.232) */ const Spectrum delta = spec - mean; mean += delta / ((Float) j+1); meanSqr += delta * (spec - mean); block->putSample(sample, spec, rRec.alpha, filter); block->setVariance(offset.x, offset.y, meanSqr / (Float) j, (int) j+1); sampler->advance(); } } } } else { /* Simple scanline traversal order */ const int sx = block->getOffset().x, sy = block->getOffset().y, ex = sx + block->getSize().x, ey = sy + block->getSize().y; if (!block->collectStatistics()) { for (int y = sy; y < ey; y++) { for (int x = sx; x < ex; x++) { if (stop) break; sampler->generate(); for (size_t j = 0; j<sampler->getSampleCount(); j++) { rRec.newQuery(RadianceQueryRecord::ECameraRay, camera->getMedium()); if (needsLensSample) lensSample = rRec.nextSample2D(); if (needsTimeSample) timeSample = rRec.nextSample1D(); sample = rRec.nextSample2D(); sample.x += x; sample.y += y; camera->generateRayDifferential(sample, lensSample, timeSample, eyeRay); eyeRay.scaleDifferential(scaleFactor); spec = Li(eyeRay, rRec); block->putSample(sample, spec, rRec.alpha, filter); sampler->advance(); } } } } else { Spectrum mean, meanSqr; for (int y = sy; y < ey; y++) { for (int x = sx; x < ex; x++) { if (stop) break; sampler->generate(); mean = meanSqr = Spectrum(0.0f); for (size_t j = 0; j<sampler->getSampleCount(); j++) { rRec.newQuery(RadianceQueryRecord::ECameraRay, camera->getMedium()); if (needsLensSample) lensSample = rRec.nextSample2D(); if (needsTimeSample) timeSample = rRec.nextSample1D(); sample = rRec.nextSample2D(); sample.x += x; sample.y += y; camera->generateRayDifferential(sample, lensSample, timeSample, eyeRay); eyeRay.scaleDifferential(scaleFactor); spec = Li(eyeRay, rRec); /* Numerically robust online variance estimation using an algorithm proposed by Donald Knuth (TAOCP vol.2, 3rd ed., p.232) */ const Spectrum delta = spec - mean; mean += delta / ((Float) j+1); meanSqr += delta * (spec - mean); block->putSample(sample, spec, rRec.alpha, filter); block->setVariance(x, y, meanSqr / (Float) j, (int) j+1); sampler->advance(); } } } } } }
void renderBlock(const Scene *scene, const Sensor *sensor, Sampler *sampler, ImageBlock *block, const bool &stop, const std::vector< TPoint2<uint8_t> > &points) const { Float diffScaleFactor = 1.0f / std::sqrt((Float)sampler->getSampleCount()); bool needsApertureSample = sensor->needsApertureSample(); bool needsTimeSample = sensor->needsTimeSample(); RadianceQueryRecord rRec(scene, sampler); Point2 apertureSample(0.5f); Float timeSample = 0.5f; RayDifferential sensorRay; block->clear(); uint32_t queryType = RadianceQueryRecord::ESensorRay; if (!sensor->getFilm()->hasAlpha()) /* Don't compute an alpha channel if we don't have to */ queryType &= ~RadianceQueryRecord::EOpacity; for (size_t i = 0; i < points.size(); ++i) { Point2i offset = Point2i(points[i]) + Vector2i(block->getOffset()); int index = offset.x + offset.y * width; if (stop) break; sampler->generate(offset); Float cntLdA = 0.f; std::vector<Float> cntLdW(m_numLobes, 0.f); for (size_t j = 0; j < sampler->getSampleCount(); j++) { rRec.newQuery(queryType, sensor->getMedium()); Point2 samplePos(Point2(offset) + Vector2(rRec.nextSample2D())); if (needsApertureSample) apertureSample = rRec.nextSample2D(); if (needsTimeSample) timeSample = rRec.nextSample1D(); Spectrum spec = sensor->sampleRayDifferential( sensorRay, samplePos, apertureSample, timeSample); sensorRay.scaleDifferential(diffScaleFactor); Spectrum oneTdA(0.f); Spectrum oneLdA(0.f); std::vector<Spectrum> oneTdW(m_numLobes, Spectrum(0.f)); std::vector<Spectrum> oneLdW(m_numLobes, Spectrum(0.f)); int albedoSegs = 0; spec *= Li(sensorRay, rRec, oneTdA, oneLdA, oneTdW, oneLdW, albedoSegs); block->put(samplePos, spec, rRec.alpha); bool goodSample = true; for (int c = 0; c < 3; c++) { if (!std::isfinite(oneLdA[c]) || oneLdA[c] < 0) { goodSample = false; break; } } if (goodSample) { LdA[index] += oneLdA; cntLdA += 1.f; } for (int k = 0; k < m_numLobes; k++) { goodSample = true; for (int c = 0; c < 3; c++) { if (!std::isfinite(oneLdW[k][c]) || oneLdW[k][c] < 0) { goodSample = false; break; } } if (goodSample) { LdW[k][index] += oneLdW[k]; cntLdW[k] += 1.f; } } imageSeg[index] |= albedoSegs; sampler->advance(); } if (cntLdA > 0.f) { LdA[index] /= cntLdA; } else { LdA[index] = Spectrum(0.f); } for (int k = 0; k < m_numLobes; k++) { if (cntLdW[k] > 0.f) { LdW[k][index] /= cntLdW[k]; } else { LdW[k][index] = Spectrum(0.f); } } } Float *data = new Float[(int)points.size() * 3]; std::string outfile = prefix + formatString("LdA_%03i_%03i.pfm", block->getOffset().x, block->getOffset().y); for (int i = 0; i < points.size(); i++) { Point2i p = Point2i(points[i]); int localIndex = p.x + p.y * block->getWidth(); Point2i offset = p + Vector2i(block->getOffset()); int globalIndex = offset.x + offset.y * width; Spectrum color(LdA[globalIndex]); for (int c = 0; c < 3; c++) { data[3 * localIndex + c] = color[c]; } } savePfm(outfile.c_str(), data, block->getWidth(), block->getHeight()); for (int k = 0; k < m_numLobes; k++) { outfile = prefix + formatString("LdW_l%02i_%03i_%03i.pfm", k, block->getOffset().x, block->getOffset().y); for (int i = 0; i < points.size(); i++) { Point2i p = Point2i(points[i]); int localIndex = p.x + p.y * block->getWidth(); Point2i offset = p + Vector2i(block->getOffset()); int globalIndex = offset.x + offset.y * width; Spectrum color(LdW[k][globalIndex]); for (int c = 0; c < 3; c++) { data[3 * localIndex + c] = color[c]; } } savePfm(outfile.c_str(), data, block->getWidth(), block->getHeight()); } outfile = prefix + formatString("image_seg_%03i_%03i.pfm", block->getOffset().x, block->getOffset().y); for (int i = 0; i < points.size(); i++) { Point2i p = Point2i(points[i]); int localIndex = p.x + p.y * block->getWidth(); Point2i offset = p + Vector2i(block->getOffset()); int globalIndex = offset.x + offset.y * width; Spectrum color(imageSeg[globalIndex]); for (int c = 0; c < 3; c++) { data[3 * localIndex + c] = color[c]; } } savePfm(outfile.c_str(), data, block->getWidth(), block->getHeight()); /* outfile = formatString("TdA_%03i_%03i.pfm", block->getOffset().x, block->getOffset().y); for (int i = 0; i < points.size(); i++) { Point2i p = Point2i(points[i]); int localIndex = p.x + p.y * block->getWidth(); Point2i offset = p + Vector2i(block->getOffset()); int globalIndex = offset.x + offset.y * width; Spectrum color(TdA[globalIndex] / Float(spp)); for (int c = 0; c < 3; c++) { data[3 * localIndex + c] = color[c]; } } savePfm(outfile.c_str(), data, block->getWidth(), block->getHeight()); */ delete[] data; }