diff --git a/include/openspace/rendering/abufferrenderer.h b/include/openspace/rendering/abufferrenderer.h index f9f9eba844..aa99d10ad1 100644 --- a/include/openspace/rendering/abufferrenderer.h +++ b/include/openspace/rendering/abufferrenderer.h @@ -62,6 +62,7 @@ public: void setResolution(glm::ivec2 res) override; void setNAaSamples(int nAaSamples) override; + void setBlurrinessLevel(int level) override; void setHDRExposure(float hdrExposure) override; void setGamma(float gamma) override; void setMaxWhite(float maxWhite) override; @@ -147,6 +148,7 @@ private: GLuint _fragmentTexture; GLuint _vertexPositionBuffer; int _nAaSamples; + int _blurrinessLevel = 1; float _hdrExposure = 0.4f; float _hdrBackground = 2.8f; diff --git a/include/openspace/rendering/framebufferrenderer.h b/include/openspace/rendering/framebufferrenderer.h index ba63e178bb..0f3f5dfa49 100644 --- a/include/openspace/rendering/framebufferrenderer.h +++ b/include/openspace/rendering/framebufferrenderer.h @@ -156,6 +156,7 @@ public: void setResolution(glm::ivec2 res) override; void setNAaSamples(int nAaSamples) override; + void setBlurrinessLevel(int level) override; void setHDRExposure(float hdrExposure) override; void setGamma(float gamma) override; void setMaxWhite(float maxWhite) override; @@ -230,8 +231,11 @@ private: toneMapOperator, aveLum, maxWhite, Hue, Saturation, Value, Lightness, colorSpace, nAaSamples) _hdrUniformCache; - UniformCache(renderedImage, bloomImage, bloomOrigFactor, bloomNewFactor) - _bloomUniformCache; + UniformCache(renderedImage, bloomImage, bloomOrigFactor, bloomNewFactor, + numberOfSamples) _bloomUniformCache; + + UniformCache(numberOfSamples, msaaTexture, blurriness) + _bloomFilterUniformCache; UniformCache(renderedImage, maxWhite, imageWidth, imageHeight) _histoUniformCache; @@ -260,6 +264,7 @@ private: glm::ivec2 _resolution = glm::ivec2(0); int _nAaSamples; + int _blurrinessLevel = 1; float _hdrExposure = 1.68f; float _gamma = 0.86f; float _maxWhite = 1.0f; diff --git a/include/openspace/rendering/renderengine.h b/include/openspace/rendering/renderengine.h index 8dd8d41f33..df16d22986 100644 --- a/include/openspace/rendering/renderengine.h +++ b/include/openspace/rendering/renderengine.h @@ -243,6 +243,7 @@ private: properties::PropertyOwner _bloomOwner; properties::BoolProperty _enableBloom; properties::BoolProperty _automaticBloom; + properties::IntProperty _bloomBlurrinessLevel; properties::FloatProperty _bloomThreshouldMin; properties::FloatProperty _bloomThreshouldMax; properties::FloatProperty _bloomOrigColorFactor; diff --git a/include/openspace/rendering/renderer.h b/include/openspace/rendering/renderer.h index bc6eda6f5b..c304b7b0db 100644 --- a/include/openspace/rendering/renderer.h +++ b/include/openspace/rendering/renderer.h @@ -50,6 +50,7 @@ public: virtual void setResolution(glm::ivec2 res) = 0; virtual void setNAaSamples(int nAaSamples) = 0; + virtual void setBlurrinessLevel(int level) = 0; virtual void setHDRExposure(float hdrExposure) = 0; virtual void setGamma(float gamma) = 0; virtual void setMaxWhite(float maxWhite) = 0; diff --git a/shaders/framebuffer/bloomFilter.frag b/shaders/framebuffer/bloomFilter.frag index 763e1fdf28..094cadfe7b 100644 --- a/shaders/framebuffer/bloomFilter.frag +++ b/shaders/framebuffer/bloomFilter.frag @@ -27,8 +27,7 @@ layout (location = 0) out vec4 finalColor; uniform int numberOfSamples; -uniform int maxResX; -uniform int maxResY; +uniform int blurriness; uniform sampler2DMS msaaTexture; // Gaussian Weights from OpenGL SuperBible 7 ed. @@ -60,7 +59,7 @@ const float weights2[] = float[](0.0024499299678342, // Gaussian weights calculated by http://dev.theomader.com/gaussian-kernel-calculator/ // sigma = 4.4625, kernel size = 5 -const float weights3[] = float[](0.190079, +const float weights1[] = float[](0.190079, 0.204885, 0.210072, 0.204885, @@ -68,7 +67,7 @@ const float weights3[] = float[](0.190079, // Gaussian weights calculated by http://dev.theomader.com/gaussian-kernel-calculator/ // sigma = 8, kernel size = 45 -const float weights[] = float[](0.001147, +const float weights3[] = float[](0.001147, 0.001605, 0.002209, 0.002995, @@ -114,23 +113,47 @@ const float weights[] = float[](0.001147, 0.001605, 0.001147); -void main(void) +vec4 applyConvolution(const int version) { vec4 color = vec4(0.0); // Transpose the image so the filter can be applied on X and Y // P is the central position in the filter mask - ivec2 P = ivec2(gl_FragCoord.yx) - ivec2(0, weights.length() >> 1); - for (int w = 0; w < weights.length(); w++) + int weightsLength = 0; + + if (version == 1) { + weightsLength = weights1.length(); + } else if (version == 2) { + weightsLength = weights2.length(); + } else if (version == 3) { + weightsLength = weights3.length(); + } + + ivec2 P = ivec2(gl_FragCoord.yx) - ivec2(0, weightsLength >> 1); + + for (int w = 0; w < weightsLength; w++) { ivec2 texelCoord = P + ivec2(0, w); vec4 tmpColor = vec4(0.0); + for (int s = 0; s < numberOfSamples; ++s) { tmpColor += texelFetch(msaaTexture, texelCoord, s); } tmpColor /= numberOfSamples; - color += tmpColor * weights[w]; + + if (version == 1) { + color += tmpColor * weights1[w]; + } else if (version == 2) { + color += tmpColor * weights2[w]; + } else if (version == 3) { + color += tmpColor * weights3[w]; + } } - finalColor = color; + return color; +} + +void main(void) +{ + finalColor = applyConvolution(blurriness); } diff --git a/src/rendering/abufferrenderer.cpp b/src/rendering/abufferrenderer.cpp index bde3611414..e504658408 100644 --- a/src/rendering/abufferrenderer.cpp +++ b/src/rendering/abufferrenderer.cpp @@ -702,6 +702,14 @@ void ABufferRenderer::setNAaSamples(int nAaSamples) { _dirtyResolution = true; } +void ABufferRenderer::setBlurrinessLevel(int level) { + ghoul_assert( + level > 0 && nAaSamples < 4, + "Blurriness level has to be between 1 and 3" + ); + _blurrinessLevel = level; +} + void ABufferRenderer::setHDRExposure(float hdrExposure) { _hdrExposure = hdrExposure; if (_hdrExposure < 0.f) { diff --git a/src/rendering/framebufferrenderer.cpp b/src/rendering/framebufferrenderer.cpp index d46463aeb8..cb84663f53 100644 --- a/src/rendering/framebufferrenderer.cpp +++ b/src/rendering/framebufferrenderer.cpp @@ -61,8 +61,13 @@ namespace { "Lightness", "colorSpace", "nAaSamples" }; - constexpr const std::array BloomUniformNames = { - "renderedImage", "bloomImage", "bloomOrigFactor", "bloomNewFactor" + constexpr const std::array BloomUniformNames = { + "renderedImage", "bloomImage", "bloomOrigFactor", "bloomNewFactor", + "numberOfSamples" + }; + + constexpr const std::array BloomFilterUniformNames = { + "numberOfSamples", "msaaTexture", "blurriness" }; constexpr const std::array HistoUniformNames = { @@ -429,7 +434,12 @@ void FramebufferRenderer::initialize() { _bloomUniformCache, BloomUniformNames ); - + ghoul::opengl::updateUniformLocations( + *_bloomProgram, + _bloomFilterUniformCache, + BloomFilterUniformNames + ); + ghoul::opengl::updateUniformLocations( *_histoProgram, _histoUniformCache, @@ -735,8 +745,9 @@ void FramebufferRenderer::applyBloomFilter() { // Incoming texture to apply the gaussian filter glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _gBuffers._filterTexture); - _bloomProgram->setUniform("msaaTexture", msaaTextureUnit); - _bloomProgram->setUniform("numberOfSamples", _nAaSamples); + _bloomProgram->setUniform(_bloomFilterUniformCache.msaaTexture, msaaTextureUnit); + _bloomProgram->setUniform(_bloomFilterUniformCache.numberOfSamples, _nAaSamples); + _bloomProgram->setUniform(_bloomFilterUniformCache.blurriness, _blurrinessLevel); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); //glFlush(); @@ -759,8 +770,9 @@ void FramebufferRenderer::applyBloomFilter() { // The results of the previous pass is passed to this pass glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _bloomBuffers._bloomTexture[0]); - _bloomProgram->setUniform("msaaTexture", msaaTextureUnit); - _bloomProgram->setUniform("numberOfSamples", _nAaSamples); + _bloomProgram->setUniform(_bloomFilterUniformCache.msaaTexture, msaaTextureUnit); + _bloomProgram->setUniform(_bloomFilterUniformCache.numberOfSamples, _nAaSamples); + _bloomProgram->setUniform(_bloomFilterUniformCache.blurriness, _blurrinessLevel); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); @@ -800,7 +812,7 @@ void FramebufferRenderer::applyBloomFilter() { glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _bloomBuffers._bloomTexture[1]); _bloomResolveProgram->setUniform(_bloomUniformCache.bloomImage, bloomTextureUnit); - _bloomResolveProgram->setUniform("numberOfSamples", _nAaSamples); + _bloomResolveProgram->setUniform(_bloomUniformCache.numberOfSamples, _nAaSamples); _bloomResolveProgram->setUniform( _bloomUniformCache.bloomOrigFactor, @@ -959,10 +971,6 @@ void FramebufferRenderer::update() { _aveLumProgram->rebuildFromFile(); } - if (_bloomProgram->isDirty()) { - _bloomProgram->rebuildFromFile(); - } - if (_bloomResolveProgram->isDirty()) { _bloomResolveProgram->rebuildFromFile(); ghoul::opengl::updateUniformLocations( @@ -972,6 +980,15 @@ void FramebufferRenderer::update() { ); } + if (_bloomProgram->isDirty()) { + _bloomProgram->rebuildFromFile(); + ghoul::opengl::updateUniformLocations( + *_bloomProgram, + _bloomFilterUniformCache, + BloomFilterUniformNames + ); + } + if (_histoProgram->isDirty()) { _histoProgram->rebuildFromFile(); ghoul::opengl::updateUniformLocations( @@ -2103,6 +2120,14 @@ void FramebufferRenderer::setNAaSamples(int nAaSamples) { _dirtyMsaaSamplingPattern = true; } +void FramebufferRenderer::setBlurrinessLevel(int level) { + ghoul_assert( + level > 0 && nAaSamples < 4, + "Blurriness level has to be between 1 and 3" + ); + _blurrinessLevel = level; +} + void FramebufferRenderer::setHDRExposure(float hdrExposure) { ghoul_assert(hdrExposure > 0.f, "HDR exposure must be greater than zero"); _hdrExposure = hdrExposure; diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 38cc738e4f..13e29acf30 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -271,6 +271,12 @@ namespace { "Enable/Disable Automatic Bloom." }; + constexpr openspace::properties::Property::PropertyInfo BlurrinessLevelBloomInfo = { + "BlurrinessLevelBloom", + "Increase/Decrease Bloom Blurriness Level", + "Increase/Decrease Bloom Blurriness Level." + }; + constexpr openspace::properties::Property::PropertyInfo HueInfo = { "Hue", "Hue", @@ -354,6 +360,7 @@ RenderEngine::RenderEngine() , _bloomOwner(BloomInfo) , _enableBloom(EnableBloomInfo, false) , _automaticBloom(AutomaticBloomInfo, false) + , _bloomBlurrinessLevel(BlurrinessLevelBloomInfo, 1, 1, 3) , _bloomThreshouldMin(BloomThreshouldMinInfo, 0.5, 0.0, 100.0) , _bloomThreshouldMax(BloomThreshouldMaxInfo, 1.0, 0.0, 100.0) , _bloomOrigColorFactor(BloomOrigColorFactorInfo, 1.0, 0.0, 100.0) @@ -543,6 +550,13 @@ RenderEngine::RenderEngine() }); addProperty(_automaticBloom); + _bloomBlurrinessLevel.onChange([this]() { + if (_renderer) { + _renderer->setBlurrinessLevel(_bloomBlurrinessLevel); + } + }); + addProperty(_bloomBlurrinessLevel); + addProperty(_bloomThreshouldMin); _bloomThreshouldMin.onChange([this]() { if (_renderer) {