Reputation: 2268
I am following the following shader to create a blur.
OpenGL es 2.0 Gaussian blur on triangle
First i generate framebuffers.
glGenTextures(2, texObj);
glGenFramebuffers(2, fbObj);
glActiveTexture(GL_TEXTURE0);
for (int i = 0; i < 2; i++)
{
glBindTexture(GL_TEXTURE_2D, texObj[i]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1920, 1080, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glGenerateMipmap(GL_TEXTURE_2D);
glBindFramebuffer(GL_FRAMEBUFFER, fbObj[i]);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texObj[i], 0);
GLuint renderbuffer;
glGenRenderbuffers(1, &renderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, 1920, 1080);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderbuffer);
}
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
Than i follow these steps.
// first create a image of the scene
GLint drawFrameBuffer;
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &drawFrameBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, fbObj[0]);
ResourceManager::GetShader("BasicShader").Use();
//ResourceManager::GetShader("BasicShader").SetInteger("UseColorMap", false);
glDisable(GL_DEPTH_TEST);
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT );
geom->draw();
// Set the Blur in X direction
glBindFramebuffer(GL_FRAMEBUFFER, fbObj[1]);
ResourceManager::GetShader("shaderTest").Use();
// Set the blur shader properties
ResourceManager::GetShader("shaderTest").SetFloat("u_sigma", intensity);
ResourceManager::GetShader("shaderTest").SetFloat("u_radius", blur);
ResourceManager::GetShader("shaderTest").SetVector2f("u_dir", glm::vec2(1.0, 0.0));
ResourceManager::GetShader("shaderTest").SetVector2f("u_textureSize", glm::vec2(1920.0, 1080.0));
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D, texObj[0]);
glGenerateMipmap(GL_TEXTURE_2D);
drawFullScreenQuad();
// Set the Blur in Y direction
glBindFramebuffer(GL_FRAMEBUFFER, fbObj[0]);
ResourceManager::GetShader("shaderTest").Use();
// Set the blur shader properties
ResourceManager::GetShader("shaderTest").SetFloat("u_sigma", intensity);
ResourceManager::GetShader("shaderTest").SetFloat("u_radius", blur);
ResourceManager::GetShader("shaderTest").SetVector2f("u_dir", glm::vec2(0.0, 1.0));
ResourceManager::GetShader("shaderTest").SetVector2f("u_textureSize", glm::vec2(1920.0, 1080.0));
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D, texObj[1]);
glGenerateMipmap(GL_TEXTURE_2D);
drawFullScreenQuad();
// Render the result to full screen.
glBindFramebuffer(GL_FRAMEBUFFER, drawFrameBuffer);
glClearColor(0.0, 0.0, 0.0, 0.0);
glEnable(GL_DEPTH_TEST);
glActiveTexture(GL_TEXTURE0);
ResourceManager::GetShader("Screen").Use();
glBindTexture(GL_TEXTURE_2D, texObj[0]);
glGenerateMipmap(GL_TEXTURE_2D);
drawFullScreenQuad();
ResourceManager::GetShader("BasicShader").Use();
These are the shaders.
#version 430 core
layout (location = 0) in vec2 aPos;
out vec2 pos;
void main()
{
pos = aPos;
gl_Position = vec4(aPos, 0.0 , 1.0);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
#version 330 core
out vec4 FragColor;
in vec2 pos;
// texture sampler
uniform sampler2D u_texture;
uniform vec2 u_textureSize;
uniform float u_sigma;
uniform float u_radius;
uniform vec2 u_dir;
float CalcGauss( float x, float sigma)
{
if( sigma <= 0.0 )
return 0.0;
return exp( -(x * x) / ( 2.0 * sigma)) / ( 2.0 * 3.14157 * sigma);
}
void main()
{
vec2 texC = pos.st * 0.5 + 0.5;
vec4 texCol = texture2D( u_texture, texC );
vec4 gaussCol = vec4( texCol.rgb, 1.0 );
vec2 step = u_dir / u_textureSize;
float weight;
for ( int i = 1; i <= 16; ++ i )
{
weight = CalcGauss( float(i) / 16.0, u_sigma * 0.5 );
if ( weight < 1.0/255.0 )
break;
texCol = texture2D( u_texture, texC + u_radius * step * float(i) );
gaussCol += vec4( texCol.rgb * weight, weight );
texCol = texture2D( u_texture, texC - u_radius * step * float(i) );
gaussCol += vec4( texCol.rgb * weight, weight );
}
gaussCol.rgb = clamp( gaussCol.rgb / gaussCol.w, 0.0, 1.0 );
FragColor = vec4( gaussCol.rgb , 1.0 );
}
When the value for u_radius and u_sigma is 1 than the blur is smooth.
when u_sigma is 10 and u_radius is 30 than the blur looks like this.
Since that example is using webgl and i am using Opengl would the results vary ?
The new image after values given by Rabbid76.
Upvotes: 1
Views: 715
Reputation: 211258
In the implementation of the shader, the value for sigma has to be in range [0.0, 1.0]. A radius of 30 seems to be to large. Start with u_sigma = 0.5
and u_radius = 10
.
The the shader effect still looks wrong, because the computation of the alpha channel is wrong.
You have copied the shader form a WebGL. WebGL by default uses premultiplied alpha, but your desktop application does not. See Straight versus premultiplied.
Skip the division of the weighted sum of the color channels by the weighted sum of the alpha channel:
gaussCol.rgb = clamp( gaussCol.rgb / gaussCol.w, 0.0, 1.0 );
gaussCol.rgb = clamp(gaussCol.rgb, 0.0, 1.0);
Upvotes: 1