1

在 JungHyun Han 的《用于游戏编程的3D 图形》一书中,第 38-39 页给出了

从 e_1, e_2, e_3 到 u,v,n 的基本变换矩阵是 在此处输入图像描述

然而,这与我从线性代数中所知道的相矛盾。我的意思是基变换矩阵不应该是该矩阵的转置吗?

请注意,作者做了他的推导,但我找不到我所知道的和作者所做的之间的缺失点在哪里。

代码:顶点着色器:

#version 330
layout(location = 0) in vec4 position;
layout(location = 1) in vec4 color;

uniform vec3 cameraPosition;
uniform vec3 AT;
uniform vec3 UP;
uniform mat4 worldTrans;

vec3 ep_1 = ( cameraPosition - AT )/ length(cameraPosition - AT);
vec3 ep_2 = ( cross(UP, ep_1) )/length( cross(UP, ep_1 )); 
vec3 ep_3 = cross(ep_1, ep_2);

vec4 t_ep_1 = vec4(ep_1, -1.0f);
vec4 t_ep_2 = vec4(ep_2, cameraPosition.y);
vec4 t_ep_3 = vec4(ep_3, cameraPosition.z);
mat4 viewTransform = mat4(t_ep_1, t_ep_2, t_ep_3, vec4(0.0f, 0.0f, 0.0f, 1.0f));

smooth out vec4 fragColor;
void main()
{
    gl_Position = transpose(viewTransform) * position;
    fragColor = color;
}
)glsl";

输入:

GLuint transMat = glGetUniformLocation(m_Program.m_shaderProgram, "worldTrans");
    GLfloat dArray[16] = {0.0};
    dArray[0] = 1;
    dArray[3] = 0.5;
    dArray[5] = 1;
    dArray[7] = 0.5;
    dArray[10] = 1;
    dArray[11] = 0;
    dArray[15] = 1;
    glUniformMatrix4fv(transMat, 1, GL_TRUE, &dArray[0]);
    GLuint cameraPosId = glGetUniformLocation(m_Program.m_shaderProgram, "cameraPosition");
    GLuint ATId = glGetUniformLocation(m_Program.m_shaderProgram, "AT");
    GLuint UPId = glGetUniformLocation(m_Program.m_shaderProgram, "UP");
    const float cameraPosition[4] = {2.0f, 0.0f, 0.0f};
    const float AT[4] = {1.0f, 0.0f, 0.0f};
    const float UP[4] = {0.0f, 0.0f, 1.0f};
    glUniform3fv(cameraPosId, 1, cameraPosition);
    glUniform3fv(ATId, 1, AT);
    glUniform3fv(UPId, 1, UP);
4

2 回答 2

1

虽然旋转、缩放或变形确实可以用 4x4 矩阵表示,形式为 在此处输入图像描述

您正在阅读的是所谓的“视图转换”

为了实现这个矩阵,我们需要两个变换:首先,平移到相机位置,然后旋转相机。

进行这些转换的数据是:

  • 相机位置C(Cx,Cy,Cz)
  • 目标位置T(Tx,Ty,Tz)
  • 相机向上归一化UP(Ux、Uy、Uz)

翻译可以表示为

在此处输入图像描述

对于我们定义的旋转:
F = T – C并且在对其进行归一化之后,我们得到f = F / ||T-C||,也表示为 f= normalize(F)
s = normalize(cross (f, UP))
u = normalize(cross(s, f))

s, u, -f是在旧坐标系中表示的新轴。

因此我们可以为这个变换构建旋转矩阵 在此处输入图像描述

将这两个变换组合在一个唯一的矩阵中,我们得到: 在此处输入图像描述 在此处输入图像描述

请注意,轴系是 OpenGL 使用的轴系,其中-f= cross(s,u).

现在,与您的 GLSL 代码相比,我看到:

  1. 您的f(ep_1) 向量朝相反的方向前进。
  2. ( sep_2) 向量计算为cross(UP, f)而不是cross(f, UP)。这是正确的,因为 1)。
  3. u(ep_3)相同。
  4. V单元格 (0,0)的构建是错误的。它试图通过使用它来设置正确的方向-1.0f
  5. 对于其他单元格(t_ep_J 组件),使用相机位置。但是您忘记将它的点积s,u,f.
  6. GLSL 初始化器mat4(c1,c2,c3,c4)需要列向量作为参数。你通过了行列。但是,之后,在main使用中transpose纠正它。

在旁注中,您不会为每个顶点计算矩阵,时间和时间和时间......对吗?更好地在 CPU 端计算它并将 if(按列顺序)作为统一传递。

于 2018-01-19T20:56:56.033 回答
0

显然,向量空间中基的变化确实会改变该向量空间中的向量,这不是我们想要的。

因此,我申请的数学在这里无效。

要了解更多关于我们为什么使用我在问题中给出的矩阵的信息,请参阅这个问题。

于 2018-01-22T10:23:36.863 回答