简短版本:我使用带有透视投影矩阵的glLookAt视图矩阵,我想知道为什么更改camLookAt向量(我和#39的位置) ;我看着)会导致相机位置发生变化。
长版本:我使用here描述的代码来实现我自己实现的众所周知的glLookAt函数:
var z = glm.normalize(camPosition - camLookAt);
var y = up;
var x = glm.normalize(glm.cross(y, z));
y = glm.cross(z, x);
var result = new mat4(1.0f);
result[0, 0] = x.x;
result[1, 0] = x.y;
result[2, 0] = x.z;
result[3, 0] = -Dot(x, camPosition);
result[0, 1] = y.x;
result[1, 1] = y.y;
result[2, 1] = y.z;
result[3, 1] = -Dot(y, camPosition);
result[0, 2] = z.x;
result[1, 2] = z.y;
result[2, 2] = z.z;
result[3, 2] = -Dot(z, camPosition);
result[0, 3] = 0;
result[1, 3] = 0;
result[2, 3] = 0;
result[3, 3] = 1.0f;
return result;
除了一件奇怪的事情外,这似乎工作得很好:当我将凸轮的位置固定,但更改camLookAt
变量时,相机似乎不仅移动了它的角度,而且它的位置。
为了证明这一点,我做了一个明确的计算:
(0, 0, 0)
和(1, 0, 0)
。camPosition = (-3, 0, 0)
从camLookAt = (0, 0, 0)
和up = (0, 0, 1)
查看这些内容。因此,我们在正x轴的方向上查看原点。这是我得到的矩阵:0, -1, 0, 0 0, 0, 1, 0 -1, 0, 0, -3 0, 0, 0, 1
(0, 0, -3)
,第二个点映射到(0, 0, -4)
。camLookAt
更改为(0, 3, 0)
,即将相机向左旋转45度。这是我得到的矩阵:0.71, -0.71, 0.00, 2.12 0.00, 0.00, 1.00, 0.00 -0.71, -0.71, 0.00, -2.12 0.00, 0.00, 0.00, 1.00
(2.1213, 0, -2.1213)
和(2.8284, 0, -2.8284)
。所以两个变换点的(X,Y)分量不匹配。现在,到目前为止,我们只使用了欧几里德变换,所以还没有透视。但是,我使用像这样的透视投影矩阵
const float radians = (60.0f / 360.0f) * (float)Math.PI * 2.0f;
projectionMatrix = glm.perspective(radians, width / height, 0.01f, 1000f);
即使应用了这个投影矩阵,这两个点也不会落在相同的(X,Y)坐标上,即在屏幕上的同一像素上。
我错过了什么?这是glLookAt的预期行为,还是我使用/实现它错了?
编辑:投影矩阵应用于顶点着色器,就像这样:
void main(void) {
gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(in_Position, 1.0);
}
EIDT 2:这是我当前场景的录音,正如澄清一样。唯一随时间变化的是camLookAt
向量。相机应该保持在相同的位置,但不知何故它似乎移动:
编辑3:根据@NicoSchertler的建议,我只是对CPU进行了所有计算。 viewMatrix乘法在上面完成,它分别导致(2.1213, 0, -2.1213)
和(2.8284, 0, -2.8284)
。现在我应用投影矩阵(参见上面我如何获得投影矩阵):
1.30, .00, .00, .00 .00, 1.73, .00, .00 .00, .00, -1.00, -.02 .00, .00, -1.00, 1.00
我得到以下载体
(2.75, 0.00, 2.10, 3.12)
(3.67, 0.00, 2.81, 3.83)
然后我将它们除以它们产生<{p>的w
值
(0.88, 0.00, 0.67, 1.00)
(0.96, 0.00, 0.73, 1.00)
所以他们显然不会相互支持。
投影矩阵中是否有错误?
答案 0 :(得分:3)
然而,情况并非如此,(......)两个变换点的(X,Y)分量不匹配。
具有不同x / y坐标的两个点并不意味着它们不会彼此相继。显然,他们有不同的深度。摄像机位于此坐标系中的原点。如果你计算从相机到点的方向(即normalize(p - 0)
),我们得到:
direction1 = {0.707107, 0, -0.707107}
direction2 = {0.707107, 0, -0.707107}
因此,从相机到两点的方向是相同的,因此它们相互排在后面。
您还没有展示如何进行投影。但这些点必须投射到同一位置。不过,有一点关于透视投影的警告。投影点的w
- 组件不是1
。您需要将该点除以此w
- 组件(透视除法)以查找实际投影点。然后,x / y坐标应该实际匹配。