mirror of
https://github.com/overte-org/overte.git
synced 2025-04-11 21:52:58 +02:00
init commit for this pr, still buggy
This commit is contained in:
parent
d49fabf370
commit
24f022ec3b
7 changed files with 272 additions and 157 deletions
|
@ -51,7 +51,7 @@
|
|||
|
||||
#include "AmbientOcclusionEffect.h"
|
||||
#include "AntialiasingEffect.h"
|
||||
#include "ToneMappingEffect.h"
|
||||
#include "ToneMapAndResampleTask.h"
|
||||
#include "SubsurfaceScattering.h"
|
||||
#include "DrawHaze.h"
|
||||
#include "BloomEffect.h"
|
||||
|
@ -239,8 +239,8 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
|
|||
task.addJob<BloomEffect>("Bloom", bloomInputs);
|
||||
|
||||
// Lighting Buffer ready for tone mapping
|
||||
const auto toneMappingInputs = ToneMappingDeferred::Input(lightingFramebuffer, scaledPrimaryFramebuffer).asVarying();
|
||||
const auto toneMappedBuffer = task.addJob<ToneMappingDeferred>("ToneMapping", toneMappingInputs);
|
||||
const auto toneMappingInputs = ToneMapAndResample::Input(lightingFramebuffer, scaledPrimaryFramebuffer).asVarying();
|
||||
const auto toneMappedBuffer = task.addJob<ToneMapAndResample>("ToneMapAndResample", toneMappingInputs);
|
||||
|
||||
// Debugging task is happening in the "over" layer after tone mapping and just before HUD
|
||||
{ // Debug the bounds of the rendered items, still look at the zbuffer
|
||||
|
@ -250,11 +250,8 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
|
|||
task.addJob<RenderDeferredTaskDebug>("DebugRenderDeferredTask", debugInputs);
|
||||
}
|
||||
|
||||
// Upscale to finale resolution
|
||||
const auto primaryFramebuffer = task.addJob<render::UpsampleToBlitFramebuffer>("PrimaryBufferUpscale", toneMappedBuffer);
|
||||
|
||||
// HUD Layer
|
||||
const auto renderHUDLayerInputs = RenderHUDLayerTask::Input(primaryFramebuffer, lightingModel, hudOpaque, hudTransparent, hazeFrame).asVarying();
|
||||
const auto renderHUDLayerInputs = RenderHUDLayerTask::Input(toneMappedBuffer, lightingModel, hudOpaque, hudTransparent, hazeFrame).asVarying();
|
||||
task.addJob<RenderHUDLayerTask>("RenderHUDLayer", renderHUDLayerInputs);
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#include "StencilMaskPass.h"
|
||||
#include "ZoneRenderer.h"
|
||||
#include "FadeEffect.h"
|
||||
#include "ToneMappingEffect.h"
|
||||
#include "ToneMapAndResampleTask.h"
|
||||
#include "BackgroundStage.h"
|
||||
#include "FramebufferCache.h"
|
||||
#include "TextureCache.h"
|
||||
|
@ -159,16 +159,13 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend
|
|||
// Lighting Buffer ready for tone mapping
|
||||
// Forward rendering on GLES doesn't support tonemapping to and from the same FBO, so we specify
|
||||
// the output FBO as null, which causes the tonemapping to target the blit framebuffer
|
||||
const auto toneMappingInputs = ToneMappingDeferred::Input(resolvedFramebuffer, resolvedFramebuffer).asVarying();
|
||||
const auto toneMappedBuffer = task.addJob<ToneMappingDeferred>("ToneMapping", toneMappingInputs);
|
||||
const auto toneMappingInputs = ToneMapAndResample::Input(resolvedFramebuffer, resolvedFramebuffer).asVarying();
|
||||
const auto toneMappedBuffer = task.addJob<ToneMapAndResample>("ToneMapAndResample", toneMappingInputs);
|
||||
|
||||
#endif
|
||||
|
||||
// Upscale to finale resolution
|
||||
const auto primaryFramebuffer = task.addJob<render::UpsampleToBlitFramebuffer>("PrimaryBufferUpscale", toneMappedBuffer);
|
||||
|
||||
// HUD Layer
|
||||
const auto renderHUDLayerInputs = RenderHUDLayerTask::Input(primaryFramebuffer, lightingModel, hudOpaque, hudTransparent, hazeFrame).asVarying();
|
||||
const auto renderHUDLayerInputs = RenderHUDLayerTask::Input(toneMappedBuffer, lightingModel, hudOpaque, hudTransparent, hazeFrame).asVarying();
|
||||
task.addJob<RenderHUDLayerTask>("RenderHUDLayer", renderHUDLayerInputs);
|
||||
}
|
||||
|
||||
|
|
139
libraries/render-utils/src/ToneMapAndResampleTask.cpp
Normal file
139
libraries/render-utils/src/ToneMapAndResampleTask.cpp
Normal file
|
@ -0,0 +1,139 @@
|
|||
//
|
||||
// ToneMapAndResampleTask.cpp
|
||||
// libraries/render-utils/src
|
||||
//
|
||||
// Created by Sam Gateau on 12/7/2015.
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// 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 shader::render_utils::program;
|
||||
|
||||
gpu::PipelinePointer ToneMapAndResample::_pipeline;
|
||||
gpu::PipelinePointer ToneMapAndResample::_mirrorPipeline;
|
||||
|
||||
ToneMapAndResample::ToneMapAndResample() {
|
||||
Parameters parameters;
|
||||
_parametersBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(Parameters), (const gpu::Byte*) ¶meters));
|
||||
}
|
||||
|
||||
void ToneMapAndResample::init(RenderArgs* args) {
|
||||
|
||||
// shared_ptr to gpu::State
|
||||
gpu::StatePointer blitState = gpu::StatePointer(new gpu::State());
|
||||
|
||||
// TODO why was this in the upsample task
|
||||
//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(toneMappingMirroredX), blitState));
|
||||
}
|
||||
|
||||
void ToneMapAndResample::setExposure(float exposure) {
|
||||
auto& params = _parametersBuffer.get<Parameters>();
|
||||
if (params._exposure != exposure) {
|
||||
_parametersBuffer.edit<Parameters>()._exposure = exposure;
|
||||
_parametersBuffer.edit<Parameters>()._twoPowExposure = pow(2.0, exposure);
|
||||
}
|
||||
}
|
||||
|
||||
void ToneMapAndResample::setToneCurve(ToneCurve curve) {
|
||||
auto& params = _parametersBuffer.get<Parameters>();
|
||||
if (params._toneCurve != (int)curve) {
|
||||
_parametersBuffer.edit<Parameters>()._toneCurve = (int)curve;
|
||||
}
|
||||
}
|
||||
|
||||
gpu::FramebufferPointer ToneMapAndResample::getResampledFrameBuffer(const gpu::FramebufferPointer& sourceFramebuffer) {
|
||||
if (_factor == 1.0f) {
|
||||
return sourceFramebuffer;
|
||||
}
|
||||
|
||||
auto resampledFramebufferSize = glm::uvec2(glm::vec2(sourceFramebuffer->getSize()) * _factor);
|
||||
|
||||
if (!_destinationFrameBuffer || resampledFramebufferSize != _destinationFrameBuffer->getSize()) {
|
||||
_destinationFrameBuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("ResampledOutput"));
|
||||
|
||||
auto sampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR);
|
||||
auto target = gpu::Texture::createRenderBuffer(sourceFramebuffer->getRenderBuffer(0)->getTexelFormat(), resampledFramebufferSize.x, resampledFramebufferSize.y, gpu::Texture::SINGLE_MIP, sampler);
|
||||
_destinationFrameBuffer->setRenderBuffer(0, target);
|
||||
}
|
||||
return _destinationFrameBuffer;
|
||||
}
|
||||
|
||||
// TODO why was destination const
|
||||
void ToneMapAndResample::render(RenderArgs* args, const gpu::TexturePointer& lightingBuffer, gpu::FramebufferPointer& destinationFramebuffer) {
|
||||
|
||||
if (!_pipeline) {
|
||||
init(args);
|
||||
}
|
||||
|
||||
if (!lightingBuffer || !destinationFramebuffer) {
|
||||
return;
|
||||
}
|
||||
|
||||
//auto framebufferSize = glm::ivec2(lightingBuffer->getDimensions());
|
||||
|
||||
auto framebufferSize = destinationFramebuffer->getSize();
|
||||
|
||||
gpu::doInBatch("ToneMapAndResample::render", args->_context, [&](gpu::Batch& batch) {
|
||||
batch.enableStereo(false);
|
||||
batch.setFramebuffer(destinationFramebuffer);
|
||||
|
||||
// FIXME: Generate the Luminosity map
|
||||
//batch.generateTextureMips(lightingBuffer);
|
||||
|
||||
batch.setViewportTransform(args->_viewport);
|
||||
batch.setProjectionTransform(glm::mat4());
|
||||
batch.resetViewTransform();
|
||||
batch.setModelTransform(gpu::Framebuffer::evalSubregionTexcoordTransform(framebufferSize, args->_viewport));
|
||||
batch.setPipeline(args->_renderMode == RenderArgs::MIRROR_RENDER_MODE ? _mirrorPipeline : _pipeline);
|
||||
|
||||
batch.setUniformBuffer(render_utils::slot::buffer::ToneMappingParams, _parametersBuffer);
|
||||
batch.setResourceTexture(render_utils::slot::texture::ToneMappingColor, lightingBuffer);
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
});
|
||||
|
||||
destinationFramebuffer = getResampledFrameBuffer(destinationFramebuffer);
|
||||
|
||||
const auto bufferSize = destinationFramebuffer->getSize();
|
||||
glm::ivec4 viewport{ 0, 0, bufferSize.x, bufferSize.y };
|
||||
|
||||
//Set full final viewport
|
||||
args->_viewport = viewport;
|
||||
}
|
||||
|
||||
void ToneMapAndResample::configure(const Config& config) {
|
||||
setExposure(config.exposure);
|
||||
setToneCurve((ToneCurve)config.curve);
|
||||
}
|
||||
|
||||
void ToneMapAndResample::run(const render::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 resampledFramebuffer = args->_blitFramebuffer;
|
||||
|
||||
render(args, lightingBuffer, resampledFramebuffer);
|
||||
|
||||
output = resampledFramebuffer;
|
||||
}
|
||||
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// ToneMappingEffect.h
|
||||
// ToneMapAndResample.h
|
||||
// libraries/render-utils/src
|
||||
//
|
||||
// Created by Sam Gateau on 12/7/2015.
|
||||
|
@ -9,8 +9,8 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_ToneMappingEffect_h
|
||||
#define hifi_ToneMappingEffect_h
|
||||
#ifndef hifi_ToneMapAndResample_h
|
||||
#define hifi_ToneMapAndResample_h
|
||||
|
||||
#include <DependencyManager.h>
|
||||
#include <NumericalConstants.h>
|
||||
|
@ -20,27 +20,64 @@
|
|||
#include <render/Forward.h>
|
||||
#include <render/DrawTask.h>
|
||||
|
||||
enum class ToneCurve {
|
||||
// Different tone curve available
|
||||
None,
|
||||
Gamma22,
|
||||
Reinhard,
|
||||
Filmic,
|
||||
};
|
||||
|
||||
class ToneMappingEffect {
|
||||
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:
|
||||
ToneMappingEffect();
|
||||
virtual ~ToneMappingEffect() {}
|
||||
ToneMappingConfig() : render::Job::Config(true) {}
|
||||
|
||||
void render(RenderArgs* args, const gpu::TexturePointer& lightingBuffer, const gpu::FramebufferPointer& destinationBuffer);
|
||||
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 ToneMapAndResample {
|
||||
public:
|
||||
ToneMapAndResample();
|
||||
virtual ~ToneMapAndResample() {}
|
||||
|
||||
void render(RenderArgs* args, const gpu::TexturePointer& lightingBuffer, gpu::FramebufferPointer& destinationBuffer);
|
||||
|
||||
void setExposure(float exposure);
|
||||
float getExposure() const { return _parametersBuffer.get<Parameters>()._exposure; }
|
||||
|
||||
// Different tone curve available
|
||||
enum ToneCurve {
|
||||
None = 0,
|
||||
Gamma22,
|
||||
Reinhard,
|
||||
Filmic,
|
||||
};
|
||||
void setToneCurve(ToneCurve curve);
|
||||
ToneCurve getToneCurve() const { return (ToneCurve)_parametersBuffer.get<Parameters>()._toneCurve; }
|
||||
|
||||
// Inputs: lightingFramebuffer, destinationFramebuffer
|
||||
using Input = render::VaryingSet2<gpu::FramebufferPointer, gpu::FramebufferPointer>;
|
||||
using Output = gpu::FramebufferPointer;
|
||||
using Config = ToneMappingConfig;
|
||||
using JobModel = render::Job::ModelIO<ToneMapAndResample, Input, Output, Config>;
|
||||
|
||||
void configure(const Config& config);
|
||||
void run(const render::RenderContextPointer& renderContext, const Input& input, Output& output);
|
||||
|
||||
protected:
|
||||
|
||||
static gpu::PipelinePointer _pipeline;
|
||||
static gpu::PipelinePointer _mirrorPipeline;
|
||||
|
||||
gpu::FramebufferPointer _destinationFrameBuffer;
|
||||
|
||||
float _factor{ 2.0f };
|
||||
|
||||
gpu::FramebufferPointer ToneMapAndResample::getResampledFrameBuffer(const gpu::FramebufferPointer& sourceFramebuffer);
|
||||
|
||||
private:
|
||||
|
||||
gpu::PipelinePointer _blitLightBuffer;
|
||||
|
@ -51,7 +88,7 @@ private:
|
|||
float _exposure = 0.0f;
|
||||
float _twoPowExposure = 1.0f;
|
||||
glm::vec2 spareA;
|
||||
int _toneCurve = Gamma22;
|
||||
int _toneCurve = (int)ToneCurve::Gamma22;
|
||||
glm::vec3 spareB;
|
||||
|
||||
Parameters() {}
|
||||
|
@ -62,35 +99,4 @@ private:
|
|||
void init(RenderArgs* args);
|
||||
};
|
||||
|
||||
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)ToneMappingEffect::None, std::min((int)ToneMappingEffect::Filmic, newCurve)); emit dirty(); }
|
||||
|
||||
|
||||
float exposure{ 0.0f };
|
||||
int curve{ ToneMappingEffect::Gamma22 };
|
||||
signals:
|
||||
void dirty();
|
||||
};
|
||||
|
||||
class ToneMappingDeferred {
|
||||
public:
|
||||
// Inputs: lightingFramebuffer, destinationFramebuffer
|
||||
using Input = render::VaryingSet2<gpu::FramebufferPointer, gpu::FramebufferPointer>;
|
||||
using Output = gpu::FramebufferPointer;
|
||||
using Config = ToneMappingConfig;
|
||||
using JobModel = render::Job::ModelIO<ToneMappingDeferred, Input, Output, Config>;
|
||||
|
||||
void configure(const Config& config);
|
||||
void run(const render::RenderContextPointer& renderContext, const Input& input, Output& output);
|
||||
|
||||
ToneMappingEffect _toneMappingEffect;
|
||||
};
|
||||
|
||||
#endif // hifi_ToneMappingEffect_h
|
||||
#endif // hifi_ToneMapAndResample_h
|
|
@ -1,96 +0,0 @@
|
|||
//
|
||||
// ToneMappingEffect.cpp
|
||||
// libraries/render-utils/src
|
||||
//
|
||||
// Created by Sam Gateau on 12/7/2015.
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "ToneMappingEffect.h"
|
||||
|
||||
#include <gpu/Context.h>
|
||||
#include <shaders/Shaders.h>
|
||||
|
||||
#include "render-utils/ShaderConstants.h"
|
||||
#include "StencilMaskPass.h"
|
||||
#include "FramebufferCache.h"
|
||||
|
||||
|
||||
ToneMappingEffect::ToneMappingEffect() {
|
||||
Parameters parameters;
|
||||
_parametersBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(Parameters), (const gpu::Byte*) ¶meters));
|
||||
}
|
||||
|
||||
void ToneMappingEffect::init(RenderArgs* args) {
|
||||
auto blitProgram = gpu::Shader::createProgram(shader::render_utils::program::toneMapping);
|
||||
|
||||
auto blitState = std::make_shared<gpu::State>();
|
||||
blitState->setColorWriteMask(true, true, true, true);
|
||||
_blitLightBuffer = gpu::PipelinePointer(gpu::Pipeline::create(blitProgram, blitState));
|
||||
}
|
||||
|
||||
void ToneMappingEffect::setExposure(float exposure) {
|
||||
auto& params = _parametersBuffer.get<Parameters>();
|
||||
if (params._exposure != exposure) {
|
||||
_parametersBuffer.edit<Parameters>()._exposure = exposure;
|
||||
_parametersBuffer.edit<Parameters>()._twoPowExposure = pow(2.0, exposure);
|
||||
}
|
||||
}
|
||||
|
||||
void ToneMappingEffect::setToneCurve(ToneCurve curve) {
|
||||
auto& params = _parametersBuffer.get<Parameters>();
|
||||
if (params._toneCurve != curve) {
|
||||
_parametersBuffer.edit<Parameters>()._toneCurve = curve;
|
||||
}
|
||||
}
|
||||
|
||||
void ToneMappingEffect::render(RenderArgs* args, const gpu::TexturePointer& lightingBuffer, const gpu::FramebufferPointer& destinationFramebuffer) {
|
||||
if (!_blitLightBuffer) {
|
||||
init(args);
|
||||
}
|
||||
|
||||
if (!lightingBuffer || !destinationFramebuffer) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto framebufferSize = glm::ivec2(lightingBuffer->getDimensions());
|
||||
gpu::doInBatch("ToneMappingEffect::render", args->_context, [&](gpu::Batch& batch) {
|
||||
batch.enableStereo(false);
|
||||
batch.setFramebuffer(destinationFramebuffer);
|
||||
|
||||
// FIXME: Generate the Luminosity map
|
||||
//batch.generateTextureMips(lightingBuffer);
|
||||
|
||||
batch.setViewportTransform(args->_viewport);
|
||||
batch.setProjectionTransform(glm::mat4());
|
||||
batch.resetViewTransform();
|
||||
batch.setModelTransform(gpu::Framebuffer::evalSubregionTexcoordTransform(framebufferSize, args->_viewport));
|
||||
batch.setPipeline(_blitLightBuffer);
|
||||
|
||||
batch.setUniformBuffer(render_utils::slot::buffer::ToneMappingParams, _parametersBuffer);
|
||||
batch.setResourceTexture(render_utils::slot::texture::ToneMappingColor, lightingBuffer);
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
void ToneMappingDeferred::configure(const Config& config) {
|
||||
_toneMappingEffect.setExposure(config.exposure);
|
||||
_toneMappingEffect.setToneCurve((ToneMappingEffect::ToneCurve)config.curve);
|
||||
}
|
||||
|
||||
void ToneMappingDeferred::run(const render::RenderContextPointer& renderContext, const Input& input, Output& output) {
|
||||
|
||||
auto lightingBuffer = input.get0()->getRenderBuffer(0);
|
||||
auto destFbo = input.get1();
|
||||
|
||||
if (!destFbo) {
|
||||
destFbo = renderContext->args->_blitFramebuffer;
|
||||
}
|
||||
|
||||
_toneMappingEffect.render(renderContext->args, lightingBuffer, destFbo);
|
||||
output = destFbo;
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
VERTEX gpu::vertex::DrawViewportQuadTransformTexcoord
|
71
libraries/render-utils/src/toneMappingMirroredX.slf
Normal file
71
libraries/render-utils/src/toneMappingMirroredX.slf
Normal file
|
@ -0,0 +1,71 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on Sat Oct 24 09:34:37 2015
|
||||
//
|
||||
// toneMapping.frag
|
||||
//
|
||||
// Draw texture 0 fetched at texcoord.xy
|
||||
//
|
||||
// Created by Sam Gateau on 6/22/2015
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
<@include render-utils/ShaderConstants.h@>
|
||||
|
||||
struct ToneMappingParams {
|
||||
vec4 _exp_2powExp_s0_s1;
|
||||
ivec4 _toneCurve_s0_s1_s2;
|
||||
};
|
||||
|
||||
const float GAMMA_22 = 2.2;
|
||||
const float INV_GAMMA_22 = 1.0 / 2.2;
|
||||
const int ToneCurveNone = 0;
|
||||
const int ToneCurveGamma22 = 1;
|
||||
const int ToneCurveReinhard = 2;
|
||||
const int ToneCurveFilmic = 3;
|
||||
|
||||
LAYOUT(binding=RENDER_UTILS_BUFFER_TM_PARAMS) uniform toneMappingParamsBuffer {
|
||||
ToneMappingParams params;
|
||||
};
|
||||
float getTwoPowExposure() {
|
||||
return params._exp_2powExp_s0_s1.y;
|
||||
}
|
||||
int getToneCurve() {
|
||||
return params._toneCurve_s0_s1_s2.x;
|
||||
}
|
||||
|
||||
LAYOUT(binding=RENDER_UTILS_TEXTURE_TM_COLOR) uniform sampler2D colorMap;
|
||||
|
||||
layout(location=0) in vec2 varTexCoord0;
|
||||
layout(location=0) out vec4 outFragColor;
|
||||
|
||||
void main(void) {
|
||||
vec4 fragColorRaw = texture(colorMap, vec2(1 - varTexCoord0.x, varTexCoord0.y));
|
||||
vec3 fragColor = fragColorRaw.xyz;
|
||||
|
||||
vec3 srcColor = fragColor * getTwoPowExposure();
|
||||
|
||||
int toneCurve = getToneCurve();
|
||||
vec3 tonedColor = srcColor;
|
||||
if (toneCurve == ToneCurveFilmic) {
|
||||
vec3 x = max(vec3(0.0), srcColor-0.004);
|
||||
tonedColor = pow((x * (6.2 * x + 0.5)) / (x * (6.2 * x + 1.7) + 0.06), vec3(GAMMA_22));
|
||||
} else if (toneCurve == ToneCurveReinhard) {
|
||||
tonedColor = srcColor/(1.0 + srcColor);
|
||||
} else if (toneCurve == ToneCurveGamma22) {
|
||||
// We use glEnable(GL_FRAMEBUFFER_SRGB), which automatically converts textures from RGB to SRGB
|
||||
// when writing from an RGB framebuffer to an SRGB framebuffer (note that it doesn't do anything
|
||||
// when writing from an SRGB framebuffer to an RGB framebuffer).
|
||||
// Since the conversion happens automatically, we don't need to do anything in this shader
|
||||
} else {
|
||||
// toneCurve == ToneCurveNone
|
||||
// For debugging purposes, we may want to see what the colors look like before the automatic OpenGL
|
||||
// conversion mentioned above, so we undo it here
|
||||
tonedColor = pow(srcColor, vec3(GAMMA_22));
|
||||
}
|
||||
|
||||
outFragColor = vec4(tonedColor, 1.0);
|
||||
}
|
Loading…
Reference in a new issue