我试图实现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);
}
制服matrix
和VPmatrix
是ModelView和Projection矩阵,具体如下:
float matrix[16];
float VPmatrix[16];
glGetFloatv(GL_MODELVIEW_MATRIX, matrix);
glGetFloatv(GL_PROJECTION_MATRIX, VPmatrix);
制服matrixPrev
和VPmatrixPrev
是之前的ModelView和Projection矩阵,在呈现后得到如下:(在下面的代码matrixPrev
和VPmatrixPrev
是全局变量)< / p>
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.xyz
和previousPos.xyz
,而渲染H.xyz
会生成彩色屏幕,previousPos.xyz
生成相同颜色的屏幕,但相机旋转时除外颜色似乎颠倒了,所以我怀疑从深度中提取世界位置有问题。
我在这里遗漏了什么吗?任何帮助将不胜感激。
答案 0 :(得分:0)
对不起,我没有答案,只是一个线索: 我和你的问题完全相同。 我想我使用了谷歌指出的相同材料,并且和你一样,只有在相机旋转时才会出现模糊现象。
但是我有一个线索(事实上和你的一样):我认为这是因为网周围的glsl着色器假设我们的深度纹理包含z / w但是,像我一样,你使用了一个真正的深度纹理填充使用固定管道。 所以你只有z,而你在第一步中就缺少了w。 由于“texture2D(zTexture,texCoord).r”只包含z:我们错过了计算以获得zOverW。 最后,我们被困在窗口间距中间到剪辑空间。
我发现了这个:https://www.opengl.org/wiki/Compute_eye_space_from_window_space#From_NDC_to_clip 但我的透视投影矩阵不符合要求,也许它会帮助你。
答案 1 :(得分:0)
忘记我以前的答案,是一个矩阵错误:
矩阵乘法的顺序错误,否则你必须发送转置矩阵(解释为什么只有旋转是在acount,translation / scale components中搞乱了):
glUniformMatrix4fvARB(glGetUniformLocationARB(postShader, "matrix"), 16, GL_FALSE, matrix);
变为
glUniformMatrix4fvARB(glGetUniformLocationARB(postShader, "matrix"), 1, GL_TRUE, matrix);
(注意16不是矩阵大小,而是矩阵计数,因此它应该只有一个)
另一个注意事项:您应该在主应用程序中计算逆矩阵和项目*视图结果矩阵,而不是像素着色器:每个像素执行一次,但每帧只应执行一次!)
过去的帖子说明:Google“ RuinIsland_GLSL_Demo.zip ”:它包含很多优秀的glsl示例,帮我解决了这个问题