3

When we want to compute light in Vertex Shader we need normal vector in view space. In general it looks as below (from OpenGL Superbible 5th):

// normalMatrix is retrieved from GLMatrixStack modelViewMatrix
vec3 vEyeNormal = normalMatrix * vNormal

I want to write program without using GLT Library. In another source (http://en.wikibooks.org/wiki/GLSL_Programming/GLUT/Diffuse_Reflection) I found following formula:

vec3 normalDirection = normalize(m_3x3_inv_transp * v_normal);

Variable m_3x3_inv_transp is computed as follows:

glm::mat3 m_3x3_inv_transp = glm::transpose(glm::inverse(glm::mat3(mesh.object2world)));

I'm conscious that:

My question is why after inversing and transponsing matrix I get NormalMatrix and how to check it with reversing computations?

4

2 回答 2

6

你的假设并不完全正确。

OpenGL 操作的顺序是缩放、平移、旋转。

不,通常你可以有一个任意的世界矩阵。这可以包括任意数量的操作。

逆矩阵是撤消最后一次变换。

不,如果你反转一个矩阵,它的整个效果就会被反转。例如,如果您有一个绕 x 轴旋转 45° 并平移 (1,2,3) 的矩阵,其逆矩阵将导致平移 (-1,-2,-3),然后旋转绕 x 轴 -45°。

法线矩阵只是模型视图矩阵的旋转分量。

不。如果是这种情况,那么您可以丢弃矩阵的平移(和任何透视)部分。但事实并非如此。

法线矩阵用于变换法线,使它们仍然与相应的表面正交。对于刚体变换(即旋转和平移),您可以直接使用世界变换。原因之一是您可以通过转置来反转旋转矩阵(因为它是正交的)。然后你有transpose(transpose(world))哪个是原始矩阵。

对于一般矩阵,您必须按照您的说明计算矩阵。想象一下 (1, 2) 的缩放比例。如果你变换一个圆,它就会变成一个椭圆。让我们看一下 45° 的法线。该位置的圆的法线为 (1, 1)(未归一化)。如果我们用缩放矩阵变换这个法线,我们得到 (1, 2)。如果您想象变换后的椭圆,您会发现法线不再与曲面正交。因此,您必须使用不同的变换(在本例中为 (1, 0.5) 的缩放),以保持正交性。

于 2013-07-01T10:28:05.073 回答
4

基于 3D 游戏编程和计算机图形学的数学第 66 页的答案(由 Eric Lengyel 撰写):

曲面上特定点的切线T和法线必须垂直,因此:N

N . T = 0

假设我们使用矩阵变换表面M。变换曲面上点的切线为:

T' = MT

我们想找到一个矩阵G,它N' = GN是变换曲面上点的法线。由于变换曲面上点的法线和切线仍然必须垂直,因此我们有:

0 = N' . T' = (GN) . (MT) = trans(GN) * MT = trans(N) * trans(G) * MT

现在:

trans(N) * T = N . T = 0

因此,如果满足上述条件:

trans(G) * M = I

何处:

G = trans(inv(M))

换句话说,转换法线所需的矩阵是用于转换切线的矩阵的逆矩阵的转置。

于 2013-07-01T10:27:18.067 回答