2012-10-11 61 views
3

首先,這裏是非常簡單的「菜鳥標準」頂點着色器:OpenGL的Go矩陣函數(Perspective/Frustum&Lookat矩陣)有什麼問題?

in vec3 aPos; 
uniform mat4 uMatModel; uniform mat4 uMatView; uniform mat4 uMatProj; 

void main() { 
    gl_Position = uMatProj * uMatView * uMatModel * vec4(aPos, 1.0); 
} 

現在就是我的渲染是一個簡單的6面立方體。在36個頂點座標中沒有應用旋轉或固有旋轉。標準教程風格-0.5 .. + 0.5的東西。我會在這裏爲您提供頂點數組,但放心吧,就這麼簡單。

  • uMatModel僅僅是單位矩陣現在,不結垢/平移/旋轉的尚未
  • uMatView注視矩陣(轉到下面的代碼)稱爲與POS = {0.1, 0.1,-3.0},target = {0.1,0.1,0.1},up = {0,1,0}(記住所有維度中的立方體頂點座標都在-0.5和0.5之間,所以0.1s應該是「幾乎中心的「)
  • uMatProj透視矩陣(轉到下面的代碼)調用FOV = 45方面= winwidth/winheight近= 0.1遠= 100

在理論上「相機」應爲約2-3個單位立方體面對它直的「後面」。相反,我得到...

enter image description here

我不知道旋轉是來自......我甚至不具備的旋轉來實現呢。

所以總而言之,我試圖在Go中自己實現所需的矩陣函數,並將數學運算。但是我必須在某個地方搞砸了。 任何人都可以在我的下面的代碼中發現任何矩陣理論問題嗎?

type Mat4x4 [4][4]float64 

func (me *Mat4x4) Identity() { 
    me[0][0], me[0][1], me[0][2], me[0][3] = 1, 0, 0, 0 
    me[1][0], me[1][1], me[1][2], me[1][3] = 0, 1, 0, 0 
    me[2][0], me[2][1], me[2][2], me[2][3] = 0, 0, 1, 0 
    me[3][0], me[3][1], me[3][2], me[3][3] = 0, 0, 0, 1 
} 

func (me *Mat4x4) Frustum (left, right, bottom, top, near, far float64) { 
    me[0][0], me[0][1], me[0][2], me[0][3] = (near * 2)/(right - left), 0, 0, 0 
    me[1][0], me[1][1], me[1][2], me[1][3] = 0, (near * 2)/(top - bottom), 0, 0 
    me[2][0], me[2][1], me[2][2], me[2][3] = (right + left)/(right - left), (top + bottom)/(top - bottom), -(far + near)/(far - near), -1 
    me[3][0], me[3][1], me[3][2], me[3][3] = 0, 0, -(far * near * 2)/(far - near), 0 
} 

func (me *Mat4x4) Perspective (fovY, aspect, near, far float64) { 
    var top = near * math.Tan(fovY * math.Pi/360) 
    var right = top * aspect 
    me.Frustum(aspect * -top, right, -top, top, near, far) 
} 

func (me *Mat4x4) LookAt (eyePos, lookTarget, worldUp *Vec3) { 
    var vz = eyePos.Sub(lookTarget) 
    vz.Normalize() 
    var vx = worldUp.Cross(&vz) 
    vx.Normalize() 
    var vy = vz.Cross(&vx) 
    vy.Normalize() 
    me[0][0], me[0][1], me[0][2], me[0][3] = vx.X, vy.X, vz.X, 0 
    me[1][0], me[1][1], me[1][2], me[1][3] = vx.Y, vy.Y, vz.Y, 0 
    me[2][0], me[2][1], me[2][2], me[2][3] = vx.Z, vy.Z, vz.Z, 0 
    me[3][0], me[3][1], me[3][2], me[3][3] = -((vx.X * eyePos.X) + (vx.Y * eyePos.Y) + (vx.Z * eyePos.Z)), -((vy.X * eyePos.X) + (vy.Y * eyePos.Y) + (vy.Z * eyePos.Z)), -((vz.X * eyePos.X) + (vz.Y * eyePos.Y) + (vz.Z * eyePos.Z)), 1 
} 

注意,VEC3這裏是在同一個包自定義類型,我這裏沒有包括它。現在我假設Vec3函數是正確的(也更容易驗證),並懷疑我在某種程度上搞砸了矩陣結構中的LookAt和/或Perspective算法。

+0

好像他們可能被調換了錯誤的方式,但我不知道有足夠的瞭解。去肯定地說。如果你轉置你的LookAt和Perspective矩陣,它看起來更好嗎?請注意,您可以使用glUniformMatrix中的快速布爾翻轉對其進行轉置,因此您不必編輯實際的矩陣函數。 – Tim

+0

現在我發現GLSL矩陣是列主要的,而我的主要行 - 你肯定是在這裏的錢。將看看這是否解決了這個問題,但它絕對是這裏的錯誤的一部分... – metaleap

+0

更改矩陣庫完全列主要但核心問題沒有改變,仍然45°傾斜相機視圖... – metaleap

回答

1

這是(推測)deg到rad轉換好嗎?

func (me *Mat4x4) Perspective (fovY, aspect, near, far float64) { 
     var top = near * math.Tan(fovY * math.Pi/360) 
     var right = top * aspect 
     me.Frustum(aspect * -top, right, -top, top, near, far) 
} 

也許應該是:

 top := near * math.Tan(fovY * 2 * math.Pi/360) 
+0

Nah,這改變了相機的視角,但核心問題仍然存在,整個視野仍然像45°旋轉... – metaleap