Super duper bloom.

This commit is contained in:
Jonathas Costa
2019-07-13 16:54:44 -04:00
parent e3775849a3
commit 3c5f4afc3f
8 changed files with 102 additions and 23 deletions

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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) {

View File

@@ -61,8 +61,13 @@ namespace {
"Lightness", "colorSpace", "nAaSamples"
};
constexpr const std::array<const char*, 4> BloomUniformNames = {
"renderedImage", "bloomImage", "bloomOrigFactor", "bloomNewFactor"
constexpr const std::array<const char*, 5> BloomUniformNames = {
"renderedImage", "bloomImage", "bloomOrigFactor", "bloomNewFactor",
"numberOfSamples"
};
constexpr const std::array<const char*, 3> BloomFilterUniformNames = {
"numberOfSamples", "msaaTexture", "blurriness"
};
constexpr const std::array<const char*, 4> 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;

View File

@@ -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) {