mirror of
https://github.com/lubosz/overte.git
synced 2025-04-15 09:49:57 +02:00
Merge pull request #13557 from Zvork/bloom
Fix Bloom on Mac and hopefully Windows AMD (bug #15434)
This commit is contained in:
commit
377c072e6d
9 changed files with 101 additions and 40 deletions
16
libraries/render-utils/src/BloomApply.shared.slh
Normal file
16
libraries/render-utils/src/BloomApply.shared.slh
Normal file
|
@ -0,0 +1,16 @@
|
|||
// glsl / C++ compatible source as interface for BloomApply
|
||||
#ifdef __cplusplus
|
||||
# define BA_VEC3 glm::vec3
|
||||
#else
|
||||
# define BA_VEC3 vec3
|
||||
#endif
|
||||
|
||||
struct Parameters
|
||||
{
|
||||
BA_VEC3 _intensities;
|
||||
};
|
||||
|
||||
// <@if 1@>
|
||||
// Trigger Scribe include
|
||||
// <@endif@> <!def that !>
|
||||
//
|
|
@ -9,11 +9,15 @@
|
|||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
<@include BloomApply.shared.slh@>
|
||||
|
||||
uniform sampler2D blurMap0;
|
||||
uniform sampler2D blurMap1;
|
||||
uniform sampler2D blurMap2;
|
||||
uniform vec3 intensity;
|
||||
|
||||
layout(std140) uniform parametersBuffer {
|
||||
Parameters parameters;
|
||||
};
|
||||
|
||||
in vec2 varTexCoord0;
|
||||
out vec4 outFragColor;
|
||||
|
@ -23,5 +27,5 @@ void main(void) {
|
|||
vec4 blur1 = texture(blurMap1, varTexCoord0);
|
||||
vec4 blur2 = texture(blurMap2, varTexCoord0);
|
||||
|
||||
outFragColor = vec4(blur0.rgb*intensity.x + blur1.rgb*intensity.y + blur2.rgb*intensity.z, 1.0f);
|
||||
outFragColor = vec4(blur0.rgb*parameters._intensities.x + blur1.rgb*parameters._intensities.y + blur2.rgb*parameters._intensities.z, 1.0f);
|
||||
}
|
||||
|
|
|
@ -21,13 +21,15 @@
|
|||
|
||||
#define BLOOM_BLUR_LEVEL_COUNT 3
|
||||
|
||||
BloomThreshold::BloomThreshold(unsigned int downsamplingFactor) :
|
||||
_downsamplingFactor(downsamplingFactor) {
|
||||
BloomThreshold::BloomThreshold(unsigned int downsamplingFactor) {
|
||||
assert(downsamplingFactor > 0);
|
||||
_parameters.edit()._sampleCount = downsamplingFactor;
|
||||
}
|
||||
|
||||
void BloomThreshold::configure(const Config& config) {
|
||||
_threshold = config.threshold;
|
||||
if (_parameters.get()._threshold != config.threshold) {
|
||||
_parameters.edit()._threshold = config.threshold;
|
||||
}
|
||||
}
|
||||
|
||||
void BloomThreshold::run(const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& outputs) {
|
||||
|
@ -43,10 +45,11 @@ void BloomThreshold::run(const render::RenderContextPointer& renderContext, cons
|
|||
|
||||
auto inputBuffer = inputFrameBuffer->getRenderBuffer(0);
|
||||
auto bufferSize = gpu::Vec2u(inputBuffer->getDimensions());
|
||||
const auto downSamplingFactor = _parameters.get()._sampleCount;
|
||||
|
||||
// Downsample resolution
|
||||
bufferSize.x /= _downsamplingFactor;
|
||||
bufferSize.y /= _downsamplingFactor;
|
||||
bufferSize.x /= downSamplingFactor;
|
||||
bufferSize.y /= downSamplingFactor;
|
||||
|
||||
if (!_outputBuffer || _outputBuffer->getSize() != bufferSize) {
|
||||
auto colorTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(inputBuffer->getTexelFormat(), bufferSize.x, bufferSize.y,
|
||||
|
@ -54,10 +57,12 @@ void BloomThreshold::run(const render::RenderContextPointer& renderContext, cons
|
|||
|
||||
_outputBuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("BloomThreshold"));
|
||||
_outputBuffer->setRenderBuffer(0, colorTexture);
|
||||
|
||||
_parameters.edit()._deltaUV = { 1.0f / bufferSize.x, 1.0f / bufferSize.y };
|
||||
}
|
||||
|
||||
static const int COLOR_MAP_SLOT = 0;
|
||||
static const int THRESHOLD_SLOT = 1;
|
||||
static const int PARAMETERS_SLOT = 1;
|
||||
|
||||
if (!_pipeline) {
|
||||
auto vs = gpu::StandardShaderLib::getDrawTransformUnitQuadVS();
|
||||
|
@ -66,7 +71,7 @@ void BloomThreshold::run(const render::RenderContextPointer& renderContext, cons
|
|||
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
slotBindings.insert(gpu::Shader::Binding("colorMap", COLOR_MAP_SLOT));
|
||||
slotBindings.insert(gpu::Shader::Binding("threshold", THRESHOLD_SLOT));
|
||||
slotBindings.insert(gpu::Shader::Binding("parametersBuffer", PARAMETERS_SLOT));
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
|
||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
|
@ -86,21 +91,26 @@ void BloomThreshold::run(const render::RenderContextPointer& renderContext, cons
|
|||
|
||||
batch.setFramebuffer(_outputBuffer);
|
||||
batch.setResourceTexture(COLOR_MAP_SLOT, inputBuffer);
|
||||
batch._glUniform1f(THRESHOLD_SLOT, _threshold);
|
||||
batch.setUniformBuffer(PARAMETERS_SLOT, _parameters);
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
});
|
||||
|
||||
outputs = _outputBuffer;
|
||||
}
|
||||
|
||||
BloomApply::BloomApply() : _intensities{ 1.0f, 1.0f, 1.0f } {
|
||||
BloomApply::BloomApply() {
|
||||
|
||||
}
|
||||
|
||||
void BloomApply::configure(const Config& config) {
|
||||
_intensities.x = config.intensity / 3.0f;
|
||||
_intensities.y = _intensities.x;
|
||||
_intensities.z = _intensities.x;
|
||||
const auto newIntensity = config.intensity / 3.0f;
|
||||
|
||||
if (_parameters.get()._intensities.x != newIntensity) {
|
||||
auto& parameters = _parameters.edit();
|
||||
parameters._intensities.x = newIntensity;
|
||||
parameters._intensities.y = newIntensity;
|
||||
parameters._intensities.z = newIntensity;
|
||||
}
|
||||
}
|
||||
|
||||
void BloomApply::run(const render::RenderContextPointer& renderContext, const Inputs& inputs) {
|
||||
|
@ -111,7 +121,7 @@ void BloomApply::run(const render::RenderContextPointer& renderContext, const In
|
|||
static const auto BLUR0_SLOT = 0;
|
||||
static const auto BLUR1_SLOT = 1;
|
||||
static const auto BLUR2_SLOT = 2;
|
||||
static const auto INTENSITY_SLOT = 3;
|
||||
static const auto PARAMETERS_SLOT = 0;
|
||||
|
||||
if (!_pipeline) {
|
||||
auto vs = gpu::StandardShaderLib::getDrawTransformUnitQuadVS();
|
||||
|
@ -122,7 +132,7 @@ void BloomApply::run(const render::RenderContextPointer& renderContext, const In
|
|||
slotBindings.insert(gpu::Shader::Binding("blurMap0", BLUR0_SLOT));
|
||||
slotBindings.insert(gpu::Shader::Binding("blurMap1", BLUR1_SLOT));
|
||||
slotBindings.insert(gpu::Shader::Binding("blurMap2", BLUR2_SLOT));
|
||||
slotBindings.insert(gpu::Shader::Binding("intensity", INTENSITY_SLOT));
|
||||
slotBindings.insert(gpu::Shader::Binding("parametersBuffer", PARAMETERS_SLOT));
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
|
||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
|
@ -151,7 +161,7 @@ void BloomApply::run(const render::RenderContextPointer& renderContext, const In
|
|||
batch.setResourceTexture(BLUR0_SLOT, blur0FB->getRenderBuffer(0));
|
||||
batch.setResourceTexture(BLUR1_SLOT, blur1FB->getRenderBuffer(0));
|
||||
batch.setResourceTexture(BLUR2_SLOT, blur2FB->getRenderBuffer(0));
|
||||
batch._glUniform3f(INTENSITY_SLOT, _intensities.x, _intensities.y, _intensities.z);
|
||||
batch.setUniformBuffer(PARAMETERS_SLOT, _parameters);
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -61,10 +61,11 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
#include "BloomThreshold.shared.slh"
|
||||
|
||||
gpu::FramebufferPointer _outputBuffer;
|
||||
gpu::PipelinePointer _pipeline;
|
||||
float _threshold;
|
||||
unsigned int _downsamplingFactor;
|
||||
gpu::StructBuffer<Parameters> _parameters;
|
||||
};
|
||||
|
||||
|
||||
|
@ -95,8 +96,10 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
#include "BloomApply.shared.slh"
|
||||
|
||||
gpu::PipelinePointer _pipeline;
|
||||
glm::vec3 _intensities;
|
||||
gpu::StructBuffer<Parameters> _parameters;
|
||||
};
|
||||
|
||||
class BloomDraw {
|
||||
|
|
18
libraries/render-utils/src/BloomThreshold.shared.slh
Normal file
18
libraries/render-utils/src/BloomThreshold.shared.slh
Normal file
|
@ -0,0 +1,18 @@
|
|||
// glsl / C++ compatible source as interface for BloomThreshold
|
||||
#ifdef __cplusplus
|
||||
# define BT_VEC2 glm::vec2
|
||||
#else
|
||||
# define BT_VEC2 vec2
|
||||
#endif
|
||||
|
||||
struct Parameters
|
||||
{
|
||||
BT_VEC2 _deltaUV;
|
||||
float _threshold;
|
||||
int _sampleCount;
|
||||
};
|
||||
|
||||
// <@if 1@>
|
||||
// Trigger Scribe include
|
||||
// <@endif@> <!def that !>
|
||||
//
|
|
@ -9,37 +9,35 @@
|
|||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
<@include BloomThreshold.shared.slh@>
|
||||
|
||||
uniform sampler2D colorMap;
|
||||
uniform float threshold;
|
||||
layout(std140) uniform parametersBuffer {
|
||||
Parameters parameters;
|
||||
};
|
||||
|
||||
in vec2 varTexCoord0;
|
||||
out vec4 outFragColor;
|
||||
|
||||
#define DOWNSAMPLING_FACTOR 4
|
||||
#define SAMPLE_COUNT (DOWNSAMPLING_FACTOR/2)
|
||||
|
||||
void main(void) {
|
||||
vec2 deltaX = dFdx(varTexCoord0) / SAMPLE_COUNT;
|
||||
vec2 deltaY = dFdy(varTexCoord0) / SAMPLE_COUNT;
|
||||
vec2 startUv = varTexCoord0;
|
||||
vec4 maskedColor = vec4(0,0,0,0);
|
||||
|
||||
for (int y=0 ; y<SAMPLE_COUNT ; y++) {
|
||||
for (int y=0 ; y<parameters._sampleCount ; y++) {
|
||||
vec2 uv = startUv;
|
||||
|
||||
for (int x=0 ; x<SAMPLE_COUNT ; x++) {
|
||||
for (int x=0 ; x<parameters._sampleCount ; x++) {
|
||||
vec4 color = texture(colorMap, uv);
|
||||
float luminance = (color.r+color.g+color.b) / 3.0;
|
||||
float mask = clamp((luminance-threshold)*0.25, 0, 1);
|
||||
float mask = clamp((luminance-parameters._threshold)*0.25, 0, 1);
|
||||
|
||||
color *= mask;
|
||||
maskedColor += color;
|
||||
uv += deltaX;
|
||||
uv.x += parameters._deltaUV.x;
|
||||
}
|
||||
|
||||
startUv += deltaY;
|
||||
startUv.y += parameters._deltaUV.y;
|
||||
}
|
||||
maskedColor /= SAMPLE_COUNT*SAMPLE_COUNT;
|
||||
maskedColor /= parameters._sampleCount * parameters._sampleCount;
|
||||
outFragColor = vec4(maskedColor.rgb, 1.0);
|
||||
}
|
||||
|
|
|
@ -117,6 +117,9 @@ void DrawHighlightMask::run(const render::RenderContextPointer& renderContext, c
|
|||
assert(renderContext->args->hasViewFrustum());
|
||||
auto& inShapes = inputs.get0();
|
||||
|
||||
const int BOUNDS_SLOT = 0;
|
||||
const int PARAMETERS_SLOT = 1;
|
||||
|
||||
if (!_stencilMaskPipeline || !_stencilMaskFillPipeline) {
|
||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
state->setDepthTest(true, false, gpu::LESS_EQUAL);
|
||||
|
@ -135,6 +138,8 @@ void DrawHighlightMask::run(const render::RenderContextPointer& renderContext, c
|
|||
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
|
||||
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("ssbo0Buffer"), BOUNDS_SLOT));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("parametersBuffer"), PARAMETERS_SLOT));
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
|
||||
_stencilMaskPipeline = gpu::Pipeline::create(program, state);
|
||||
|
@ -214,6 +219,15 @@ void DrawHighlightMask::run(const render::RenderContextPointer& renderContext, c
|
|||
|
||||
_boundsBuffer->setData(itemBounds.size() * sizeof(render::ItemBound), (const gpu::Byte*) itemBounds.data());
|
||||
|
||||
const auto securityMargin = 2.0f;
|
||||
const float blurPixelWidth = 2.0f * securityMargin * HighlightSharedParameters::getBlurPixelWidth(highlight._style, args->_viewport.w);
|
||||
const auto framebufferSize = ressources->getSourceFrameSize();
|
||||
const glm::vec2 highlightWidth = { blurPixelWidth / framebufferSize.x, blurPixelWidth / framebufferSize.y };
|
||||
|
||||
if (highlightWidth != _outlineWidth.get()) {
|
||||
_outlineWidth.edit() = highlightWidth;
|
||||
}
|
||||
|
||||
gpu::doInBatch("DrawHighlightMask::run::end", args->_context, [&](gpu::Batch& batch) {
|
||||
// Setup camera, projection and viewport for all items
|
||||
batch.setViewportTransform(args->_viewport);
|
||||
|
@ -221,15 +235,10 @@ void DrawHighlightMask::run(const render::RenderContextPointer& renderContext, c
|
|||
batch.setViewTransform(viewMat);
|
||||
|
||||
// Draw stencil mask with object bounding boxes
|
||||
const auto highlightWidthLoc = _stencilMaskPipeline->getProgram()->getUniforms().findLocation("outlineWidth");
|
||||
const auto securityMargin = 2.0f;
|
||||
const float blurPixelWidth = 2.0f * securityMargin * HighlightSharedParameters::getBlurPixelWidth(highlight._style, args->_viewport.w);
|
||||
const auto framebufferSize = ressources->getSourceFrameSize();
|
||||
|
||||
auto stencilPipeline = highlight._style.isFilled() ? _stencilMaskFillPipeline : _stencilMaskPipeline;
|
||||
batch.setPipeline(stencilPipeline);
|
||||
batch.setResourceBuffer(0, _boundsBuffer);
|
||||
batch._glUniform2f(highlightWidthLoc, blurPixelWidth / framebufferSize.x, blurPixelWidth / framebufferSize.y);
|
||||
batch.setResourceBuffer(BOUNDS_SLOT, _boundsBuffer);
|
||||
batch.setUniformBuffer(PARAMETERS_SLOT, _outlineWidth);
|
||||
static const int NUM_VERTICES_PER_CUBE = 36;
|
||||
batch.draw(gpu::TRIANGLES, NUM_VERTICES_PER_CUBE * (gpu::uint32) itemBounds.size(), 0);
|
||||
});
|
||||
|
|
|
@ -127,6 +127,7 @@ protected:
|
|||
render::ShapePlumberPointer _shapePlumber;
|
||||
HighlightSharedParametersPointer _sharedParameters;
|
||||
gpu::BufferPointer _boundsBuffer;
|
||||
gpu::StructBuffer<glm::vec2> _outlineWidth;
|
||||
|
||||
static gpu::PipelinePointer _stencilMaskPipeline;
|
||||
static gpu::PipelinePointer _stencilMaskFillPipeline;
|
||||
|
|
|
@ -40,7 +40,9 @@ ItemBound getItemBound(int i) {
|
|||
}
|
||||
#endif
|
||||
|
||||
uniform vec2 outlineWidth;
|
||||
uniform parametersBuffer {
|
||||
vec2 outlineWidth;
|
||||
};
|
||||
|
||||
void main(void) {
|
||||
const vec3 UNIT_BOX_VERTICES[8] = vec3[8](
|
||||
|
|
Loading…
Reference in a new issue