使用现代OpenGL累积运动模糊

时间:2013-07-17 11:07:03

标签: opengl glsl

我正在尝试使用现代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

0 个答案:

没有答案