Precompute coefficient in gaussian blur pass

This commit is contained in:
Vincent Lejeune 2014-12-09 18:43:48 +01:00
parent d84d103b03
commit b24fd621a5
5 changed files with 65 additions and 63 deletions

View File

@ -1,7 +1,7 @@
uniform sampler2D source;
uniform layout(rgba16f) restrict writeonly image2D dest;
uniform vec2 pixel;
uniform float sigma;
uniform float weights[7];
// Gaussian separated blur with radius 6.
@ -23,18 +23,10 @@ void main()
barrier();
float g0, g1, g2;
g0 = 1.0 / (sqrt(2.0 * 3.14) * sigma);
g1 = exp(-0.5 / (sigma * sigma));
g2 = g1 * g1;
vec4 sum = local_src[x + 6][y] * g0;
g0 *= g1;
g1 *= g2;
vec4 sum = local_src[x + 6][y] * weights[0];
for (int i = 1; i < 6; i++) {
sum += local_src[6 + x - i][y] * g0;
sum += local_src[6 + x + i][y] * g0;
g0 *= g1;
g1 *= g2;
sum += local_src[6 + x - i][y] * weights[i];
sum += local_src[6 + x + i][y] * weights[i];
}
imageStore(dest, iuv, sum);

View File

@ -1,7 +1,7 @@
uniform sampler2D source;
uniform layout(rgba16f) restrict writeonly image2D dest;
uniform vec2 pixel;
uniform float sigma;
uniform float weights[7];
// Gaussian separated blur with radius 6.
@ -23,18 +23,10 @@ void main()
barrier();
float g0, g1, g2;
g0 = 1.0 / (sqrt(2.0 * 3.14) * sigma);
g1 = exp(-0.5 / (sigma * sigma));
g2 = g1 * g1;
vec4 sum = local_src[x][y + 6] * g0;
g0 *= g1;
g1 *= g2;
vec4 sum = local_src[x][y + 6] * weights[0];
for (int i = 1; i < 6; i++) {
sum += local_src[x][6 + y - i] * g0;
sum += local_src[x][6 + y + i] * g0;
g0 *= g1;
g1 *= g2;
sum += local_src[x][6 + y - i] * weights[i];
sum += local_src[x][6 + y + i] * weights[i];
}
imageStore(dest, iuv, sum);

View File

@ -353,45 +353,63 @@ void PostProcessing::renderGaussian6Blur(FrameBuffer &in_fbo, FrameBuffer &auxil
{
assert(in_fbo.getWidth() == auxiliary.getWidth() && in_fbo.getHeight() == auxiliary.getHeight());
float inv_width = 1.0f / in_fbo.getWidth(), inv_height = 1.0f / in_fbo.getHeight();
{
if (!irr_driver->hasARBComputeShaders())
{
auxiliary.Bind();
FullScreenShader::Gaussian6VBlurShader::getInstance()->SetTextureUnits(in_fbo.getRTT()[0]);
DrawFullScreenEffect<FullScreenShader::Gaussian6VBlurShader>(core::vector2df(inv_width, inv_height), sigmaV);
}
else
{
glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT);
glUseProgram(FullScreenShader::ComputeGaussian6VBlurShader::getInstance()->Program);
FullScreenShader::ComputeGaussian6VBlurShader::getInstance()->SetTextureUnits(in_fbo.getRTT()[0]);
glBindSampler(FullScreenShader::ComputeGaussian6VBlurShader::getInstance()->TU_dest, 0);
glBindImageTexture(FullScreenShader::ComputeGaussian6VBlurShader::getInstance()->TU_dest, auxiliary.getRTT()[0], 0, false, 0, GL_WRITE_ONLY, GL_RGBA16F);
FullScreenShader::ComputeGaussian6VBlurShader::getInstance()->setUniforms(core::vector2df(inv_width, inv_height), sigmaV);
glDispatchCompute((int)in_fbo.getWidth() / 8 + 1, (int)in_fbo.getHeight() / 8 + 1, 1);
}
}
if (!irr_driver->hasARBComputeShaders())
{
if (!irr_driver->hasARBComputeShaders())
{
in_fbo.Bind();
auxiliary.Bind();
FullScreenShader::Gaussian6HBlurShader::getInstance()->SetTextureUnits(auxiliary.getRTT()[0]);
DrawFullScreenEffect<FullScreenShader::Gaussian6HBlurShader>(core::vector2df(inv_width, inv_height), sigmaH);
}
else
{
glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
glUseProgram(FullScreenShader::ComputeGaussian6HBlurShader::getInstance()->Program);
FullScreenShader::ComputeGaussian6HBlurShader::getInstance()->SetTextureUnits(auxiliary.getRTT()[0]);
glBindSampler(FullScreenShader::ComputeGaussian6HBlurShader::getInstance()->TU_dest, 0);
glBindImageTexture(FullScreenShader::ComputeGaussian6HBlurShader::getInstance()->TU_dest, in_fbo.getRTT()[0], 0, false, 0, GL_WRITE_ONLY, GL_RGBA16F);
FullScreenShader::ComputeGaussian6HBlurShader::getInstance()->setUniforms(core::vector2df(inv_width, inv_height), sigmaH);
glDispatchCompute((int)in_fbo.getWidth() / 8 + 1, (int)in_fbo.getHeight() / 8 + 1, 1);
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
}
FullScreenShader::Gaussian6VBlurShader::getInstance()->SetTextureUnits(in_fbo.getRTT()[0]);
DrawFullScreenEffect<FullScreenShader::Gaussian6VBlurShader>(core::vector2df(inv_width, inv_height), sigmaV);
in_fbo.Bind();
FullScreenShader::Gaussian6HBlurShader::getInstance()->SetTextureUnits(auxiliary.getRTT()[0]);
DrawFullScreenEffect<FullScreenShader::Gaussian6HBlurShader>(core::vector2df(inv_width, inv_height), sigmaH);
}
else
{
float g0, g1, g2;
std::vector<float> weightsV;
g0 = 1.f / (sqrtf(2.f * 3.14f) * sigmaV);
g1 = exp(-.5f / (sigmaV * sigmaV));
g2 = g1 * g1;
for (unsigned i = 0; i < 7; i++)
{
weightsV.push_back(g0);
g0 *= g1;
g1 *= g2;
}
glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT);
glUseProgram(FullScreenShader::ComputeGaussian6VBlurShader::getInstance()->Program);
FullScreenShader::ComputeGaussian6VBlurShader::getInstance()->SetTextureUnits(in_fbo.getRTT()[0]);
glBindSampler(FullScreenShader::ComputeGaussian6VBlurShader::getInstance()->TU_dest, 0);
glBindImageTexture(FullScreenShader::ComputeGaussian6VBlurShader::getInstance()->TU_dest, auxiliary.getRTT()[0], 0, false, 0, GL_WRITE_ONLY, GL_RGBA16F);
FullScreenShader::ComputeGaussian6VBlurShader::getInstance()->setUniforms(core::vector2df(inv_width, inv_height), weightsV);
glDispatchCompute((int)in_fbo.getWidth() / 8 + 1, (int)in_fbo.getHeight() / 8 + 1, 1);
std::vector<float> weightsH;
g0 = 1.f / (sqrtf(2.f * 3.14f) * sigmaH);
g1 = exp(-.5f / (sigmaH * sigmaH));
g2 = g1 * g1;
for (unsigned i = 0; i < 7; i++)
{
weightsH.push_back(g0);
g0 *= g1;
g1 *= g2;
}
glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
glUseProgram(FullScreenShader::ComputeGaussian6HBlurShader::getInstance()->Program);
FullScreenShader::ComputeGaussian6HBlurShader::getInstance()->SetTextureUnits(auxiliary.getRTT()[0]);
glBindSampler(FullScreenShader::ComputeGaussian6HBlurShader::getInstance()->TU_dest, 0);
glBindImageTexture(FullScreenShader::ComputeGaussian6HBlurShader::getInstance()->TU_dest, in_fbo.getRTT()[0], 0, false, 0, GL_WRITE_ONLY, GL_RGBA16F);
FullScreenShader::ComputeGaussian6HBlurShader::getInstance()->setUniforms(core::vector2df(inv_width, inv_height), weightsH);
glDispatchCompute((int)in_fbo.getWidth() / 8 + 1, (int)in_fbo.getHeight() / 8 + 1, 1);
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
}
}
void PostProcessing::renderHorizontalBlur(FrameBuffer &in_fbo, FrameBuffer &auxiliary)

View File

@ -1752,7 +1752,7 @@ namespace FullScreenShader
Program = LoadProgram(OBJECT,
GL_COMPUTE_SHADER, file_manager->getAsset("shaders/gaussian6h.comp").c_str());
TU_dest = 1;
AssignUniforms("pixel", "sigma");
AssignUniforms("pixel", "weights");
AssignSamplerNames(Program, 0, "source");
AssignTextureUnit(Program, TexUnit(TU_dest, "dest"));
}
@ -1822,7 +1822,7 @@ namespace FullScreenShader
Program = LoadProgram(OBJECT,
GL_COMPUTE_SHADER, file_manager->getAsset("shaders/gaussian6v.comp").c_str());
TU_dest = 1;
AssignUniforms("pixel", "sigma");
AssignUniforms("pixel", "weights");
AssignSamplerNames(Program, 0, "source");
AssignTextureUnit(Program, TexUnit(TU_dest, "dest"));
}

View File

@ -471,7 +471,7 @@ public:
ComputeGaussian17TapHShader();
};
class ComputeGaussian6HBlurShader : public ShaderHelperSingleton<ComputeGaussian6HBlurShader, core::vector2df, float>, public TextureRead<Bilinear_Clamped_Filtered>
class ComputeGaussian6HBlurShader : public ShaderHelperSingleton<ComputeGaussian6HBlurShader, core::vector2df, std::vector<float> >, public TextureRead<Bilinear_Clamped_Filtered>
{
public:
GLuint TU_dest;
@ -517,7 +517,7 @@ public:
ComputeGaussian17TapVShader();
};
class ComputeGaussian6VBlurShader : public ShaderHelperSingleton<ComputeGaussian6VBlurShader, core::vector2df, float>, public TextureRead<Bilinear_Clamped_Filtered>
class ComputeGaussian6VBlurShader : public ShaderHelperSingleton<ComputeGaussian6VBlurShader, core::vector2df, std::vector<float> >, public TextureRead<Bilinear_Clamped_Filtered>
{
public:
GLuint TU_dest;