OpenGL 3(LWJGL)LookAt Matrix混乱 [英] OpenGL 3 (LWJGL) LookAt Matrix Confusion

查看:147
本文介绍了OpenGL 3(LWJGL)LookAt Matrix混乱的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用LWJGL学习OpenGL 3。我试图实现等效于 gluLookAt(),虽然它有效但我有点困惑为什么。



<我承认只是在网上从各种来源复制这些代码,但经过深入研究后,我认为理解它背后的数学,并且我理解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(向前,向上,向侧面);
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(); //< ------我的愚蠢黑客

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

返回矩阵;
}

我不认为我应该进行转置,但它不起作用没有它。我把 transpose(),因为我无法重新键入所有矩阵单元位置btw!



My理解是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]

我认为LWJGL Matrix4f 类将矩阵单元格表示为 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 的列/行主要问题(是一个单词?!)还是别的什么?我的其余代码是否已损坏?它真的是正确的,我只是担心太多了吗?我只是个白痴吗?



谢谢。

解决方案

你应该没有任何转置。你应该否定lookAt()矩阵的眼睛向量和看方向。EYE对应于应该总是反转的摄像机位置。所有这一切都在lookAt()

$ b $内完成b

这是来自着名的GLM数学库。

  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);

返回翻译(结果,新的Vec3(-eye.x,-eye.y,-eye.z));
}

我将它用于基于LWJGL的OpenGL 4渲染器,它就像一个魅力:)


I'm learning OpenGL 3 using LWJGL. I have tried to implement an equivalent to gluLookAt(), and although it works am I somewhat confused as to why.

I confess to just copying this code from various sources on the web, but after much study I think understand the maths behind it, and that I understand what LWJGL is doing.

However the 'correct' gluLookAt code behaved incorrectly in my application, as the camera seemed to be turning the wrong way. I only managed to get my code working by transposing the orthonormal vectors forward, side, and up (hope I'm using the correct terminology!), which I'm pretty sure is wrong...

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;
}

I dont think I should be doing the transpose, but it doesn't work without it. I put transpose() because I couldn't be bothered to retype all the matrix cell positions btw!

My understanding is that the form of the lookAt matrix should be as follows

[ 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 ]

And I think that the LWJGL Matrix4f class represents matrix cells as m<col><row>. The translate(Vector3f) method does the following

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;
  ...
}

So I am left hugely confused as to what part of this I have screwed up. Is it my understanding of the lookAt matrix, the column/row major-ness (is that a word?!) of Matrix4f, or something else? Is the rest of my code just broken? Is it actually correct and I'm just worrying too much? Am I just an idiot?

Thanks.

解决方案

You should transpose nothing .You should negate "eye" vector of the lookAt() matrix and the looking direction."EYE" corresponds to camera position which should be always inverted.All that is done inside the lookAt()

Here is lookAt() method from Java port of the famous GLM math lib.

 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));
}

I use it with my LWJGL based OpenGL 4 renderer and it works like a charm :)

这篇关于OpenGL 3(LWJGL)LookAt Matrix混乱的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆