2013-03-13 56 views
5

我一直在爲此摔跤數日。我想我已經把它縮小到每個頂點切線的問題了,但我不確定解決這個問題的最佳方法。Opengl着色器問題 - 怪異的光線反射文物

上下文是iPhone應用程序,opengl es2使用我自己的引擎。我的着色器是使用提供的每個頂點切線創建TBN矩陣的凹凸貼圖(法線貼圖)。頂點着色器將光矢量和眼圖向量轉換爲切空間,並將它們傳遞給片段着色器並計算燈光。但是我的前兩種測試模型中的一些幾何圖形在光照中顯示出奇怪的僞影。在鏡面反射組件中最容易看到。

在試圖調試這個我已經取代了普通的地圖與一個平坦的普通PNG ..所有像素是128,128,255。我也硬編碼的顏色。

我的第一個模型是一個按鈕形狀。它顯示了神器在外環上的扇形鏡面反射。需要注意的是,這裏的UV貼圖方法是「平坦」的,以使與貼圖垂直的邊基本上在那裏紋理紋理。我認爲這會使得該幾何體的切線難以計算,因爲兩個點將具有完全相同的紋理座標。

我試着調試渲染,將gl_FragColor設置爲不同的變量。當將其設置爲每個頂點法線時,我們會看到扇形消失,表明法線是正確的。但是,將其設置爲每個頂點的切線時,您可以看到扇貝。

enter image description here

下一個形狀是一個簡單的球體。有了它,模型的頂部和底部就是神器展示的地方。在線框中,您會看到這是幾個三角形在一個頂點會合的地方。因爲每個三角形在那裏都有完全不同的UV映射,所以我無法將自己的頭圍繞在切線的意義上。

我想我會得到很多宣傳的,如果我不顯示着色器代碼...

頂點着色器:

v_fragmentTexCoord0 = a_vertexTexCoord0; 

gl_Position = u_modelViewProjectionMatrix * vec4(a_vertexPosition,1.0); 

vec3 normal = normalize(u_normalMatrix * a_vertexNormal); 
vec3 tangent = normalize(u_normalMatrix * a_vertexTangent); 
vec3 bitangent = cross(normal, tangent); 
mat3 TBNMatrix = mat3(tangent, bitangent, normal); 

v_eyeVec = -a_vertexPosition.xyz; 
v_eyeVec *= TBNMatrix; 

v_lightVec = u_lightPosition - a_vertexPosition.xyz; 
v_lightVec *= TBNMatrix; 

v_normal = a_vertexTangent; 

片段着色器:

vec3 norm = texture2D(u_normalSampler, v_fragmentTexCoord0).rgb * 2.0 - 1.0; 
vec4 baseColor = vec4(0.6015625,0.0,0.0,1.0); // is normally texture2D(u_textureSampler,v_fragmentTexCoord0); 

float dist = length(v_lightVec); 
vec3 lightVector = normalize(v_lightVec); 
float nxDir = max(0.0, dot(norm, lightVector)); 
vec4 diffuse = u_lightColorDiffuse * nxDir; 
float specularPower = 0.0; 
if(nxDir != 0.0) 
{ 
    vec3 cameraVector = v_eyeVec; 
    vec3 halfVector = normalize(v_lightVec + cameraVector); 
    float nxHalf = max(0.0,dot(norm, halfVector)); 
    specularPower = pow(nxHalf, u_shininess); 
} 
vec4 specular = u_lightColorSpecular * specularPower; 

gl_FragColor = (diffuse * vec4(baseColor.rgb,1.0)) + specular; 

在試圖找出着色器並在線查看所有示例和教程時,我可以找到......我爲什麼凹凸貼圖着色器不會干擾3d模型提供的法線貼圖而困惑不解。我猜沒有某種參考點你怎麼知道如何修改模型的正常?按什麼方向?我想這就是TBN矩陣的用途。但是在上面的測試中,法線貼圖中的法線向量是0,0,1 - 直線向上。所以它看起來應該不會修改它。任何次數1仍然是1.但是,在數學或TBN矩陣中必須有足夠的東西,以至於它不會與3d模型中的法線相同。然後,這個想法給我帶來了一些東西......在我的頂點着色器中,我還首先將頂點法線乘以normalMatrix,以將其放入模型空間。但是再一次,這些調試渲染在轉換之前是頂點正常的。

是否有另一種方法干擾模型的正常而不使用TBN矩陣?在沒有法線貼圖的情況下使用phong着色器進行渲染不會顯示工件。

更新:我幾乎肯定問題是由導入應用程序創建的預先準確的切線。在嘗試使用不同UV地圖的不同模型後,我發現類似的外觀問題,有時是黑暗而不是亮點。因此,除非我可以應用沒有TBM矩陣或轉換爲切線空間的法線貼圖,否則我需要找到另一個導入程序。

更新#2:我剛發現這個問題聽起來像是一個線索,可能是真正的問題。 3d graphics, unit vectors and orthogonal matrices

重要的是要注意,這些奇怪的燈光不會發生在頂點,而只發生在它們之間。即使在球體上,我們也看到一個位於頂部頂點和它下面的頂點之間的環。我開始相信這是一個插值問題。就拿只是那些三角形在那裏的一個:

enter image description here

忽略了第二個原因,我重新計算,壞二重。但切線具有相反的極性。所以,當在這兩個狀態之間進行插值時,你會得到指向所有位置的向量。

新的問題是我該如何解決它?修正切線?修復着色器來處理它?

+0

爲什麼不將正常矢量和切線矢量(LERP'd)傳遞給片段着色器,並在那裏處理TBN變換?如果法線在每個頂點都有所不同,則可以通過每片段計算得到更平滑的結果。 – 2013-03-13 12:59:05

+0

我想我擔心它會太慢。當它具有紋理貼圖和凹凸貼圖時,它看起來非常好,而且你不會注意到它。如果它能解決我的問題。 – badweasel 2013-03-13 13:41:39

+0

對於着色器來說沒有多大意義,特別是與'pow'函數類似的配置文件相比。正如你所說,這可能不是問題的根源。 – 2013-03-13 13:55:13

回答