6

LWJGL を使用して OpenGL 3 を学習しています。に相当するものを実装しようとしましたが、gluLookAt()機能しますが、その理由について少し混乱しています。

私はこのコードを Web 上のさまざまなソースからコピーしただけであることを告白しますが、多くの研究の結果、その背後にある数学を理解し、LWJGL が何をしているかを理解していると思います。

gluLookAtただし、カメラが間違った方向を向いているように見えたため、「正しい」コードがアプリケーションで正しく動作しませんでした。forward直交ベクトル、side、および(正しい用語を使用していることを願っています!)を転置することによってのみ、コードを機能させることができましたがup、これは間違っていると確信しています...

private static final Vector3f forward = new Vector3f();
private static final Vector3f side = new Vector3f();
private static final Vector3f up = new Vector3f();
private static final Vector3f eye = new Vector3f();

public static Matrix4f lookAt(float eyeX, float eyeY, float eyeZ, 
                              float centerX, float centerY, float centerZ, 
                              float upX, float upY, float upZ) {
    forward.set(centerX - eyeX, centerY - eyeY, centerZ - eyeZ);
    forward.normalise();

    up.set(upX, upY, upZ);

    Vector3f.cross(forward, up, side);
    side.normalise();

    Vector3f.cross(side, forward, up);
    up.normalise();

    Matrix4f matrix = new Matrix4f();
    matrix.m00 = side.x;
    matrix.m01 = side.y;
    matrix.m02 = side.z;

    matrix.m10 = up.x;
    matrix.m11 = up.y;
    matrix.m12 = up.z;

    matrix.m20 = -forward.x;
    matrix.m21 = -forward.y;
    matrix.m22 = -forward.z;

    matrix.transpose(); // <------ My dumb hack

    eye.set(-eyeX, -eyeY, -eyeZ);
    matrix.translate(eye);

    return matrix;
}

転置を行うべきではないと思いますが、それなしでは機能しません。transpose()ところで、すべてのマトリックスセルの位置を再入力するのが面倒だったので、入れました!

私の理解では、lookAt マトリックスの形式は次のようになります。

[ side.x  up.x  fwd.x  0 ] [ 1  0  0  -eye.x ]
[ side.y  up.y  fwd.y  0 ] [ 0  1  0  -eye.y ]
[ side.z  up.z  fwd.z  0 ] [ 0  0  1  -eye.z ]
[      0     0      0  1 ] [ 0  0  0       1 ]

Matrix4fそして、LWJGLクラスは行列セルを として表していると思いますm<col><row>translate(Vector3f)メソッドは次のことを行います

public static Matrix4f translate(Vector3f vec, Matrix4f src, Matrix4f dest) {
  ...
    dest.m30 += src.m00 * vec.x + src.m10 * vec.y + src.m20 * vec.z;
    dest.m31 += src.m01 * vec.x + src.m11 * vec.y + src.m21 * vec.z;
    dest.m32 += src.m02 * vec.x + src.m12 * vec.y + src.m22 * vec.z;
    dest.m33 += src.m03 * vec.x + src.m13 * vec.y + src.m23 * vec.z;
  ...
}

そのため、私はこれのどの部分を台無しにしたのか、非常に混乱しています。それは、lookAtマトリックス、列/行の主要度(それは単語ですか?!)Matrix4f、または他の何かについての私の理解ですか? 私のコードの残りの部分は壊れていますか? それは本当に正しいのでしょうか?私はただのばかですか?

ありがとう。

4

1 に答える 1

11

何も転置しないでください。lookAt() マトリックスの「目」ベクトルと視線方向を無効にする必要があります。「目」は、常に反転する必要があるカメラ位置に対応します。lookAt() 内で行われるすべてのこと

これは、有名な GLM math libの Java ポートからの lookAt() メソッドです。

 public static Mat4 lookAt(Vec3 eye, Vec3 center, Vec3 up) {

    Vec3 f = normalize(Vec3.sub(center, eye));
    Vec3 u = normalize(up);
    Vec3 s = normalize(cross(f, u));
    u = cross(s, f);

    Mat4 result = new Mat4(1.0f);
    result.set(0, 0, s.x);
    result.set(1, 0, s.y);
    result.set(2, 0, s.z);
    result.set(0, 1, u.x);
    result.set(1, 1, u.y);
    result.set(2, 1, u.z);
    result.set(0, 2, -f.x);
    result.set(1, 2, -f.y);
    result.set(2, 2, -f.z);

    return translate(result, new Vec3(-eye.x,-eye.y,-eye.z));
}

LWJGL ベースの OpenGL 4 レンダラーで使用すると、魅力的に機能します :)

于 2013-02-14T13:04:37.040 に答える