我正在尝试使用现代 OpenGL 实现累积运动模糊(是的,我知道它很慢并且可以说是现实的,以防 Nicol Bolas 会质疑......但这就是我需要的)。我的参考来源是 OpenGL SuperBible-5。
它对我不起作用。输出中没有模糊。我将 6 个纹理传递给片段着色器,看起来它们都具有相同的帧。
此外,我从 OpenGL 获取调试日志,并显示以下消息:
严重性:中,消息:像素补丁性能警告:像素传输与 3D 渲染同步。
对我来说,看起来 PBO 无法将像素从后缓冲区传输到纹理中,或者无法从后缓冲区获取像素。
这是我的设置:
GLint dataSize = _viewportW * _viewportH * 4 * sizeof(GLfloat);
void* data = (void*)malloc(dataSize);
memset(data, 0x00, dataSize);
glGenBuffers(1,&_pbo1);
glBindBuffer(GL_PIXEL_PACK_BUFFER,_pbo1);
glBufferData(GL_PIXEL_PACK_BUFFER,dataSize,data,GL_DYNAMIC_COPY);
glBindBuffer(GL_PIXEL_PACK_BUFFER , 0);
_blurTexs.resize(mbSamplesNum);
for(GLint i = 0; i <mbSamplesNum; ++i) {
glGenTextures(1, &_blurTexs[i]);
glActiveTexture(GL_TEXTURE0 + i);
glBindTexture(GL_TEXTURE_2D, _blurTexs[i]);
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_MIN_FILTER, GL_NEAREST );
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexStorage2D(GL_TEXTURE_2D,1, GL_RGBA8, _viewportW, _viewportH);
glTexSubImage2D(GL_TEXTURE_2D,0,0,0,_viewportW,_viewportH,GL_RGBA,GL_UNSIGNED_BYTE,data);
glBindTexture(GL_TEXTURE_2D,0);
}
这是渲染循环:
// HERE DRAW STUFF INTO BACKBUFFER.....
glBindBuffer(GL_PIXEL_PACK_BUFFER, _pbo1);
glReadPixels(0, 0, _viewportW, _viewportH, GL_RGBA, GL_UNSIGNED_BYTE, BUFFER_OFFSET(0));
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
// Next bind the PBO as the unpack buffer, then push the pixels straight into the texture
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _pbo1);
// Setup texture unit for new blur, this gets imcremented every frame
GLuint curIndex =GetBlurTarget0();
glBindTexture(GL_TEXTURE_2D,_blurTexs[curIndex]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, _viewportW, _viewportH, 0, GL_RGBA, GL_UNSIGNED_BYTE, BUFFER_OFFSET(0));
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
// Draw full screen quad with blur shader and all blur textures:
_progManager->BindPipeline(ACCUM_PIPELINE);
GLuint fragProg =GetProg();
GLuint t0= GetBlurTarget0();
GLuint t1= GetBlurTarget1();
GLuint t2= GetBlurTarget2();
GLuint t3= GetBlurTarget3();
GLuint t4= GetBlurTarget4();
GLuint t5= GetBlurTarget5();
glActiveTexture(GL_TEXTURE0 );
glBindTexture(GL_TEXTURE_2D,_blurTexs[t0]);
glActiveTexture(GL_TEXTURE1 );
glBindTexture(GL_TEXTURE_2D,_blurTexs[t1]);
glActiveTexture(GL_TEXTURE2 );
glBindTexture(GL_TEXTURE_2D,_blurTexs[t2]);
glActiveTexture(GL_TEXTURE3 );
glBindTexture(GL_TEXTURE_2D,_blurTexs[t3]);
glActiveTexture(GL_TEXTURE4 );
glBindTexture(GL_TEXTURE_2D,_blurTexs[t4]);
glActiveTexture(GL_TEXTURE5 );
glBindTexture(GL_TEXTURE_2D,_blurTexs[t5]);
_screenQuad->Draw();
glBindTexture(GL_TEXTURE_2D,0);
AdvanceBlurTaget();
_progManager->UnBindPipeline();
这是我的片段着色器:
#version 420 core
// This is the output color
out vec4 color;///layout (location = 0)
const int numFrames =6;
layout(binding=0)uniform sampler2D textureUnit0;
layout(binding=1)uniform sampler2D textureUnit1;
layout(binding=2)uniform sampler2D textureUnit2;
layout(binding=3)uniform sampler2D textureUnit3;
layout(binding=4)uniform sampler2D textureUnit4;
layout(binding=5)uniform sampler2D textureUnit5;
void main(void)
{
vec2 texelSize = 1.0 / vec2(textureSize(textureUnit0, 0));
vec2 screenTexCoords = gl_FragCoord.xy * texelSize;
// 0 is the newest image and 5 is the oldest
vec4 blur0 = texture(textureUnit0, texelSize);
vec4 blur1 = texture(textureUnit1, texelSize);
vec4 blur2 = texture(textureUnit2, texelSize);
vec4 blur3 = texture(textureUnit3, texelSize);
vec4 blur4 = texture(textureUnit4, texelSize);
vec4 blur5 = texture(textureUnit5, texelSize);
vec4 summedBlur = blur0 + blur1 + blur2 + blur3 + blur4 + blur5;
color = summedBlur / numFrames;
}
更新
好吧,好吧,我的坏....
片段着色器中的愚蠢错误:
vec2 screenTexCoords = gl_FragCoord.xy * texelSize;
// 0 is the newest image and 5 is the oldest
vec4 blur0 = texture(textureUnit0, screenTexCoords );
vec4 blur1 = texture(textureUnit1, screenTexCoords );
vec4 blur2 = texture(textureUnit2, screenTexCoords );
vec4 blur3 = texture(textureUnit3, screenTexCoords );
vec4 blur4 = texture(textureUnit4, screenTexCoords );
vec4 blur5 = texture(textureUnit5, screenTexCoords );
我错误地将texelSize传递给 UV 而不是screenTexCoords。