mirror of
https://github.com/lubosz/overte.git
synced 2025-04-23 13:33:38 +02:00
Threshold now doesn't downsample anymore. Done in separate pass
This commit is contained in:
parent
76305c5285
commit
f55d44dfc3
4 changed files with 44 additions and 61 deletions
|
@ -21,15 +21,15 @@
|
|||
|
||||
#define BLOOM_BLUR_LEVEL_COUNT 3
|
||||
|
||||
ThresholdAndDownsampleJob::ThresholdAndDownsampleJob() {
|
||||
BloomThreshold::BloomThreshold() {
|
||||
|
||||
}
|
||||
|
||||
void ThresholdAndDownsampleJob::configure(const Config& config) {
|
||||
void BloomThreshold::configure(const Config& config) {
|
||||
_threshold = config.threshold;
|
||||
}
|
||||
|
||||
void ThresholdAndDownsampleJob::run(const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& outputs) {
|
||||
void BloomThreshold::run(const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& outputs) {
|
||||
assert(renderContext->args);
|
||||
assert(renderContext->args->hasViewFrustum());
|
||||
|
||||
|
@ -40,25 +40,23 @@ void ThresholdAndDownsampleJob::run(const render::RenderContextPointer& renderCo
|
|||
|
||||
assert(inputFrameBuffer->hasColor());
|
||||
|
||||
auto inputColor = inputFrameBuffer->getRenderBuffer(0);
|
||||
auto inputBuffer = inputFrameBuffer->getRenderBuffer(0);
|
||||
auto sourceViewport = args->_viewport;
|
||||
auto fullSize = glm::ivec2(inputColor->getDimensions());
|
||||
auto halfSize = fullSize / 2;
|
||||
auto halfViewport = args->_viewport >> 1;
|
||||
auto bufferSize = glm::ivec2(inputBuffer->getDimensions());
|
||||
|
||||
if (!_downsampledBuffer || _downsampledBuffer->getSize().x != halfSize.x || _downsampledBuffer->getSize().y != halfSize.y) {
|
||||
auto colorTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(inputColor->getTexelFormat(), halfSize.x, halfSize.y,
|
||||
if (!_outputBuffer || _outputBuffer->getSize() != inputFrameBuffer->getSize()) {
|
||||
auto colorTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(inputBuffer->getTexelFormat(), bufferSize.x, bufferSize.y,
|
||||
gpu::Texture::SINGLE_MIP, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT)));
|
||||
|
||||
_downsampledBuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("BloomThreshold"));
|
||||
_downsampledBuffer->setRenderBuffer(0, colorTexture);
|
||||
_outputBuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("BloomThreshold"));
|
||||
_outputBuffer->setRenderBuffer(0, colorTexture);
|
||||
}
|
||||
|
||||
static const int COLOR_MAP_SLOT = 0;
|
||||
static const int THRESHOLD_SLOT = 1;
|
||||
|
||||
if (!_pipeline) {
|
||||
auto vs = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS();
|
||||
auto vs = gpu::StandardShaderLib::getDrawTransformUnitQuadVS();
|
||||
auto ps = gpu::Shader::createPixel(std::string(BloomThreshold_frag));
|
||||
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
|
||||
|
||||
|
@ -74,23 +72,19 @@ void ThresholdAndDownsampleJob::run(const render::RenderContextPointer& renderCo
|
|||
gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
|
||||
batch.enableStereo(false);
|
||||
|
||||
batch.setViewportTransform(halfViewport);
|
||||
batch.setViewportTransform(args->_viewport);
|
||||
batch.setProjectionTransform(glm::mat4());
|
||||
batch.resetViewTransform();
|
||||
batch.setModelTransform(gpu::Framebuffer::evalSubregionTexcoordTransform(inputFrameBuffer->getSize(), args->_viewport));
|
||||
batch.setModelTransform(gpu::Framebuffer::evalSubregionTexcoordTransform(bufferSize, args->_viewport));
|
||||
batch.setPipeline(_pipeline);
|
||||
|
||||
batch.setFramebuffer(_downsampledBuffer);
|
||||
batch.setResourceTexture(COLOR_MAP_SLOT, inputColor);
|
||||
batch.setFramebuffer(_outputBuffer);
|
||||
batch.setResourceTexture(COLOR_MAP_SLOT, inputBuffer);
|
||||
batch._glUniform1f(THRESHOLD_SLOT, _threshold);
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
|
||||
batch.setViewportTransform(args->_viewport);
|
||||
batch.setResourceTexture(COLOR_MAP_SLOT, nullptr);
|
||||
batch.setFramebuffer(nullptr);
|
||||
});
|
||||
|
||||
outputs = _downsampledBuffer;
|
||||
outputs = _outputBuffer;
|
||||
}
|
||||
|
||||
BloomApply::BloomApply() {
|
||||
|
@ -287,14 +281,27 @@ void Bloom::configure(const Config& config) {
|
|||
}
|
||||
|
||||
void Bloom::build(JobModel& task, const render::Varying& inputs, render::Varying& outputs) {
|
||||
const auto bloomInputBuffer = task.addJob<ThresholdAndDownsampleJob>("BloomThreshold", inputs);
|
||||
const auto bloomInputBuffer = task.addJob<BloomThreshold>("BloomThreshold", inputs);
|
||||
const auto bloomHalfInputBuffer = task.addJob<render::HalfDownsample>("BloomHalf", bloomInputBuffer);
|
||||
const auto bloomQuarterInputBuffer = task.addJob<render::HalfDownsample>("BloomQuarter", bloomHalfInputBuffer);
|
||||
|
||||
#if 1
|
||||
// Multi-scale blur
|
||||
const auto blurFB0 = task.addJob<render::BlurGaussian>("BloomBlur0", bloomInputBuffer);
|
||||
const auto blurFB0 = task.addJob<render::BlurGaussian>("BloomBlur0", bloomQuarterInputBuffer);
|
||||
const auto halfBlurFB0 = task.addJob<render::HalfDownsample>("BloomHalfBlur0", blurFB0);
|
||||
const auto blurFB1 = task.addJob<render::BlurGaussian>("BloomBlur1", halfBlurFB0, true);
|
||||
const auto halfBlurFB1 = task.addJob<render::HalfDownsample>("BloomHalfBlur1", blurFB1);
|
||||
const auto blurFB2 = task.addJob<render::BlurGaussian>("BloomBlur2", halfBlurFB1, true);
|
||||
#else
|
||||
// Multi-scale downsampling debug
|
||||
const auto blurFB0 = bloomQuarterInputBuffer;
|
||||
const auto blurFB1 = task.addJob<render::HalfDownsample>("BloomHalfBlur1", blurFB0);
|
||||
const auto blurFB2 = task.addJob<render::HalfDownsample>("BloomHalfBlur2", blurFB1);
|
||||
// This is only needed so as not to crash as we expect to have the three blur jobs
|
||||
task.addJob<render::BlurGaussian>("BloomBlur0", bloomHalfInputBuffer, true);
|
||||
task.addJob<render::BlurGaussian>("BloomBlur1", blurFB1, true);
|
||||
task.addJob<render::BlurGaussian>("BloomBlur2", blurFB2, true);
|
||||
#endif
|
||||
|
||||
const auto& input = inputs.get<Inputs>();
|
||||
const auto& frameBuffer = input[1];
|
||||
|
|
|
@ -25,7 +25,7 @@ public:
|
|||
|
||||
BloomConfig() : render::Task::Config(true) {}
|
||||
|
||||
float size{ 0.45f };
|
||||
float size{ 0.8f };
|
||||
|
||||
void setIntensity(float value);
|
||||
float getIntensity() const;
|
||||
|
@ -35,7 +35,7 @@ signals:
|
|||
void dirty();
|
||||
};
|
||||
|
||||
class ThresholdConfig : public render::Job::Config {
|
||||
class BloomThresholdConfig : public render::Job::Config {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(float threshold MEMBER threshold NOTIFY dirty)
|
||||
|
||||
|
@ -47,21 +47,21 @@ signals:
|
|||
void dirty();
|
||||
};
|
||||
|
||||
class ThresholdAndDownsampleJob {
|
||||
class BloomThreshold {
|
||||
public:
|
||||
using Inputs = render::VaryingSet2<DeferredFrameTransformPointer, gpu::FramebufferPointer>;
|
||||
using Outputs = gpu::FramebufferPointer;
|
||||
using Config = ThresholdConfig;
|
||||
using JobModel = render::Job::ModelIO<ThresholdAndDownsampleJob, Inputs, Outputs, Config>;
|
||||
using Config = BloomThresholdConfig;
|
||||
using JobModel = render::Job::ModelIO<BloomThreshold, Inputs, Outputs, Config>;
|
||||
|
||||
ThresholdAndDownsampleJob();
|
||||
BloomThreshold();
|
||||
|
||||
void configure(const Config& config);
|
||||
void run(const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& outputs);
|
||||
|
||||
private:
|
||||
|
||||
gpu::FramebufferPointer _downsampledBuffer;
|
||||
gpu::FramebufferPointer _outputBuffer;
|
||||
gpu::PipelinePointer _pipeline;
|
||||
float _threshold;
|
||||
};
|
||||
|
@ -73,7 +73,7 @@ class BloomApplyConfig : public render::Job::Config {
|
|||
|
||||
public:
|
||||
|
||||
float intensity{ 0.5f };
|
||||
float intensity{ 0.8f };
|
||||
|
||||
signals:
|
||||
void dirty();
|
||||
|
|
|
@ -17,29 +17,11 @@ in vec2 varTexCoord0;
|
|||
out vec4 outFragColor;
|
||||
|
||||
void main(void) {
|
||||
// Gather 2 by 2 quads from texture, threshold and downsample
|
||||
vec4 reds = textureGather(colorMap, varTexCoord0, 0);
|
||||
vec4 greens = textureGather(colorMap, varTexCoord0, 1);
|
||||
vec4 blues = textureGather(colorMap, varTexCoord0, 2);
|
||||
vec4 color = texture(colorMap, varTexCoord0);
|
||||
float luminance = (color.r+color.g+color.b) / 3.0;
|
||||
float mask = clamp((luminance-threshold)*0.25, 0, 1);
|
||||
|
||||
vec3 texel0 = vec3(reds.x, greens.x, blues.x);
|
||||
vec3 texel1 = vec3(reds.y, greens.y, blues.y);
|
||||
vec3 texel2 = vec3(reds.z, greens.z, blues.z);
|
||||
vec3 texel3 = vec3(reds.w, greens.w, blues.w);
|
||||
color *= mask;
|
||||
|
||||
vec4 luminances;
|
||||
vec3 luminanceWeights = vec3(0.333,0.333,0.333);
|
||||
|
||||
luminances.x = dot(texel0, luminanceWeights);
|
||||
luminances.y = dot(texel1, luminanceWeights);
|
||||
luminances.z = dot(texel2, luminanceWeights);
|
||||
luminances.w = dot(texel0, luminanceWeights);
|
||||
|
||||
vec4 mask = clamp(luminances-threshold, 0, 1);
|
||||
vec3 color;
|
||||
|
||||
color.x = dot(mask, reds);
|
||||
color.y = dot(mask, greens);
|
||||
color.z = dot(mask, blues);
|
||||
outFragColor = vec4(color/4.0, 1.0);
|
||||
outFragColor = vec4(color.rgb, 1.0);
|
||||
}
|
||||
|
|
|
@ -48,15 +48,12 @@ void HalfDownsample::run(const RenderContextPointer& renderContext, const gpu::F
|
|||
|
||||
resampledFrameBuffer = getResampledFrameBuffer(sourceFramebuffer);
|
||||
|
||||
static auto TEXCOORD_RECT_SLOT = 1;
|
||||
|
||||
if (!_pipeline) {
|
||||
auto vs = gpu::StandardShaderLib::getDrawTexcoordRectTransformUnitQuadVS();
|
||||
auto vs = gpu::StandardShaderLib::getDrawTransformUnitQuadVS();
|
||||
auto ps = gpu::StandardShaderLib::getDrawTextureOpaquePS();
|
||||
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
|
||||
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("texcoordRect"), TEXCOORD_RECT_SLOT));
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
|
||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
|
@ -80,9 +77,6 @@ void HalfDownsample::run(const RenderContextPointer& renderContext, const gpu::F
|
|||
|
||||
batch.setModelTransform(gpu::Framebuffer::evalSubregionTexcoordTransform(bufferSize, viewport));
|
||||
batch.setResourceTexture(0, sourceFramebuffer->getRenderBuffer(0));
|
||||
// Add half a texel of offset to be sure to sample in the middle of 4 neighbouring texture pixels
|
||||
// to perform box filtering.
|
||||
batch._glUniform4f(TEXCOORD_RECT_SLOT, 0.5f / sourceSize.x, 0.5f / sourceSize.y, 1.f, 1.f);
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue