130 lines · 4.4 KB · C++
RawDownload
////  ToneMapAndResampleTask.cpp//  libraries/render-utils/src////  Created by Anna Brewer on 7/3/19.//  Copyright 2019 High Fidelity, Inc.//  Copyright 2024 Overte e.V.////  Distributed under the Apache License, Version 2.0.//  See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html// #include "ToneMapAndResampleTask.h" #include <gpu/Context.h>#include <shaders/Shaders.h> #include "render-utils/ShaderConstants.h"#include "StencilMaskPass.h"#include "FramebufferCache.h" using namespace render;using namespace shader::gpu::program;using namespace shader::render_utils::program; gpu::PipelinePointer ToneMapAndResample::_pipeline;gpu::PipelinePointer ToneMapAndResample::_mirrorPipeline; ToneMapAndResample::ToneMapAndResample() {    Parameters parameters;    _parametersBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(gpu::Buffer::UniformBuffer, sizeof(Parameters), (const gpu::Byte*) &parameters));} void ToneMapAndResample::init() {    // shared_ptr to gpu::State    gpu::StatePointer blitState = std::make_shared<gpu::State>();     blitState->setDepthTest(gpu::State::DepthTest(false, false));    blitState->setColorWriteMask(true, true, true, true);     _pipeline = gpu::PipelinePointer(gpu::Pipeline::create(gpu::Shader::createProgram(toneMapping), blitState));    _mirrorPipeline = gpu::PipelinePointer(gpu::Pipeline::create(gpu::Shader::createProgram(toneMapping_mirrored), blitState));} void ToneMapAndResample::setExposure(float exposure) {    if (_exposure != exposure) {        _exposure = exposure;        _parametersBuffer.edit<Parameters>()._twoPowExposure = pow(2.0, exposure);    }} void ToneMapAndResample::setCurve(TonemappingCurve curve) {    auto& params = _parametersBuffer.get<Parameters>();    if (params._toneCurve != (int)curve) {        _parametersBuffer.edit<Parameters>()._toneCurve = (int)curve;    }} void ToneMapAndResample::configure(const Config& config) {    _debug = config.debug;    _debugExposure = config.exposure;    _debugCurve = (TonemappingCurve)config.curve;} void ToneMapAndResample::run(const RenderContextPointer& renderContext, const Input& input, Output& output) {    assert(renderContext->args);    assert(renderContext->args->hasViewFrustum());     RenderArgs* args = renderContext->args;     auto lightingBuffer = input.get0()->getRenderBuffer(0);    auto destinationFramebuffer = input.get1();    const auto tonemappingFrame = input.get2();     const auto& tonemappingStage = renderContext->_scene->getStage<TonemappingStage>();    graphics::TonemappingPointer tonemapping;    if (tonemappingStage && tonemappingFrame->_elements.size()) {        tonemapping = tonemappingStage->getElement(tonemappingFrame->_elements.front());    }     if (args->_mirrorDepth > 0) {        setCurve(TonemappingCurve::SRGB);        setExposure(0.0f);    } else if (_debug) {        setCurve(_debugCurve);        setExposure(_debugExposure);    } else if (tonemapping) {        setCurve(tonemapping->getCurve());        setExposure(tonemapping->getExposure());    }     if (!destinationFramebuffer) {        destinationFramebuffer = args->_blitFramebuffer;    }     if (!lightingBuffer || !destinationFramebuffer) {        return;    }     if (!_pipeline) {        init();    }     const auto bufferSize = destinationFramebuffer->getSize();     auto srcBufferSize = glm::ivec2(lightingBuffer->getDimensions());     glm::ivec4 destViewport{ 0, 0, bufferSize.x, bufferSize.y };     gpu::doInBatch("Resample::run", args->_context, [&](gpu::Batch& batch) {        batch.enableStereo(false);        batch.setFramebuffer(destinationFramebuffer);         batch.setViewportTransform(destViewport);        batch.setProjectionTransform(glm::mat4());        batch.resetViewTransform();        bool shouldMirror = args->_numMirrorFlips >= (args->_renderMode != RenderArgs::MIRROR_RENDER_MODE ? 1 : 0);        batch.setPipeline(shouldMirror ? _mirrorPipeline : _pipeline);         batch.setModelTransform(gpu::Framebuffer::evalSubregionTexcoordTransform(srcBufferSize, args->_viewport));        batch.setUniformBuffer(render_utils::slot::buffer::ToneMappingParams, _parametersBuffer);        batch.setResourceTexture(render_utils::slot::texture::ToneMappingColor, lightingBuffer);        batch.draw(gpu::TRIANGLE_STRIP, 4);    });     // Set full final viewport    args->_viewport = destViewport;     output = destinationFramebuffer;}