Esempio n. 1
0
 inline void splat(Vec2u pixel, Vec3f w)
 {
     uint32 idx = pixel.x() + pixel.y()*_w;
     atomicAdd(_buffer[idx].x(), w.x());
     atomicAdd(_buffer[idx].y(), w.y());
     atomicAdd(_buffer[idx].z(), w.z());
 }
Esempio n. 2
0
bool PinholeCamera::sampleDirection(PathSampleGenerator &sampler, const PositionSample &/*point*/, Vec2u pixel,
        DirectionSample &sample) const
{
    float pdf;
    Vec2f uv = _filter.sample(sampler.next2D(CameraSample), pdf);
    Vec3f localD = Vec3f(
        -1.0f  + (float(pixel.x()) + 0.5f + uv.x())*2.0f*_pixelSize.x(),
        _ratio - (float(pixel.y()) + 0.5f + uv.y())*2.0f*_pixelSize.x(),
        _planeDist
    ).normalized();

    sample.d =  _transform.transformVector(localD);
    sample.weight = Vec3f(1.0f);
    sample.pdf = _invPlaneArea/cube(localD.z());

    return true;
}
Esempio n. 3
0
    void iterateTiles(std::array<QuadSetup, N> quads, Intersector intersector) const
    {
        Box2i bounds;
        for (const auto &q : quads)
            bounds.grow(q.bounds);

        if (bounds.empty())
            return;

        uint32 minX = uint32(bounds.min().x()) & ~TileMask, maxX = bounds.max().x();
        uint32 minY = uint32(bounds.min().y()) & ~TileMask, maxY = bounds.max().y();

        for (auto &q : quads) {
            q.start(minX + TileSize*0.5f, minY + TileSize*0.5f);
            for (int k = 0; k < 3; ++k) {
                q.stepX[k] *= float(TileSize);
                q.stepY[k] *= float(TileSize);
            }
        }

        for (uint32 y = minY; y < maxY; y += TileSize) {
            for (auto &q : quads)
                q.beginRow();

            for (uint32 x = minX; x < maxX; x += TileSize) {
                float wMin = -1.0f;
                for (auto &q : quads)
                    wMin = max(wMin, q.reduce());
                if (wMin >= 0.0f) {
                    uint32 xjMax = min(x + TileSize, _res.x());
                    uint32 yjMax = min(y + TileSize, _res.y());
                    for (uint32 yj = y; yj < yjMax; ++yj)
                        for (uint32 xj = x; xj < xjMax; ++xj)
                            intersector(xj, yj, xj + yj*_res.x());
                }
                for (auto &q : quads)
                    q.stepCol();
            }
            for (auto &q : quads)
                q.endRow();
        }
    }
Esempio n. 4
0
void Integrator::writeBuffers(const std::string &suffix, bool overwrite)
{
    Vec2u res = _scene->cam().resolution();
    std::unique_ptr<Vec3f[]> hdr(new Vec3f[res.product()]);
    std::unique_ptr<Vec3c[]> ldr(new Vec3c[res.product()]);

    for (uint32 y = 0; y < res.y(); ++y)
        for (uint32 x = 0; x < res.x(); ++x)
            hdr[x + y*res.x()] = _scene->cam().getLinear(x, y);

    for (uint32 i = 0; i < res.product(); ++i)
        ldr[i] = Vec3c(clamp(Vec3i(_scene->cam().tonemap(hdr[i])*255.0f), Vec3i(0), Vec3i(255)));

    const RendererSettings &settings = _scene->rendererSettings();

    if (!settings.outputFile().empty())
        ImageIO::saveLdr(incrementalFilename(settings.outputFile(), suffix, overwrite),
                &ldr[0].x(), res.x(), res.y(), 3);
    if (!settings.hdrOutputFile().empty())
        ImageIO::saveHdr(incrementalFilename(settings.hdrOutputFile(), suffix, overwrite),
                &hdr[0].x(), res.x(), res.y(), 3);
}
void ProgressivePhotonMapIntegrator::prepareForRender(TraceableScene &scene, uint32 seed)
{
    _sampler = UniformSampler(MathUtil::hash32(seed));
    _currentSpp = 0;
    _iteration = 0;
    _scene = &scene;
    advanceSpp();
    scene.cam().requestColorBuffer();

    _surfacePhotons.resize(_settings.photonCount);
    if (!_scene->media().empty())
        _volumePhotons.resize(_settings.volumePhotonCount);

    int numThreads = ThreadUtils::pool->threadCount();
    for (int i = 0; i < numThreads; ++i) {
        uint32 surfaceRangeStart = intLerp(0, uint32(_surfacePhotons.size()), i + 0, numThreads);
        uint32 surfaceRangeEnd   = intLerp(0, uint32(_surfacePhotons.size()), i + 1, numThreads);
        uint32  volumeRangeStart = intLerp(0, uint32( _volumePhotons.size()), i + 0, numThreads);
        uint32  volumeRangeEnd   = intLerp(0, uint32( _volumePhotons.size()), i + 1, numThreads);
        _taskData.emplace_back(SubTaskData{
            SurfacePhotonRange(&_surfacePhotons[0], surfaceRangeStart, surfaceRangeEnd),
            VolumePhotonRange(_volumePhotons.empty() ? nullptr : &_volumePhotons[0], volumeRangeStart, volumeRangeEnd)
        });
        _samplers.emplace_back(_scene->rendererSettings().useSobol() ?
            std::unique_ptr<PathSampleGenerator>(new SobolPathSampler(MathUtil::hash32(_sampler.nextI()))) :
            std::unique_ptr<PathSampleGenerator>(new UniformPathSampler(MathUtil::hash32(_sampler.nextI())))
        );

        _tracers.emplace_back(new PhotonTracer(&scene, _settings, i));
    }

    Vec2u res = _scene->cam().resolution();
    _w = res.x();
    _h = res.y();

    diceTiles();
}