From f3e972790bcd074ad44e66df28994019d88caeaa Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Thu, 27 Jun 2019 22:00:19 -0400 Subject: [PATCH] Fixed bloom. Improved performance. --- .../scene/digitaluniverse/milkyway.asset | 3 +- .../openspace/rendering/framebufferrenderer.h | 28 ++++++++- include/openspace/rendering/renderengine.h | 1 + shaders/framebuffer/bloomFilter.frag | 11 +++- shaders/framebuffer/renderframebuffer.frag | 11 ++-- src/rendering/framebufferrenderer.cpp | 63 ++++++++++--------- src/rendering/renderengine.cpp | 15 +++++ 7 files changed, 93 insertions(+), 39 deletions(-) diff --git a/data/assets/scene/digitaluniverse/milkyway.asset b/data/assets/scene/digitaluniverse/milkyway.asset index dff01194a4..83ee5c6f92 100644 --- a/data/assets/scene/digitaluniverse/milkyway.asset +++ b/data/assets/scene/digitaluniverse/milkyway.asset @@ -40,7 +40,8 @@ local sphere = { Orientation = "Inside", UseAdditiveBlending = true, MirrorTexture = true, - FadeOutThreshold = 0.025 + FadeOutThreshold = 0.025, + Background = true }, GUI = { Name = "Milky Way Sphere", diff --git a/include/openspace/rendering/framebufferrenderer.h b/include/openspace/rendering/framebufferrenderer.h index 2f7ef6d3b3..9918edb7b5 100644 --- a/include/openspace/rendering/framebufferrenderer.h +++ b/include/openspace/rendering/framebufferrenderer.h @@ -59,6 +59,29 @@ struct UpdateStructures; class FramebufferRenderer : public Renderer, public RaycasterListener, public DeferredcasterListener { +private: + inline static const GLenum ColorAttachment0Array[1] = { + GL_COLOR_ATTACHMENT0 + }; + + inline static const GLenum ColorAttachment01Array[2] = { + GL_COLOR_ATTACHMENT0, + GL_COLOR_ATTACHMENT1 + }; + + inline static const GLenum ColorAttachment012Array[3] = { + GL_COLOR_ATTACHMENT0, + GL_COLOR_ATTACHMENT1, + GL_COLOR_ATTACHMENT2 + }; + + inline static const GLenum ColorAttachment0123Array[4] = { + GL_COLOR_ATTACHMENT0, + GL_COLOR_ATTACHMENT1, + GL_COLOR_ATTACHMENT2, + GL_COLOR_ATTACHMENT3 + }; + public: typedef std::map< VolumeRaycaster*, @@ -157,8 +180,8 @@ private: toneMapOperator, aveLum, maxWhite, Hue, Saturation, Value, Lightness, colorSpace) _hdrUniformCache; - UniformCache(renderedImage, bloomImage, bloomThresholdMin, bloomThresholdMax, - bloomOrigFactor, bloomNewFactor) _bloomUniformCache; + UniformCache(renderedImage, bloomImage, bloomOrigFactor, bloomNewFactor) + _bloomUniformCache; UniformCache(renderedImage, maxWhite, imageWidth, imageHeight) _histoUniformCache; @@ -182,6 +205,7 @@ private: GLuint _histoVao; GLuint _histoVbo; + GLuint _bloomVAO = 0u; GLuint _bloomFilterFBO[3]; GLuint _bloomTexture[3]; diff --git a/include/openspace/rendering/renderengine.h b/include/openspace/rendering/renderengine.h index 4ff80c325e..8dd8d41f33 100644 --- a/include/openspace/rendering/renderengine.h +++ b/include/openspace/rendering/renderengine.h @@ -242,6 +242,7 @@ private: properties::PropertyOwner _bloomOwner; properties::BoolProperty _enableBloom; + properties::BoolProperty _automaticBloom; properties::FloatProperty _bloomThreshouldMin; properties::FloatProperty _bloomThreshouldMax; properties::FloatProperty _bloomOrigColorFactor; diff --git a/shaders/framebuffer/bloomFilter.frag b/shaders/framebuffer/bloomFilter.frag index e964803a07..e0830c77e9 100644 --- a/shaders/framebuffer/bloomFilter.frag +++ b/shaders/framebuffer/bloomFilter.frag @@ -26,6 +26,7 @@ layout (location = 0) out vec4 finalColor; +uniform int numberOfSamples; uniform int filterStep; uniform sampler2DMS filterImage; uniform sampler2D filterFirstPass; @@ -67,10 +68,16 @@ void main(void) for (int i = 0; i < weights.length(); i++) { if (filterStep == 1) { - color += vec4(texelFetch(filterImage, P + ivec2(0, i), 0).rgb, 1.0) * weights[i]; + vec4 tmpColor = vec4(0.0); + for (int s = 0; s < numberOfSamples; ++s) { + tmpColor += vec4(texelFetch(filterImage, P + ivec2(0, i), 0).rgb, s) * weights[i]; + } + tmpColor /= numberOfSamples; + color += tmpColor; + //color += vec4(texelFetch(filterImage, P + ivec2(0, i), 0).rgb, 1) * weights[i]; origAlpha = color.a; } else if (filterStep == 2) { - color += vec4(texelFetch(filterFirstPass, P + ivec2(0, i), 0).rgb, 1.0) * weights[i]; + color += vec4(texelFetch(filterFirstPass, P + ivec2(0, i), 0).rgb, 0) * weights[i]; } } diff --git a/shaders/framebuffer/renderframebuffer.frag b/shaders/framebuffer/renderframebuffer.frag index 3b4728ee5b..2da88e1da5 100644 --- a/shaders/framebuffer/renderframebuffer.frag +++ b/shaders/framebuffer/renderframebuffer.frag @@ -30,21 +30,24 @@ layout(location = 1) out vec4 gPosition; layout(location = 2) out vec4 gNormal; layout(location = 3) out vec4 filterBuffer; +uniform bool automaticBloom; +uniform float bloom_thresh_min; +uniform float bloom_thresh_max; + void main() { Fragment f = getFragment(); _out_color_ = f.color; gPosition = f.gPosition; gNormal = f.gNormal; - bool automaticBloom = false; if (automaticBloom) { // Extract luminance float Y = dot(f.color.rgb, vec3(0.299, 0.587, 0.144)); // Apply Bloom on the bloom threshold range values - //vec4 bColor = f.color * 4.0 * smoothstep(bloom_thresh_min, bloom_thresh_max, Y); - //filterBuffer = bColor - filterBuffer = vec4(f.filterFlag); + vec3 bColor = f.color.rgb * 4.0 * smoothstep(bloom_thresh_min, bloom_thresh_max, Y); + + filterBuffer = vec4(bColor, f.color.a); } else { if (f.filterFlag == 1) filterBuffer = f.color; diff --git a/src/rendering/framebufferrenderer.cpp b/src/rendering/framebufferrenderer.cpp index 457241c8da..1aa4c4c90e 100644 --- a/src/rendering/framebufferrenderer.cpp +++ b/src/rendering/framebufferrenderer.cpp @@ -61,9 +61,8 @@ namespace { "Lightness", "colorSpace" }; - constexpr const std::array BloomUniformNames = { - "renderedImage", "bloomImage", "bloomThresholdMin", "bloomThresholdMax", - "bloomOrigFactor", "bloomNewFactor" + constexpr const std::array BloomUniformNames = { + "renderedImage", "bloomImage", "bloomOrigFactor", "bloomNewFactor" }; constexpr const std::array HistoUniformNames = { @@ -512,23 +511,20 @@ float FramebufferRenderer::computeBufferAveLuminanceGPU() { } void FramebufferRenderer::applyBloomFilter() { - GLint defaultFbo; - glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFbo); - - GLuint vao; - glGenVertexArrays(1, &vao); + + if (!_bloomVAO) { + glGenVertexArrays(1, &_bloomVAO); + } glBindFramebuffer(GL_FRAMEBUFFER, _bloomFilterFBO[0]); - GLenum textureBuffer[] = { - GL_COLOR_ATTACHMENT0 - }; - glDrawBuffers(1, textureBuffer); + glDrawBuffers(1, ColorAttachment0Array); glClear(GL_COLOR_BUFFER_BIT); glViewport(0, 0, _resolution.y, _resolution.x); - glBindVertexArray(vao); + glBindVertexArray(_bloomVAO); _bloomProgram->activate(); + // First blurring pass (vertical) { ghoul::opengl::TextureUnit filterTextureUnit; filterTextureUnit.activate(); @@ -536,6 +532,7 @@ void FramebufferRenderer::applyBloomFilter() { glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainFilterTexture); _bloomProgram->setUniform("filterStep", 1); _bloomProgram->setUniform("filterImage", filterTextureUnit); + _bloomProgram->setUniform("numberOfSamples", _nAaSamples); // Making OpenGL happy... ghoul::opengl::TextureUnit dummyTextureUnit; @@ -550,13 +547,14 @@ void FramebufferRenderer::applyBloomFilter() { _bloomProgram->deactivate(); glBindFramebuffer(GL_FRAMEBUFFER, _bloomFilterFBO[1]); - glDrawBuffers(1, textureBuffer); + glDrawBuffers(1, ColorAttachment0Array); glViewport(0, 0, _resolution.x, _resolution.y); glClear(GL_COLOR_BUFFER_BIT); - glBindVertexArray(vao); + glBindVertexArray(_bloomVAO); _bloomProgram->activate(); + // Second blurring pass (horizontal) { ghoul::opengl::TextureUnit filterTextureUnit; filterTextureUnit.activate(); @@ -564,6 +562,7 @@ void FramebufferRenderer::applyBloomFilter() { glBindTexture(GL_TEXTURE_2D, _bloomTexture[0]); _bloomProgram->setUniform("filterStep", 2); _bloomProgram->setUniform("filterFirstPass", filterTextureUnit); + _bloomProgram->setUniform("numberOfSamples", _nAaSamples); // Making OpenGL happy... ghoul::opengl::TextureUnit dummyTextureUnit; @@ -579,12 +578,16 @@ void FramebufferRenderer::applyBloomFilter() { _bloomProgram->deactivate(); glBindFramebuffer(GL_FRAMEBUFFER, _bloomFilterFBO[2]); - glDrawBuffers(1, textureBuffer); + glDrawBuffers(1, ColorAttachment0Array); glViewport(0, 0, _resolution.x, _resolution.y); glClear(GL_COLOR_BUFFER_BIT); _bloomResolveProgram->activate(); + // Adding the result of the blurring processes to the + // hdrFilteringTexture and saving the result in + // the _bloomTexture[2] texture (JCC: That can be + // done by blending operation (ONE)) { ghoul::opengl::TextureUnit deferredResultsTextureUnit; deferredResultsTextureUnit.activate(); @@ -617,7 +620,7 @@ void FramebufferRenderer::applyBloomFilter() { _bloomResolveProgram->deactivate(); - glBindFramebuffer(GL_FRAMEBUFFER, defaultFbo); + glBindFramebuffer(GL_FRAMEBUFFER, _osDefaultGLState.defaultFBO); } void FramebufferRenderer::computeImageHistogram() { @@ -935,8 +938,8 @@ void FramebufferRenderer::updateResolution() { nullptr ); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } // Histogram Texture @@ -1526,7 +1529,7 @@ void FramebufferRenderer::updateMSAASamplingPattern() { nOneStripProgram->activate(); ghoul::opengl::TextureUnit pixelSizeTextureUnit; - pixelSizeTextureUnit.activate(); + pixelSizeTextureUnit.activate (); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, pixelSizeTexture); nOneStripProgram->setUniform("pixelSizeTexture", pixelSizeTextureUnit); @@ -1625,13 +1628,7 @@ void FramebufferRenderer::render(Scene* scene, Camera* camera, float blackoutFac global::renderEngine.setGLDefaultState(_osDefaultGLState); // deferred g-buffer plus filter - GLenum textureBuffers[4] = { - GL_COLOR_ATTACHMENT0, - GL_COLOR_ATTACHMENT1, - GL_COLOR_ATTACHMENT2, - GL_COLOR_ATTACHMENT3 - }; - glDrawBuffers(4, textureBuffers); + glDrawBuffers(4, ColorAttachment0123Array); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); Time time = global::timeManager.time(); @@ -1654,6 +1651,7 @@ void FramebufferRenderer::render(Scene* scene, Camera* camera, float blackoutFac data.renderBinMask = static_cast(Renderable::RenderBin::Overlay); scene->render(data, tasks); + // Run Volume Tasks { std::unique_ptr perfInternal; if (doPerformanceMeasurements) { @@ -1664,12 +1662,12 @@ void FramebufferRenderer::render(Scene* scene, Camera* camera, float blackoutFac performRaycasterTasks(tasks.raycasterTasks); } - //glBindFramebuffer(GL_FRAMEBUFFER, defaultFbo); + // Binds the final Framebuffer which will contain the results of the TMOs glBindFramebuffer(GL_FRAMEBUFFER, _hdrFilteringFramebuffer); - GLenum dBuffer[1] = { GL_COLOR_ATTACHMENT0 }; - glDrawBuffers(1, dBuffer); + glDrawBuffers(1, ColorAttachment0Array); glClear(GL_COLOR_BUFFER_BIT); + // Run Deferred Tasks (resolve step is executed together with these tasks) { std::unique_ptr perfInternal; if (doPerformanceMeasurements) { @@ -1681,6 +1679,8 @@ void FramebufferRenderer::render(Scene* scene, Camera* camera, float blackoutFac } + // If no Deferred Task are prensent, the resolve step + // is executed in a separated step if (tasks.deferredcasterTasks.empty()) { //glBindFramebuffer(GL_FRAMEBUFFER, defaultFbo); _resolveProgram->activate(); @@ -1721,6 +1721,9 @@ void FramebufferRenderer::render(Scene* scene, Camera* camera, float blackoutFac // ////float averageLuminaceInFB = 0.5; + + // When applying the TMO, the result is saved to the default FBO to be displayed + // by the Operating System glBindFramebuffer(GL_FRAMEBUFFER, _osDefaultGLState.defaultFBO); glViewport(0, 0, _resolution.x, _resolution.y); diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 142c99fc15..38cc738e4f 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -265,6 +265,12 @@ namespace { "Enable/Disable Bloom." }; + constexpr openspace::properties::Property::PropertyInfo AutomaticBloomInfo = { + "AutomaticBloom", + "Enable/Disable Automatic Bloom", + "Enable/Disable Automatic Bloom." + }; + constexpr openspace::properties::Property::PropertyInfo HueInfo = { "Hue", "Hue", @@ -347,6 +353,7 @@ RenderEngine::RenderEngine() , _nAaSamples(AaSamplesInfo, 4, 1, 8) , _bloomOwner(BloomInfo) , _enableBloom(EnableBloomInfo, false) + , _automaticBloom(AutomaticBloomInfo, false) , _bloomThreshouldMin(BloomThreshouldMinInfo, 0.5, 0.0, 100.0) , _bloomThreshouldMax(BloomThreshouldMaxInfo, 1.0, 0.0, 100.0) , _bloomOrigColorFactor(BloomOrigColorFactorInfo, 1.0, 0.0, 100.0) @@ -528,6 +535,14 @@ RenderEngine::RenderEngine() addProperty(_enableBloom); + _automaticBloom.onChange([this]() { + if (_renderer && _automaticBloom) { + _renderer->enableBloom(true); + _enableBloom = true; + } + }); + addProperty(_automaticBloom); + addProperty(_bloomThreshouldMin); _bloomThreshouldMin.onChange([this]() { if (_renderer) {