[英]Image blur effect in shaders
I want to do image effects such as screen blur in my game but I have a problem that it just darkens the screen slightly. 我想在我的游戏中进行屏幕模糊等图像效果,但我有一个问题,它只是略微使屏幕变暗。
Here is the class for the FBO 这是FBO的课程
GLuint m_fbo;
GLuint m_fboTexture;
GLuint m_fboDepthBuffer;
void FBO::Initialize(float width, float height)
{
glGenFramebuffersEXT(1, &m_fbo);
glGenTextures(1, &m_fboTexture);
glGenRenderbuffersEXT(1, &m_fboDepthBuffer);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, m_fboTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glGenerateMipmapEXT(GL_TEXTURE_2D);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, (GLuint)width, (GLuint)height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_fboTexture, 0);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_fboDepthBuffer);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, (GLuint)width, (GLuint)height);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_fboDepthBuffer);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glDisable(GL_TEXTURE_2D);
}
void FBO::Bind()
{
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
}
void FBO::UnBind()
{
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}
void FBO::Clear()
{
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}
This is how I set it up in my main class. 这就是我在主课堂中设置它的方法。
FBO m_fbo;//create an object
//initialize size
m_fbo.Initiliazie(screen_width, screen_height);
In my render function I do this 在我的渲染功能中,我这样做
void Render()
{
SetShaderProgram();//start shader program
m_fbo.Bind();
SetShaderImageSampler("texture", 0, m_fbo.m_fboTexture);
SetShaderUniformVec2("size", (float)SCREEN_WIDTH, (float)SCREEN_HEIGHT);
SetShaderUniformInt("kernel_size", ksize);
//draws my texture
m_spriteBatch->Draw(RecTangle(0, 0, (float)SCREEN_WIDTH, (float)SCREEN_HEIGHT));
m_fbo.UnBind();
EndShaderProgram();//end shader program
}
This is what SetShaderImageSampler function does: 这就是SetShaderImageSampler函数的作用:
void SetShaderImageSampler(char *sSamplerName, U32 nSlot, GLuint nHandle)
{
glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0 + nSlot);
glBindTexture(GL_TEXTURE_2D, nHandle);
U32 nSamplerLoc = glGetUniformLocation(m_shaderProgram, sSamplerName);
glUniform1iARB(nSamplerLoc, nSlot);
}
This is my spritebatch draw 这是我的spritebatch画
void SpriteBatch::Draw(RecTangle rect)
{
//draws it depending on its center
float left = -(rect.right/2.0f);
float right = left + (rect.right);
float top = -(rect.bottom/2.0f);
float bottom = top + (rect.bottom);
//vertices: Vertex(x, y, z, u, v) coordinates
m_vertex[0] = Vertex(left, top, 0, 0, 0);
m_vertex[1] = Vertex(right, top, 0, 1, 0);
m_vertex[2] = Vertex(right, bottom, 0, 1, 1);
m_vertex[3] = Vertex(left, bottom, 0, 0, 1);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(Vertex), &m_vertex[0].m_fX);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &m_vertex[0].m_fU);
glDrawArrays(GL_QUADS, 0, 4);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glColor4f(0.5f, 0.5f, 0.5f, 0.5f);
}
This is my frag shader 这是我的碎片着色器
uniform sampler2D texture;
uniform vec2 size;
uniform int kernel_size;
void main (void)
{
vec4 color = vec4(0.0, 0.0, 0.0, 1.0);
vec2 st = gl_TexCoord[0].st;
vec2 texel = 1.0/size;
int sum = 0;
for(int i=-kernel_size; i <= kernel_size; i++)
{
vec4 value = texture2D(texture, st + vec2(0.0, texel.y * i));
int factor = kernel_size+1 - abs((float)i);
color += value * factor;
sum += factor;
}
color /= sum;
gl_FragColor = color;
gl_FragColor.a = 1.0;
}
Its not working too well. 它工作得不好。 I tried changing the shader to do something else but it just slighly darkens it no matter what.
我尝试更改着色器以执行其他操作,但无论如何它都会使它变暗。
解开应该是
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
Maybe you haven't included enough code but I don't see you actually rendering anything in your Render method. 也许您没有包含足够的代码,但我没有看到您实际渲染Render方法中的任何内容。
You have some calls the first of which I assume activate's the context, then you bind the frame buffer and link the shader variables, but next I would expect a call to render a quad / mesh somehow (ie with a glBegin/glEnd section or a vertex buffer bind and render.) 你有一些调用第一个我假设激活的上下文,然后你绑定帧缓冲区并链接着色器变量,但接下来我希望调用以某种方式渲染四元组/网格(即使用glBegin / glEnd部分或顶点缓冲区绑定和渲染。)
Ok, generally to do post processing effects you would render the scene with the frame buffer active. 好的,通常要做后期处理效果,你会在帧缓冲区激活的情况下渲染场景。 Then render a full screen quad with your post process (blur) shader active and the frame buffer textures bound as samplers.
然后使用后期处理(模糊)着色器激活并将帧缓冲区纹理绑定为采样器来渲染全屏四边形。
Nevenmind I have it working now. Nevenmind我现在正在工作。 I was calling Bind and UnBind in the wrong place.
我把Bind和UnBind称为错误的地方。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.