2012-10-11 30 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