mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-05-05 02:20:11 -05:00
moved bloom into postDraw() stage
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2025 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_RENDERING_POSTPROCESS___
|
||||
#define __OPENSPACE_RENDERING_POSTPROCESS___
|
||||
|
||||
#include <ghoul/opengl/ghoul_gl.h>
|
||||
#include <memory>
|
||||
|
||||
namespace ghoul::opengl {
|
||||
class ProgramObject;
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class PostprocessingBloom {
|
||||
public:
|
||||
PostprocessingBloom();
|
||||
~PostprocessingBloom();
|
||||
|
||||
void initialize();
|
||||
void deinitialize();
|
||||
void setResolution(int width, int height);
|
||||
void update();
|
||||
void render(GLuint inputTexture);
|
||||
|
||||
void setEnabled(bool enabled) { _enabled = enabled; }
|
||||
bool isEnabled() const { return _enabled; }
|
||||
|
||||
void setThreshold(float threshold) { _threshold = threshold; }
|
||||
void setBlurPasses(int passes) { _blurPasses = passes; }
|
||||
void setBlurMagnitude(float magnitude) { _blurMagnitude = magnitude; }
|
||||
void setIntensity(float intensity) { _intensity = intensity; }
|
||||
|
||||
private:
|
||||
void createFramebuffers();
|
||||
void renderExtract(GLuint inputTexture);
|
||||
void renderBlur();
|
||||
void renderBlend(GLuint inputTexture);
|
||||
|
||||
bool _enabled = true;
|
||||
float _threshold = 0.75f;
|
||||
int _blurPasses = 3;
|
||||
float _blurMagnitude = 0.001f;
|
||||
float _intensity = 1.0f;
|
||||
|
||||
int _width = 0;
|
||||
int _height = 0;
|
||||
int _bloomWidth = 0;
|
||||
int _bloomHeight = 0;
|
||||
|
||||
GLuint _screenQuad = 0;
|
||||
GLuint _vertexBuffer = 0;
|
||||
|
||||
GLuint _bloomFramebuffer = 0;
|
||||
GLuint _blurFramebuffer = 0;
|
||||
GLuint _bloomTexture = 0;
|
||||
GLuint _blurTexture[2] = {0, 0};
|
||||
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _extractProgram;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _blurProgram;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _blendProgram;
|
||||
|
||||
struct {
|
||||
GLint mainColorTexture = -1;
|
||||
GLint threshold = -1;
|
||||
} _extractUniforms;
|
||||
|
||||
struct {
|
||||
GLint mainColorTexture = -1;
|
||||
GLint blurDirection = -1;
|
||||
GLint blurMagnitude = -1;
|
||||
} _blurUniforms;
|
||||
|
||||
struct {
|
||||
GLint mainColorTexture = -1;
|
||||
GLint bloomTexture = -1;
|
||||
GLint bloomIntensity = -1;
|
||||
} _blendUniforms;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_RENDERING_POSTPROCESS___
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <openspace/properties/vector/vec3property.h>
|
||||
#include <openspace/properties/vector/vec4property.h>
|
||||
#include <openspace/rendering/framebufferrenderer.h>
|
||||
#include <openspace/rendering/postprocess.h>
|
||||
#include <chrono>
|
||||
#include <filesystem>
|
||||
|
||||
@@ -172,6 +173,7 @@ private:
|
||||
Scene* _scene = nullptr;
|
||||
|
||||
FramebufferRenderer _renderer;
|
||||
PostprocessingBloom _bloom;
|
||||
ghoul::Dictionary _rendererData;
|
||||
ghoul::Dictionary _resolveData;
|
||||
ScreenLog* _log = nullptr;
|
||||
|
||||
@@ -1 +1 @@
|
||||
set (DEFAULT_MODULE ON)
|
||||
set (DEFAULT_MODULE OFF)
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2025 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
layout (location = 0) out vec4 finalColor;
|
||||
|
||||
in vec2 UV;
|
||||
|
||||
uniform sampler2D mainColorTexture;
|
||||
uniform sampler2D bloomTexture;
|
||||
uniform float bloomIntensity;
|
||||
|
||||
void main() {
|
||||
vec3 scene = texture(mainColorTexture, UV).rgb;
|
||||
vec3 bloom = texture(bloomTexture, UV).rgb;
|
||||
|
||||
vec3 color = scene + bloom * bloomIntensity;
|
||||
finalColor = vec4(color, 1.0);
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2025 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
layout (location = 0) out vec4 finalColor;
|
||||
|
||||
in vec2 UV;
|
||||
|
||||
uniform sampler2D mainColorTexture;
|
||||
uniform vec2 blurDirection;
|
||||
uniform float blurMagnitude;
|
||||
|
||||
uniform int n = 3;
|
||||
uniform float offset[3] = float[]( 0, 1.4983346041173402, 3.4961134994916776 );
|
||||
uniform float weight[3] = float[]( 0.112759, 0.224271, 0.21934900000000002 );
|
||||
|
||||
void main() {
|
||||
vec4 sum = vec4(0.0);
|
||||
vec2 tc = UV;
|
||||
float mag = blurMagnitude;
|
||||
float hstep = blurDirection.x;
|
||||
float vstep = blurDirection.y;
|
||||
float h = mag*hstep;
|
||||
float v = mag*vstep;
|
||||
|
||||
sum = texture( mainColorTexture, tc ) * weight[0];
|
||||
for (int i=1; i<n; i++) {
|
||||
sum += texture( mainColorTexture, tc + vec2( offset[i] * h, offset[i] * v ) ) * weight[i];
|
||||
sum += texture( mainColorTexture, tc - vec2( offset[i] * h, offset[i] * v ) ) * weight[i];
|
||||
}
|
||||
|
||||
finalColor = vec4(sum.rgb, 1.0);
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2025 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
layout (location = 0) out vec4 finalColor;
|
||||
|
||||
in vec2 UV;
|
||||
|
||||
uniform sampler2D mainColorTexture;
|
||||
uniform float threshold;
|
||||
|
||||
void main() {
|
||||
vec4 color = texture(mainColorTexture, UV);
|
||||
float brightness = dot(color.rgb, vec3(0.2126, 0.7152, 0.0722));
|
||||
if (brightness > threshold){
|
||||
finalColor = vec4(color.rgb, 1.0);
|
||||
} else {
|
||||
finalColor = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2025 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
in vec4 position;
|
||||
|
||||
out vec2 UV;
|
||||
|
||||
void main() {
|
||||
gl_Position = position;
|
||||
UV = 0.5 + position.xy * 0.5;
|
||||
}
|
||||
@@ -138,6 +138,7 @@ set(OPENSPACE_SOURCE
|
||||
rendering/labelscomponent.cpp
|
||||
rendering/loadingscreen.cpp
|
||||
rendering/luaconsole.cpp
|
||||
rendering/postprocess.cpp
|
||||
rendering/raycastermanager.cpp
|
||||
rendering/renderable.cpp
|
||||
rendering/renderengine.cpp
|
||||
@@ -335,6 +336,7 @@ set(OPENSPACE_HEADER
|
||||
${PROJECT_SOURCE_DIR}/include/openspace/rendering/luaconsole.h
|
||||
${PROJECT_SOURCE_DIR}/include/openspace/rendering/helper.h
|
||||
${PROJECT_SOURCE_DIR}/include/openspace/rendering/labelscomponent.h
|
||||
${PROJECT_SOURCE_DIR}/include/openspace/rendering/postprocess.h
|
||||
${PROJECT_SOURCE_DIR}/include/openspace/rendering/raycasterlistener.h
|
||||
${PROJECT_SOURCE_DIR}/include/openspace/rendering/raycastermanager.h
|
||||
${PROJECT_SOURCE_DIR}/include/openspace/rendering/renderable.h
|
||||
|
||||
@@ -48,11 +48,6 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#define OPENSPACE_MODULE_POSTPROCESSING_ENABLED
|
||||
#ifdef OPENSPACE_MODULE_POSTPROCESSING_ENABLED
|
||||
#include <modules/postprocessing/postprocessingmodule.h>
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
constexpr std::string_view _loggerCat = "FramebufferRenderer";
|
||||
|
||||
@@ -609,10 +604,6 @@ void FramebufferRenderer::update() {
|
||||
|
||||
ghoul::opengl::updateUniformLocations(*_hdrFilteringProgram, _hdrUniformCache);
|
||||
}
|
||||
|
||||
#ifdef OPENSPACE_MODULE_POSTPROCESSING_ENABLED
|
||||
PostprocessingModule::renderer().update();
|
||||
#endif
|
||||
|
||||
if (_fxaaProgram->isDirty()) {
|
||||
_fxaaProgram->rebuildFromFile();
|
||||
@@ -1146,19 +1137,6 @@ void FramebufferRenderer::render(Scene* scene, Camera* camera, float blackoutFac
|
||||
|
||||
glDrawBuffers(1, &ColorAttachmentArray[_pingPongIndex]);
|
||||
glEnablei(GL_BLEND, 0);
|
||||
|
||||
#ifdef OPENSPACE_MODULE_POSTPROCESSING_ENABLED
|
||||
{
|
||||
// Render Postprocessing effects
|
||||
TracyGpuZone("Postprocessing");
|
||||
const ghoul::GLDebugGroup group("Postprocessing");
|
||||
|
||||
PostprocessingModule::renderer().setSceneTexture(
|
||||
_pingPongBuffers.colorTexture[_pingPongIndex]
|
||||
);
|
||||
PostprocessingModule::renderer().render(camera);
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
TracyGpuZone("Overlay")
|
||||
|
||||
@@ -0,0 +1,336 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2025 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/rendering/postprocess.h>
|
||||
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
#include <ghoul/opengl/textureunit.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
namespace {
|
||||
constexpr std::string_view _loggerCat = "PostprocessingBloom";
|
||||
|
||||
constexpr std::string_view BloomPassVertexShaderPath = "${SHADERS}/bloom_pass_vs.glsl";
|
||||
constexpr std::string_view BloomExtractFragmentShaderPath = "${SHADERS}/bloom_extract_fs.glsl";
|
||||
constexpr std::string_view BloomBlurFragmentShaderPath = "${SHADERS}/bloom_blur_fs.glsl";
|
||||
constexpr std::string_view BloomBlendFragmentShaderPath = "${SHADERS}/bloom_blend_fs.glsl";
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
|
||||
PostprocessingBloom::PostprocessingBloom() = default;
|
||||
|
||||
PostprocessingBloom::~PostprocessingBloom() {
|
||||
deinitialize();
|
||||
}
|
||||
|
||||
void PostprocessingBloom::initialize() {
|
||||
const GLfloat vertexData[] = {
|
||||
-1.f, -1.f,
|
||||
1.f, 1.f,
|
||||
-1.f, 1.f,
|
||||
-1.f, -1.f,
|
||||
1.f, -1.f,
|
||||
1.f, 1.f,
|
||||
};
|
||||
|
||||
glGenVertexArrays(1, &_screenQuad);
|
||||
glBindVertexArray(_screenQuad);
|
||||
|
||||
glGenBuffers(1, &_vertexBuffer);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, nullptr);
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
glBindVertexArray(0);
|
||||
|
||||
_extractProgram = ghoul::opengl::ProgramObject::Build(
|
||||
"BloomExtract",
|
||||
absPath(BloomPassVertexShaderPath),
|
||||
absPath(BloomExtractFragmentShaderPath)
|
||||
);
|
||||
if (_extractProgram) {
|
||||
_extractUniforms.mainColorTexture = _extractProgram->uniformLocation("mainColorTexture");
|
||||
_extractUniforms.threshold = _extractProgram->uniformLocation("threshold");
|
||||
}
|
||||
|
||||
_blurProgram = ghoul::opengl::ProgramObject::Build(
|
||||
"BloomBlur",
|
||||
absPath(BloomPassVertexShaderPath),
|
||||
absPath(BloomBlurFragmentShaderPath)
|
||||
);
|
||||
if (_blurProgram) {
|
||||
_blurUniforms.mainColorTexture = _blurProgram->uniformLocation("mainColorTexture");
|
||||
_blurUniforms.blurDirection = _blurProgram->uniformLocation("blurDirection");
|
||||
_blurUniforms.blurMagnitude = _blurProgram->uniformLocation("blurMagnitude");
|
||||
}
|
||||
|
||||
_blendProgram = ghoul::opengl::ProgramObject::Build(
|
||||
"BloomBlend",
|
||||
absPath(BloomPassVertexShaderPath),
|
||||
absPath(BloomBlendFragmentShaderPath)
|
||||
);
|
||||
if (_blendProgram) {
|
||||
_blendUniforms.mainColorTexture = _blendProgram->uniformLocation("mainColorTexture");
|
||||
_blendUniforms.bloomTexture = _blendProgram->uniformLocation("bloomTexture");
|
||||
_blendUniforms.bloomIntensity = _blendProgram->uniformLocation("bloomIntensity");
|
||||
}
|
||||
}
|
||||
|
||||
void PostprocessingBloom::deinitialize() {
|
||||
if (_screenQuad != 0) {
|
||||
glDeleteVertexArrays(1, &_screenQuad);
|
||||
_screenQuad = 0;
|
||||
}
|
||||
|
||||
if (_vertexBuffer != 0) {
|
||||
glDeleteBuffers(1, &_vertexBuffer);
|
||||
_vertexBuffer = 0;
|
||||
}
|
||||
|
||||
if (_bloomFramebuffer != 0) {
|
||||
glDeleteFramebuffers(1, &_bloomFramebuffer);
|
||||
_bloomFramebuffer = 0;
|
||||
}
|
||||
|
||||
if (_blurFramebuffer != 0) {
|
||||
glDeleteFramebuffers(1, &_blurFramebuffer);
|
||||
_blurFramebuffer = 0;
|
||||
}
|
||||
|
||||
if (_bloomTexture != 0) {
|
||||
glDeleteTextures(1, &_bloomTexture);
|
||||
_bloomTexture = 0;
|
||||
}
|
||||
|
||||
if (_blurTexture[0] != 0) {
|
||||
glDeleteTextures(2, _blurTexture);
|
||||
_blurTexture[0] = 0;
|
||||
_blurTexture[1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void PostprocessingBloom::setResolution(int width, int height) {
|
||||
if (_width == width && _height == height) {
|
||||
return;
|
||||
}
|
||||
|
||||
_width = width;
|
||||
_height = height;
|
||||
_bloomWidth = width / 2;
|
||||
_bloomHeight = height / 2;
|
||||
|
||||
createFramebuffers();
|
||||
}
|
||||
|
||||
void PostprocessingBloom::createFramebuffers() {
|
||||
if (_bloomFramebuffer != 0) {
|
||||
glDeleteFramebuffers(1, &_bloomFramebuffer);
|
||||
glDeleteTextures(1, &_bloomTexture);
|
||||
}
|
||||
|
||||
if (_blurFramebuffer != 0) {
|
||||
glDeleteFramebuffers(1, &_blurFramebuffer);
|
||||
glDeleteTextures(2, _blurTexture);
|
||||
}
|
||||
|
||||
glGenTextures(1, &_bloomTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, _bloomTexture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, _bloomWidth, _bloomHeight, 0, GL_RGBA, GL_FLOAT, nullptr);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
glGenTextures(2, _blurTexture);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
glBindTexture(GL_TEXTURE_2D, _blurTexture[i]);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, _bloomWidth, _bloomHeight, 0, GL_RGBA, GL_FLOAT, nullptr);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
}
|
||||
|
||||
glGenFramebuffers(1, &_bloomFramebuffer);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, _bloomFramebuffer);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _bloomTexture, 0);
|
||||
|
||||
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
if (status != GL_FRAMEBUFFER_COMPLETE) {
|
||||
LERROR("Bloom framebuffer is not complete");
|
||||
}
|
||||
|
||||
glGenFramebuffers(1, &_blurFramebuffer);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, _blurFramebuffer);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _blurTexture[0], 0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, _blurTexture[1], 0);
|
||||
|
||||
status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
if (status != GL_FRAMEBUFFER_COMPLETE) {
|
||||
LERROR("Blur framebuffer is not complete");
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
void PostprocessingBloom::update() {
|
||||
if (_extractProgram && _extractProgram->isDirty()) {
|
||||
_extractProgram->rebuildFromFile();
|
||||
_extractUniforms.mainColorTexture = _extractProgram->uniformLocation("mainColorTexture");
|
||||
_extractUniforms.threshold = _extractProgram->uniformLocation("threshold");
|
||||
}
|
||||
|
||||
if (_blurProgram && _blurProgram->isDirty()) {
|
||||
_blurProgram->rebuildFromFile();
|
||||
_blurUniforms.mainColorTexture = _blurProgram->uniformLocation("mainColorTexture");
|
||||
_blurUniforms.blurDirection = _blurProgram->uniformLocation("blurDirection");
|
||||
_blurUniforms.blurMagnitude = _blurProgram->uniformLocation("blurMagnitude");
|
||||
}
|
||||
|
||||
if (_blendProgram && _blendProgram->isDirty()) {
|
||||
_blendProgram->rebuildFromFile();
|
||||
_blendUniforms.mainColorTexture = _blendProgram->uniformLocation("mainColorTexture");
|
||||
_blendUniforms.bloomTexture = _blendProgram->uniformLocation("bloomTexture");
|
||||
_blendUniforms.bloomIntensity = _blendProgram->uniformLocation("bloomIntensity");
|
||||
}
|
||||
}
|
||||
|
||||
void PostprocessingBloom::render(GLuint inputTexture) {
|
||||
if (!_enabled || !_extractProgram || !_blurProgram || !_blendProgram) {
|
||||
return;
|
||||
}
|
||||
|
||||
GLint defaultFbo;
|
||||
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFbo);
|
||||
|
||||
renderExtract(inputTexture);
|
||||
renderBlur();
|
||||
renderBlend(inputTexture);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, defaultFbo);
|
||||
}
|
||||
|
||||
void PostprocessingBloom::renderExtract(GLuint inputTexture) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, _bloomFramebuffer);
|
||||
glViewport(0, 0, _bloomWidth, _bloomHeight);
|
||||
|
||||
_extractProgram->activate();
|
||||
|
||||
ghoul::opengl::TextureUnit textureUnit;
|
||||
textureUnit.activate();
|
||||
glBindTexture(GL_TEXTURE_2D, inputTexture);
|
||||
glUniform1i(_extractUniforms.mainColorTexture, textureUnit);
|
||||
glUniform1f(_extractUniforms.threshold, _threshold);
|
||||
|
||||
glBindVertexArray(_screenQuad);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
glBindVertexArray(0);
|
||||
|
||||
_extractProgram->deactivate();
|
||||
}
|
||||
|
||||
void PostprocessingBloom::renderBlur() {
|
||||
_blurProgram->activate();
|
||||
|
||||
int sourceBuffer = 0;
|
||||
int targetBuffer = 1;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, _bloomTexture);
|
||||
|
||||
for (int pass = 0; pass < _blurPasses; pass++) {
|
||||
// Horizontal pass
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, _blurFramebuffer);
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0 + targetBuffer);
|
||||
glViewport(0, 0, _bloomWidth, _bloomHeight);
|
||||
|
||||
ghoul::opengl::TextureUnit textureUnit;
|
||||
textureUnit.activate();
|
||||
if (pass == 0) {
|
||||
glBindTexture(GL_TEXTURE_2D, _bloomTexture);
|
||||
} else {
|
||||
glBindTexture(GL_TEXTURE_2D, _blurTexture[sourceBuffer]);
|
||||
}
|
||||
|
||||
glUniform1i(_blurUniforms.mainColorTexture, textureUnit);
|
||||
glUniform2f(_blurUniforms.blurDirection, 1.0f, 0.0f);
|
||||
glUniform1f(_blurUniforms.blurMagnitude, _blurMagnitude);
|
||||
|
||||
glBindVertexArray(_screenQuad);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
glBindVertexArray(0);
|
||||
|
||||
std::swap(sourceBuffer, targetBuffer);
|
||||
|
||||
// Vertical pass
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0 + targetBuffer);
|
||||
|
||||
textureUnit.activate();
|
||||
glBindTexture(GL_TEXTURE_2D, _blurTexture[sourceBuffer]);
|
||||
glUniform1i(_blurUniforms.mainColorTexture, textureUnit);
|
||||
glUniform2f(_blurUniforms.blurDirection, 0.0f, 1.0f);
|
||||
glUniform1f(_blurUniforms.blurMagnitude, _blurMagnitude);
|
||||
|
||||
glBindVertexArray(_screenQuad);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
glBindVertexArray(0);
|
||||
|
||||
std::swap(sourceBuffer, targetBuffer);
|
||||
}
|
||||
|
||||
_blurProgram->deactivate();
|
||||
}
|
||||
|
||||
void PostprocessingBloom::renderBlend(GLuint inputTexture) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glViewport(0, 0, _width, _height);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_ONE, GL_ONE);
|
||||
|
||||
_blendProgram->activate();
|
||||
|
||||
ghoul::opengl::TextureUnit mainTextureUnit;
|
||||
mainTextureUnit.activate();
|
||||
glBindTexture(GL_TEXTURE_2D, inputTexture);
|
||||
glUniform1i(_blendUniforms.mainColorTexture, mainTextureUnit);
|
||||
|
||||
ghoul::opengl::TextureUnit bloomTextureUnit;
|
||||
bloomTextureUnit.activate();
|
||||
glBindTexture(GL_TEXTURE_2D, _blurTexture[0]);
|
||||
glUniform1i(_blendUniforms.bloomTexture, bloomTextureUnit);
|
||||
glUniform1f(_blendUniforms.bloomIntensity, _intensity);
|
||||
|
||||
glBindVertexArray(_screenQuad);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
glBindVertexArray(0);
|
||||
|
||||
_blendProgram->deactivate();
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
@@ -514,6 +514,10 @@ void RenderEngine::initializeGL() {
|
||||
_renderer.setHDRExposure(_hdrExposure);
|
||||
_renderer.initialize();
|
||||
|
||||
_bloom.initialize();
|
||||
const glm::ivec2 res = renderingResolution();
|
||||
_bloom.setResolution(res.x, res.y);
|
||||
|
||||
// set the close clip plane and the far clip plane to extreme values while in
|
||||
// development
|
||||
global::windowDelegate->setNearFarClippingPlane(0.001f, 1000.f);
|
||||
@@ -553,6 +557,7 @@ void RenderEngine::initializeGL() {
|
||||
void RenderEngine::deinitializeGL() {
|
||||
ZoneScoped;
|
||||
|
||||
_bloom.deinitialize();
|
||||
_renderer.deinitialize();
|
||||
}
|
||||
|
||||
@@ -600,6 +605,9 @@ void RenderEngine::updateRenderer() {
|
||||
if (windowResized) {
|
||||
_renderer.setResolution(renderingResolution());
|
||||
|
||||
const glm::ivec2 res = renderingResolution();
|
||||
_bloom.setResolution(res.x, res.y);
|
||||
|
||||
using FR = ghoul::fontrendering::FontRenderer;
|
||||
FR::defaultRenderer().setFramebufferSize(fontResolution());
|
||||
FR::defaultProjectionRenderer().setFramebufferSize(renderingResolution());
|
||||
@@ -614,6 +622,7 @@ void RenderEngine::updateRenderer() {
|
||||
}
|
||||
|
||||
_renderer.update();
|
||||
_bloom.update();
|
||||
}
|
||||
|
||||
void RenderEngine::updateScreenSpaceRenderables() {
|
||||
@@ -914,6 +923,39 @@ float RenderEngine::combinedBlackoutFactor() const {
|
||||
void RenderEngine::postDraw() {
|
||||
ZoneScoped;
|
||||
|
||||
// Apply bloom postprocessing effect
|
||||
if (_bloom.isEnabled()) {
|
||||
// Copy current framebuffer to texture for bloom processing
|
||||
GLint currentFbo;
|
||||
glGetIntegerv(GL_FRAMEBUFFER_BINDING, ¤tFbo);
|
||||
|
||||
// Create temporary texture to capture current framebuffer content
|
||||
static GLuint captureTexture = 0;
|
||||
static glm::ivec2 lastRes = glm::ivec2(0);
|
||||
const glm::ivec2 res = renderingResolution();
|
||||
|
||||
if (captureTexture == 0 || lastRes != res) {
|
||||
if (captureTexture != 0) {
|
||||
glDeleteTextures(1, &captureTexture);
|
||||
}
|
||||
glGenTextures(1, &captureTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, captureTexture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, res.x, res.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
lastRes = res;
|
||||
}
|
||||
|
||||
// Copy current framebuffer to texture
|
||||
glBindTexture(GL_TEXTURE_2D, captureTexture);
|
||||
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, res.x, res.y, 0);
|
||||
|
||||
// Apply bloom effect
|
||||
_bloom.render(captureTexture);
|
||||
}
|
||||
|
||||
++_frameNumber;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user