glsl - 片段着色器(模糊)->黑屏
在过去的几天里,我一直在努力让它发挥作用,但我真的开始变得绝望了。对于您可能提出的建议,我将非常感激。
我一直在尝试做的事情:
- 将场景渲染到 FBO
- 模糊使用 glsl 着色器附加的纹理
- 将生成的纹理渲染到屏幕对齐的四边形
问题:
如果我启用片段着色器(水平模糊),我确实会得到模糊的图像在第一帧左右渲染到我的四边形,之后它就全黑了。
我怀疑我将纹理传递给着色器的方式有问题:
horizontalBlurVertex.enable();
horizontalBlurFragment.enable();
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, fboTexture);
glUniform1i(glGetUniformLocation(horizontalBlurFragment.program, "RTScene"), 0);
编辑: 另外一条信息: 如果我删除 glUniform1i(glGetUniformLocation(horizontalBlurFragment.program, "RTScene"), 0);我得到完全相同的结果。我猜这表明我的着色器永远不会获取任何纹理数据。
来源:
vertex-shader:
varying vec2 vTexCoord;
void main(void)
{
gl_FrontColor = gl_Color;
gl_Position = ftransform();
vec2 Pos;
Pos = sign(gl_Vertex.xy);
gl_Position = vec4(Pos, 0.0, 1.0);
vTexCoord = Pos * 0.5 + 0.5;
}
fragment-shader:
uniform sampler2D RTScene;
varying vec2 vTexCoord;
const float blurSize = 1.0/800.0;
const float weightSum = 70.0 + 2.0 * (1.0 + 8.0 + 28.0 + 56.0);
void main(void)
{
vec4 sum = vec4(0.0);
sum += texture2D(RTScene, vec2(vTexCoord.x - 4.0*blurSize, vTexCoord.y)) * 1.0 / weightSum;
sum += texture2D(RTScene, vec2(vTexCoord.x - 3.0*blurSize, vTexCoord.y)) * 8.0 / weightSum;
sum += texture2D(RTScene, vec2(vTexCoord.x - 2.0*blurSize, vTexCoord.y)) * 28.0 / weightSum;
sum += texture2D(RTScene, vec2(vTexCoord.x - blurSize, vTexCoord.y)) * 56.0 / weightSum;
sum += texture2D(RTScene, vec2(vTexCoord.x, vTexCoord.y)) * 70.0 / weightSum;
sum += texture2D(RTScene, vec2(vTexCoord.x + blurSize, vTexCoord.y)) * 56.0 / weightSum;
sum += texture2D(RTScene, vec2(vTexCoord.x + 2.0*blurSize, vTexCoord.y)) * 28.0 / weightSum;
sum += texture2D(RTScene, vec2(vTexCoord.x + 3.0*blurSize, vTexCoord.y)) * 8.0 / weightSum;
sum += texture2D(RTScene, vec2(vTexCoord.x + 4.0*blurSize, vTexCoord.y)) * 1.0 / weightSum;
gl_FragColor = sum;
}
渲染到fbo:(
//handels
GLuint fbo, fboTexture, fboDepthbuffer;
// generate namespace for the frame buffer, colorbuffer and depthbuffer
glGenFramebuffersEXT(1, &fbo);
glGenTextures(1, &fboTexture);
glGenRenderbuffersEXT(1, &fboDepthbuffer);
//switch to our fbo so we can bind stuff to it
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
//create the colorbuffer texture and attach it to the frame buffer
glGenTextures(1, &fboTexture);
glBindTexture(GL_TEXTURE_2D, fboTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, fboTexture, 0);
// create a render buffer as our depthbuffer and attach it
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, fboDepthbuffer);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, width, height);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, fboDepthbuffer);
// Go back to regular frame buffer rendering
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
glPushAttrib(GL_VIEWPORT_BIT);
glViewport(0, 0, width, height);
glPushMatrix();
glBegin(GL_QUADS);
glNormal3f(0.0, 0.0, 1.0);
glColor3f(1.0f, 1.0f, 0.0f);
glVertex3f(-0.1, 0.1, -1.0);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(0.1, 0.1, -1.0);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(0.1, -0.1, -1.0);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(-0.1, -0.1, -1.0);
glEnd();
glPopMatrix();
glPopAttrib();
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
不在这里发布我的ShaderLoader源代码,因为使用更简单的着色器(切换颜色等)效果很好)
如果您认为错误出在其他地方我很乐意发布一些额外的代码。
I've been trying to get this to work for the last few days and I'm really starting to become desperate. I'd be really grateful for suggestions you might have.
What I've been trying to do:
- render the scene to an FBO
- blur the attached texture using glsl shaders
- render the resulting texture to a screen aligned quad
Issue:
If I enable the fragment-shader (horizontal blur) i do get a blurred image rendered to my quad for the first frame or so, after that it's all black.
My suspicion is that there i something wrong with the way I'm passing the texture to my shader:
horizontalBlurVertex.enable();
horizontalBlurFragment.enable();
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, fboTexture);
glUniform1i(glGetUniformLocation(horizontalBlurFragment.program, "RTScene"), 0);
EDIT:
One more piece of Information:
if i remove glUniform1i(glGetUniformLocation(horizontalBlurFragment.program, "RTScene"), 0); i get the exact same result. Which i guess indicates that my shader never gets any texture data whatsoever.
sources:
vertex-shader:
varying vec2 vTexCoord;
void main(void)
{
gl_FrontColor = gl_Color;
gl_Position = ftransform();
vec2 Pos;
Pos = sign(gl_Vertex.xy);
gl_Position = vec4(Pos, 0.0, 1.0);
vTexCoord = Pos * 0.5 + 0.5;
}
fragment-shader:
uniform sampler2D RTScene;
varying vec2 vTexCoord;
const float blurSize = 1.0/800.0;
const float weightSum = 70.0 + 2.0 * (1.0 + 8.0 + 28.0 + 56.0);
void main(void)
{
vec4 sum = vec4(0.0);
sum += texture2D(RTScene, vec2(vTexCoord.x - 4.0*blurSize, vTexCoord.y)) * 1.0 / weightSum;
sum += texture2D(RTScene, vec2(vTexCoord.x - 3.0*blurSize, vTexCoord.y)) * 8.0 / weightSum;
sum += texture2D(RTScene, vec2(vTexCoord.x - 2.0*blurSize, vTexCoord.y)) * 28.0 / weightSum;
sum += texture2D(RTScene, vec2(vTexCoord.x - blurSize, vTexCoord.y)) * 56.0 / weightSum;
sum += texture2D(RTScene, vec2(vTexCoord.x, vTexCoord.y)) * 70.0 / weightSum;
sum += texture2D(RTScene, vec2(vTexCoord.x + blurSize, vTexCoord.y)) * 56.0 / weightSum;
sum += texture2D(RTScene, vec2(vTexCoord.x + 2.0*blurSize, vTexCoord.y)) * 28.0 / weightSum;
sum += texture2D(RTScene, vec2(vTexCoord.x + 3.0*blurSize, vTexCoord.y)) * 8.0 / weightSum;
sum += texture2D(RTScene, vec2(vTexCoord.x + 4.0*blurSize, vTexCoord.y)) * 1.0 / weightSum;
gl_FragColor = sum;
}
render to fbo:
//handels
GLuint fbo, fboTexture, fboDepthbuffer;
// generate namespace for the frame buffer, colorbuffer and depthbuffer
glGenFramebuffersEXT(1, &fbo);
glGenTextures(1, &fboTexture);
glGenRenderbuffersEXT(1, &fboDepthbuffer);
//switch to our fbo so we can bind stuff to it
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
//create the colorbuffer texture and attach it to the frame buffer
glGenTextures(1, &fboTexture);
glBindTexture(GL_TEXTURE_2D, fboTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, fboTexture, 0);
// create a render buffer as our depthbuffer and attach it
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, fboDepthbuffer);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, width, height);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, fboDepthbuffer);
// Go back to regular frame buffer rendering
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
glPushAttrib(GL_VIEWPORT_BIT);
glViewport(0, 0, width, height);
glPushMatrix();
glBegin(GL_QUADS);
glNormal3f(0.0, 0.0, 1.0);
glColor3f(1.0f, 1.0f, 0.0f);
glVertex3f(-0.1, 0.1, -1.0);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(0.1, 0.1, -1.0);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(0.1, -0.1, -1.0);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(-0.1, -0.1, -1.0);
glEnd();
glPopMatrix();
glPopAttrib();
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
(not posting my ShaderLoader source here since using simpler shaders (switching colors and whatnot) works perfectly fine)
If you think the error lies somewhere else I'll be happy to post some additional code.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题解决了!
结果我愚蠢地在每一帧创建了我的固定基地台......现在工作得很好。
Problem solved!
Turns out I foolishly created my fbo every frame... works perfectly fine now.