2011-04-20 107 views
4

與之前發佈的問題有些類似,我試圖讓法線在我的GLSL應用中正確顯示。 爲了我的解釋,我使用隨RenderMonkey提供的ninjaHead.obj模型進行測試(you can grab it here)。現在,在RenderMonkey的預覽窗口中,一切看起來不錯: RenderMonkey 分別產生的頂點和片段代碼:GLSL法線效果奇怪

頂點:

uniform vec4 view_position; 

varying vec3 vNormal; 
varying vec3 vViewVec; 

void main(void) 
{ 
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; 

    // World-space lighting 
    vNormal = gl_Normal; 
    vViewVec = view_position.xyz - gl_Vertex.xyz; 
} 

片段:

uniform vec4 color; 

varying vec3 vNormal; 
varying vec3 vViewVec; 

void main(void) 
{ 
    float v = 0.5 * (1.0 + dot(normalize(vViewVec), vNormal)); 
    gl_FragColor = v* color; 
} 

我根據我的GLSL代碼,但我沒有得到預期的結果...

My verte X shader代碼:

uniform mat4 P; 
uniform mat4 modelRotationMatrix; 
uniform mat4 modelScaleMatrix; 
uniform mat4 modelTranslationMatrix; 
uniform vec3 cameraPosition; 

varying vec4 vNormal; 
varying vec4 vViewVec; 

void main() 
{ 
vec4 pos = gl_ProjectionMatrix * P * modelTranslationMatrix * modelRotationMatrix * modelScaleMatrix * gl_Vertex; 

gl_Position = pos; 

gl_TexCoord[0] = gl_MultiTexCoord0; 

gl_FrontColor = gl_Color; 

vec4 normal4 = vec4(gl_Normal.x,gl_Normal.y,gl_Normal.z,0);  

// World-space lighting 
    vNormal = normal4*modelRotationMatrix; 
    vec4 tempCameraPos = vec4(cameraPosition.x,cameraPosition.y,cameraPosition.z,0);  
    //vViewVec = cameraPosition.xyz - pos.xyz; 
    vViewVec = tempCameraPos - pos; 
} 

我的片段着色器代碼:

varying vec4 vNormal; 
varying vec4 vViewVec; 

void main() 
{ 
    //gl_FragColor = gl_Color; 
    float v = 0.5 * (1.0 + dot(normalize(vViewVec), vNormal)); 
gl_FragColor = v * gl_Color; 
} 

但是我的渲染產生這個... openGL render

有誰知道什麼可能導致這個和/或如何讓它起作用?

編輯 針對kvark的評論,在這裏是沒有任何正常/照明計算顯示所呈現的所有三角形渲染模型。 Render flat shading

這裏是與用於顏色的法線的模型着色。我相信問題已經找到!現在的原因是它爲什麼呈現這樣以及如何解決它?歡迎提出建議! Normal shading

SOLUTION 好大家的問題已經解決了!感謝kvark對他所有有用的見解,這絕對有助於我的編程練習,但恐怕答案來自於我是一個大規模的山雀......我的代碼的display()函數有一個錯誤,它將glNormalPointer偏移量到一個隨機值。它曾經是這樣的:

gl.glEnableClientState(GL.GL_NORMAL_ARRAY); 
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, getNormalsBufferObject()); 
gl.glNormalPointer(GL.GL_FLOAT, 0, getNormalsBufferObject()); 

但應該是這樣的:

gl.glEnableClientState(GL.GL_NORMAL_ARRAY); 
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, getNormalsBufferObject()); 
gl.glNormalPointer(GL.GL_FLOAT, 0, 0); 

所以我想這是一個教訓。永遠不要盲目地按Ctrl + C和Ctrl + V代碼來節省星期五下午的時間,並且...當你確定你正在查看的部分代碼是正確的時,問題可能就在其他地方了!

+0

請始終指定您的OpenGL版本。在GLSL中使用'#version'指令也是一種好的做法。 – Kos 2011-04-23 12:58:19

+0

恭喜!最後:) – kvark 2011-05-03 14:45:31

+1

你應該從你的問題中刪除解決方案,並添加它作爲答案(如果它真的解決了你的問題,接受它)。 – murgatroid99 2011-09-19 02:05:37

回答

1
  1. 什麼是您的P矩陣? (我想這是一個世界 - >相機視圖變換)。

  2. vNormal = normal4*modelRotationMatrix;你爲什麼改變參數的順序?這樣做是通過反轉旋轉來增加法線,這是你並不真正想要的。改用標準訂單(modelRotationMatrix * normal4)

  3. vViewVec = tempCameraPos - pos。這完全不正確。 pos是你的頂點在齊次剪輯空間,而tempCameraPos是在世界空間(我想)。您需要將結果放在與法線(世界空間)相同的空間中,因此對於該方程使用世界空間頂點位置(modelTranslationMatrix * modelRotationMatrix * modelScaleMatrix * gl_Vertex)。

+0

感謝您的回覆。是的,P確實是世界相機矩陣。我已經對(2)和(3)中提出的修改進行了修改,但沒有可見的變化。我無法弄清楚發生了什麼事! – 2011-04-21 10:28:52

+0

@克里斯羅賓遜。你的屏幕截圖顯示一些三角形根本沒有繪製。你能用恆定的顏色填充模型來檢查這個嗎? – kvark 2011-04-21 12:56:12

+0

@kvark當我沒有法線渲染時(即平面着色),模型確實被填充並且所有三角形都被渲染。 – 2011-04-21 14:55:24

0

您似乎在混合GL版本有點?您正通過制服手動傳遞矩陣,但使用固定函數傳遞頂點屬性。嗯。無論如何...


我真誠地不喜歡你在做什麼你的法線。看看:

vec4 normal4 = vec4(gl_Normal.x,gl_Normal.y,gl_Normal.z,0);  

vNormal = normal4*modelRotationMatrix; 

一個正常只存儲方向性數據,爲什麼使用它一個vec4它?我相信只要使用vec3就更加優雅。此外,看看接下來會發生什麼 - 將法線與4x4模型旋轉矩陣相乘...此外,您的法線的第四個座標等於0,因此它不是均勻座標中的正確矢量。我不確定這是否是主要問題,但如果這種乘法會給你帶來垃圾,我不會感到驚訝。

變換法線的標準方法是將vec3乘以模型視圖矩陣的3x3子矩陣(因爲您只對方向感興趣,而不是翻譯)。那麼,「正確」的方法就是使用該3x3子矩陣的逆轉置(當你縮放時這變得很重要)。在舊的OpenGL版本中,它預先計算爲gl_NormalMatrix

因此,而不是上面的,你應該使用類似

// (...) 
varying vec3 vNormal; 
// (...) 

mat3 normalMatrix = transpose(inverse(mat3(modelRotationMatrix))); 
// or if you don't need scaling, this one should work too- 
mat3 normalMatrix = mat3(modelRotationMatrix); 

vNormal = gl_Normal*normalMatrix; 

這肯定一件事在你的代碼來解決 - 我希望它可以解決你的問題。