GLSL运动模糊抖动



我试图实现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);
}

一致的matrixVPmatrix是ModelView和Projection矩阵,得到如下:

float matrix[16];
float VPmatrix[16];
glGetFloatv(GL_MODELVIEW_MATRIX, matrix);
glGetFloatv(GL_PROJECTION_MATRIX, VPmatrix);

统一的matrixPrevVPmatrixPrev是渲染后得到的先前ModelView和Projection矩阵,如下所示:(在下面的代码中,matrixPrevVPmatrixPrev是全局变量)

for(int i = 0; i < 16; i++) {
    matrixPrev[i] = matrix[i];
    VPmatrixPrev[i] = VPmatrix[i];
}

所有四个矩阵都传递给着色器,如下所示:

glUniformMatrix4fvARB(glGetUniformLocationARB(postShader, "matrix"), 16, GL_FALSE, matrix);
glUniformMatrix4fvARB(glGetUniformLocationARB(postShader, "VPmatrix"), 16, GL_FALSE, VPmatrix);
glUniformMatrix4fvARB(glGetUniformLocationARB(postShader, "matrixPrev"), 16, GL_FALSE, matrixPrev);
glUniformMatrix4fvARB(glGetUniformLocationARB(postShader, "VPmatrixPrev"), 16, GL_FALSE, VPmatrixPrev);

在着色器中,统一zTexture是一个包含帧缓冲区深度值的纹理。(不确定是否除以W)

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

我是不是遗漏了什么?如有任何帮助,我们将不胜感激。

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

矩阵乘法的顺序是错误的,否则你必须发送转置矩阵(解释为什么只有旋转是在计数、平移/缩放组件中进行的):

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

成为

glUniformMatrix4fvARB(glGetUniformLocationARB(postShader, "matrix"), 1, GL_TRUE, matrix);

(注意16不是矩阵大小,而是矩阵计数,所以这里应该只有一个)

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

过去的帖子注释:谷歌"RuinIsland_GLSL_Demo.zip":它包含了许多好的GLSL样本,帮助我解决了这个问题

很抱歉,我没有答案,只有一条线索:我和你的问题完全一样。我想我使用了谷歌指出的相同材料,和你一样,只有当相机旋转时,模糊才会存在。

然而,我有一个线索(事实上和你的一样):我认为这是因为网络周围的glsl着色器假设我们的深度纹理包含z/w,但和我一样,你使用了使用固定管道填充的真正深度纹理。所以你只有z,而你在第一步就错过了w。由于"texture2D(zTexture,texCoord).r"只包含z:我们错过了获取zOverW的计算。最后,我们被困在了从窗口spce到剪辑空间的一半。

我发现:https://www.opengl.org/wiki/Compute_eye_space_from_window_space#From_NDC_to_clip但是我的透视投影矩阵不符合要求,也许它会对你有所帮助。

相关内容

  • 没有找到相关文章

最新更新