GLSL运动模糊抖动

GLSL运动模糊抖动,glsl,motion-blur,Glsl,Motion Blur,我试图实现GPU Gems 3第27章中描述的运动模糊后处理效果,但我遇到了一些问题,因为当我移动相机时,模糊会抖动,无法按预期工作。 这是我的片段着色器: varying vec3 pos; varying vec3 normal; varying vec2 tex; varying vec3 tangent; uniform mat4 matrix; uniform mat4 VPmatrix; uniform mat4 matrixPrev; uniform mat4 VPmatrixPr

我试图实现GPU Gems 3第27章中描述的运动模糊后处理效果,但我遇到了一些问题,因为当我移动相机时,模糊会抖动,无法按预期工作。 这是我的片段着色器:

varying vec3 pos;
varying vec3 normal;
varying vec2 tex;
varying vec3 tangent;
uniform mat4 matrix;
uniform mat4 VPmatrix;
uniform mat4 matrixPrev;
uniform mat4 VPmatrixPrev;
uniform sampler2D diffuseTexture;
uniform sampler2D zTexture;
void main() {
    vec2 texCoord = tex;
    float zOverW = texture2D(zTexture, texCoord).r;
    vec4 H = vec4(texCoord.x * 2.0 - 1.0, (1 - texCoord.y) * 2.0 - 1.0, zOverW, 1.0);
    mat4 inv1 = inverse(matrix);
    mat4 inv2 = inverse(VPmatrix);
    vec4 D = H*(inv2*inv1);
    vec4 worldPos = D/D.w;
    mat4 prev = matrixPrev*VPmatrixPrev;
    vec4 previousPos = worldPos*prev;
    previousPos /= previousPos.w;
    vec2 velocity = vec2((H.x-previousPos.x)/2.0, (H.y-previousPos.y)/2.0);
    vec3 color = vec3(texture2D(diffuseTexture, texCoord));
    for(int i = 0; i < 16; i++) {
        texCoord += velocity;
        vec3 color2 = vec3(texture2D(diffuseTexture, texCoord));
        color += color2;
    }
    color /= 16;
    gl_FragColor = vec4(color, 1.0);
}
matrixPrev和VPmatrixPrev是之前的ModelView,渲染后得到的投影矩阵如下:在下面的代码中,matrixPrev和VPmatrixPrev是全局变量

for(int i = 0; i < 16; i++) {
    matrixPrev[i] = matrix[i];
    VPmatrixPrev[i] = VPmatrix[i];
}
在着色器中,统一zTexture是包含帧缓冲区深度值的纹理。不确定它们是否除以W

我希望着色器能够工作,但我得到的结果是,当我围绕模糊旋转摄影机时,会以非常快的速度进行微妙的旋转。我尝试渲染zTexture,得到的结果是一个灰度图像,所以看起来不错。我还尝试将片段颜色设置为H.xyz和previousPos.xyz,当渲染H.xyz生成彩色屏幕时,previousPos.xyz生成相同的彩色屏幕,只是当相机旋转时,颜色似乎反转,因此我怀疑从深度提取世界位置有问题


我是不是遗漏了什么?非常感谢您的帮助。

很抱歉,我没有答案,只有一个线索: 我和你的问题完全一样。 我想我使用的是谷歌指向的同一种材质,和你一样,只有当相机旋转时才会出现模糊

然而,我有一个与你的相同的线索:我认为这是因为网络周围的glsl着色器假设我们的深度纹理包含z/w,但是,像我一样,你使用了使用固定管道填充的真实深度纹理。 因此,在第一步中,只有z,而缺少w。 由于texture2DzTexture,texCoord.r只包含z:我们错过了获得zOverW的计算。 最后,我们被困在从窗户到剪辑空间的中间

我发现:
但是我的透视投影矩阵不符合要求,也许会对您有所帮助。

忘记我之前的答案,是矩阵错误:

矩阵乘法顺序错误,否则您必须发送转置矩阵,解释为什么在计数、平移/缩放组件中只进行旋转,其中出现混乱:

glUniformMatrix4fvARB(glGetUniformLocationARB(postShader, "matrix"), 16, GL_FALSE, matrix);
变成

glUniformMatrix4fvARB(glGetUniformLocationARB(postShader, "matrix"), 1, GL_TRUE, matrix);
注16不是矩阵大小,而是矩阵计数,因此此处仅为一个

另一个注意事项:您应该在主应用程序中计算逆矩阵和project*view结果矩阵,而不是像素着色器:它每像素执行一次,但每帧仅执行一次


过去的帖子注释:Google ruinsland_GLSL_Demo.zip:它包含了许多好的GLSL示例,帮助我解决了这个问题

在你的代码中,你做了16次模糊采样。请注意,这意味着您需要每像素采样16倍。太多了。您是否尝试将其减少到例如4倍?效果好吗?你还看到抖动吗?单凭代码很难说什么,也许一些实验会证明什么是错误的。你应该编辑你以前的答案,而不是像这样发布另一个答案。我最终放弃了那个项目,但在编写另一个项目时,我成功地实现了运动模糊。在这个新项目上实现自定义矩阵堆栈时,我注意到的一点是,我应该将1作为参数传递,而不是16,否则它将发送一个满是零的矩阵。我想这是我以前项目中唯一的错误,所以我接受了。非常感谢。
glUniformMatrix4fvARB(glGetUniformLocationARB(postShader, "matrix"), 16, GL_FALSE, matrix);
glUniformMatrix4fvARB(glGetUniformLocationARB(postShader, "matrix"), 1, GL_TRUE, matrix);