From 0d2b2a2aefc60aa3547c09066b2bf11f723cc0c1 Mon Sep 17 00:00:00 2001 From: Anna Date: Fri, 26 Jul 2019 12:53:18 -0700 Subject: [PATCH] added tone mapping config --- .../render-utils/src/RenderForwardTask.cpp | 2 +- .../src/render/ToneMapAndResampleTask.cpp | 52 ++++++++++++- .../src/render/ToneMapAndResampleTask.h | 74 +++++++++++++++++-- 3 files changed, 118 insertions(+), 10 deletions(-) diff --git a/libraries/render-utils/src/RenderForwardTask.cpp b/libraries/render-utils/src/RenderForwardTask.cpp index 0e3f036e6b..fb2222f98c 100755 --- a/libraries/render-utils/src/RenderForwardTask.cpp +++ b/libraries/render-utils/src/RenderForwardTask.cpp @@ -168,7 +168,7 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend // Upscale to finale resolution //const auto primaryFramebuffer = task.addJob("ToneMapAndResample", toneMappedBuffer); - const auto primaryFramebuffer = task.addJob("ToneMapAndResample", toneMappedBuffer); + const auto primaryFramebuffer = task.addJob("ToneMapAndResample", toneMappedBuffer); // HUD Layer const auto renderHUDLayerInputs = RenderHUDLayerTask::Input(primaryFramebuffer, lightingModel, hudOpaque, hudTransparent, hazeFrame).asVarying(); diff --git a/libraries/render/src/render/ToneMapAndResampleTask.cpp b/libraries/render/src/render/ToneMapAndResampleTask.cpp index c304f12f4a..b551aa14ce 100644 --- a/libraries/render/src/render/ToneMapAndResampleTask.cpp +++ b/libraries/render/src/render/ToneMapAndResampleTask.cpp @@ -77,6 +77,7 @@ void HalfDownsample::run(const RenderContextPointer& renderContext, const gpu::F }); } */ +/* gpu::PipelinePointer Resample::_pipeline; void Resample::configure(const Config& config) { @@ -136,32 +137,74 @@ void Resample::run(const RenderContextPointer& renderContext, const gpu::Framebu args->_viewport = viewport; } } +*/ +ToneMapAndResample::ToneMapAndResample() { + Parameters parameters; + _parametersBuffer = gpu::BufferView(std::make_shared(sizeof(Parameters), (const gpu::Byte*) ¶meters)); +} -gpu::PipelinePointer ResampleToBlitFramebuffer::_pipeline; -gpu::PipelinePointer ResampleToBlitFramebuffer::_mirrorPipeline; +void ToneMapAndResample::setExposure(float exposure) { + auto& params = _parametersBuffer.get(); + if (params._exposure != exposure) { + _parametersBuffer.edit()._exposure = exposure; + _parametersBuffer.edit()._twoPowExposure = pow(2.0, exposure); + } +} -void ResampleToBlitFramebuffer::run(const RenderContextPointer& renderContext, const Input& input, gpu::FramebufferPointer& resampledFrameBuffer) { +void ToneMapAndResample::setToneCurve(ToneCurve curve) { + auto& params = _parametersBuffer.get(); + if (params._toneCurve != (int)curve) { + _parametersBuffer.edit()._toneCurve = (int)curve; + } +} + +void ToneMapAndResample::configure(const Config& config) { + setExposure(config.exposure); + setToneCurve((ToneCurve)config.curve); +} + +gpu::PipelinePointer ToneMapAndResample::_pipeline; +gpu::PipelinePointer ToneMapAndResample::_mirrorPipeline; + +void ToneMapAndResample::run(const RenderContextPointer& renderContext, const Input& input, gpu::FramebufferPointer& resampledFrameBuffer) { assert(renderContext->args); assert(renderContext->args->hasViewFrustum()); RenderArgs* args = renderContext->args; auto sourceFramebuffer = input; + //auto lightingBuffer = input->getRenderBuffer(0); + resampledFrameBuffer = args->_blitFramebuffer; +/* + if (!_pipeline) { + init(args); + } + + if (!lightingBuffer || !blitFramebuffer) { + return; + } + */ if (resampledFrameBuffer != sourceFramebuffer) { + if (!_pipeline) { gpu::StatePointer state = gpu::StatePointer(new gpu::State()); + state->setDepthTest(gpu::State::DepthTest(false, false)); + //blitState->setColorWriteMask(true, true, true, true); _pipeline = gpu::Pipeline::create(gpu::Shader::createProgram(drawTransformUnitQuadTextureOpaque), state); _mirrorPipeline = gpu::Pipeline::create(gpu::Shader::createProgram(DrawTextureMirroredX), state); } + const auto bufferSize = resampledFrameBuffer->getSize(); + + //auto srcBufferSize = glm::ivec2(lightingBuffer->getDimensions()); + glm::ivec4 viewport{ 0, 0, bufferSize.x, bufferSize.y }; gpu::doInBatch("Resample::run", args->_context, [&](gpu::Batch& batch) { batch.enableStereo(false); - batch.setFramebuffer(resampledFrameBuffer); batch.setViewportTransform(viewport); @@ -169,6 +212,7 @@ void ResampleToBlitFramebuffer::run(const RenderContextPointer& renderContext, c batch.resetViewTransform(); batch.setPipeline(args->_renderMode == RenderArgs::MIRROR_RENDER_MODE ? _mirrorPipeline : _pipeline); + // viewport = args->_viewport ?? batch.setModelTransform(gpu::Framebuffer::evalSubregionTexcoordTransform(bufferSize, viewport)); batch.setResourceTexture(0, sourceFramebuffer->getRenderBuffer(0)); batch.draw(gpu::TRIANGLE_STRIP, 4); diff --git a/libraries/render/src/render/ToneMapAndResampleTask.h b/libraries/render/src/render/ToneMapAndResampleTask.h index f900bf85fa..1365cabf71 100644 --- a/libraries/render/src/render/ToneMapAndResampleTask.h +++ b/libraries/render/src/render/ToneMapAndResampleTask.h @@ -17,6 +17,31 @@ #include "Engine.h" namespace render { + + enum class ToneCurve { + // Different tone curve available + None, + Gamma22, + Reinhard, + Filmic, + }; + + class ToneMappingConfig : public render::Job::Config { + Q_OBJECT + Q_PROPERTY(float exposure MEMBER exposure WRITE setExposure); + Q_PROPERTY(int curve MEMBER curve WRITE setCurve); + + public: + ToneMappingConfig() : render::Job::Config(true) {} + + void setExposure(float newExposure) { exposure = newExposure; emit dirty(); } + void setCurve(int newCurve) { curve = std::max((int)ToneCurve::None, std::min((int)ToneCurve::Filmic, newCurve)); emit dirty(); } + + float exposure{ 0.0f }; + int curve{ (int)ToneCurve::Gamma22 }; + signals: + void dirty(); + }; /* class HalfDownsample { public: @@ -37,6 +62,7 @@ namespace render { gpu::FramebufferPointer getResampledFrameBuffer(const gpu::FramebufferPointer& sourceFramebuffer); }; */ +/* class ResampleConfig : public render::Job::Config { Q_OBJECT Q_PROPERTY(float factor MEMBER factor NOTIFY dirty) @@ -67,20 +93,58 @@ namespace render { gpu::FramebufferPointer getResampledFrameBuffer(const gpu::FramebufferPointer& sourceFramebuffer); }; - - class ResampleToBlitFramebuffer { + */ + class ToneMapAndResample{ public: + ToneMapAndResample(); + virtual ~ToneMapAndResample() {} + + void setExposure(float exposure); + float getExposure() const { return _parametersBuffer.get()._exposure; } + + void setToneCurve(ToneCurve curve); + ToneCurve getToneCurve() const { return (ToneCurve)_parametersBuffer.get()._toneCurve; } + + // Inputs: lightingFramebuffer, destinationFramebuffer using Input = gpu::FramebufferPointer; - using JobModel = Job::ModelIO; - - ResampleToBlitFramebuffer() {} + using Output = gpu::FramebufferPointer; + using Config = ToneMappingConfig; + //using JobModel = render::Job::ModelIO; + using JobModel = Job::ModelIO; + void configure(const Config& config); void run(const RenderContextPointer& renderContext, const Input& input, gpu::FramebufferPointer& resampledFrameBuffer); protected: static gpu::PipelinePointer _pipeline; static gpu::PipelinePointer _mirrorPipeline; + + gpu::FramebufferPointer _destinationFrameBuffer; + + float _factor{ 2.0f }; + + gpu::FramebufferPointer getResampledFrameBuffer(const gpu::FramebufferPointer& sourceFramebuffer); + + private: + + gpu::PipelinePointer _blitLightBuffer; + + // Class describing the uniform buffer with all the parameters common to the tone mapping shaders + class Parameters { + public: + float _exposure = 0.0f; + float _twoPowExposure = 1.0f; + glm::vec2 spareA; + int _toneCurve = (int)ToneCurve::Gamma22; + glm::vec3 spareB; + + Parameters() {} + }; + typedef gpu::BufferView UniformBufferView; + gpu::BufferView _parametersBuffer; + + void init(RenderArgs* args); }; }