2014-10-18 66 views
1

我試圖進行運動模糊後處理效果在GPU精粹3第27章所描述的,但由於模糊抖動,當我移動相機,並沒有按預期工作,我遇到的問題。 這是我的片段着色器:GLSL運動模糊抖動的

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是進行了如下的模型視圖和投影矩陣:

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

制服matrixPrevVPmatrixPrev是以前的模型視圖和投影矩陣得到渲染後如下:(以下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產生相同的彩色屏幕,除了當相機旋轉顏色似乎顛倒了,所以我懷疑有什麼不對的提取世界從深度的位置。

我在這裏錯過了什麼嗎?任何幫助將不勝感激。

+0

在你的代碼中,你做了16次模糊採樣。請注意,這意味着您需要每像素16倍採樣。好多啊。您是否嘗試將其降至例如4次?效果好嗎?你還看到抖動?單單根據代碼很難說任何事情,也許有些實驗會顯示出什麼是錯的。 – Krystian 2014-10-20 11:31:58

回答

0

忘了我以前的答案,是一個矩陣的錯誤:

矩陣乘法是在錯誤的命令或其他地方搞砸了,你必須送轉置矩陣(解釋爲什麼只有旋轉拍攝於acount,平移/縮放組件):

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

成爲

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

(注16不是矩陣大小,但矩陣算的,所以它應該只有唯一的Ø NE這裏)

另注:您應該計算逆矩陣和項目*在你的主應用程序視圖結果矩陣,沒有像素着色器:它做一次每像素,但應該每幀只有一次)

過去的帖子說明:谷歌「RuinIsland_GLSL_Demo.zip」:它包含很多很好的glsl樣本,幫我解決了這個問題

+0

你應該編輯你以前的答案,而不是像這樣發佈另一個 – camelccc 2015-01-22 00:07:55

+0

我最終放棄了這個項目,但是在編碼另一個項目時,我成功地實現了運動模糊。在這個新項目上實現自定義矩陣堆棧時我注意到的一件事是,我應該將1作爲參數而不是16,否則它會發送滿零的矩陣。我認爲這是我的舊項目唯一的錯誤,所以我接受了這一點。謝謝! – Intellectual 2015-02-03 17:09:20

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 但我的透視投影矩陣不符合要求,也許它會幫助你。