3

まず、非常に単純な「初心者標準」の頂点シェーダーを次に示します。

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}で呼び出されるLookAt行列(以下のGoコード)です(立方体の頂点座標はすべてであることに注意してください)すべての次元で-0.5から0.5の間なので、0.1は「ほぼ中央」になります)
  • uMatProjは、fov =45アスペクト=winwidth/ winheight near = 0.1 far = 100で呼び出されるパースペクティブマトリックス(以下のコードを参照)です。

理論的には、「カメラ」は、真っ直ぐに面している立方体の「後ろ」に約2〜3ユニットあるはずです。代わりに、私は...

ここに画像の説明を入力してください

ローテーションはどこから来ているのだろうか...私はまだローテーションを実装していません。

要約すると、私は必要な行列関数を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アルゴリズムをどういうわけか台無しにしたのではないかと思います。

4

1 に答える 1

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)
于 2012-10-11T20:03:36.617 に答える