GLSL法向量变换



在这个glsl着色器示例中,一些顶点法线通过变换转换为视图空间:vec4(vertNormal,1.0)).xyz为什么我们需要做这种转变?

#version 430
layout (location=0) in vec3 vertPos;
layout (location=1) in vec3 vertNormal;
void main(void)
{ 
...

// convert vertex position to view space
vec4 P = mv_matrix * vec4(vertPos,1.0); // looks good
// convert normal to view space
vec3 N = normalize((norm_matrix * vec4(vertNormal,1.0)).xyz); // why to vec4 and back to vec3?
...
}

模型视图矩阵如下所示:

( X-axis.x, X-axis.y, X-axis.z, 0 )
( Y-axis.x, Y-axis.y, Y-axis.z, 0 )
( Z-axis.x, Z-axis.y, Z-axis.z, 0 )
( trans.x,  trans.y,  trans.z,  1 )

上部的let 3*3包含方向和比例。第4行包含翻译
对于点的变换,必须考虑全矩阵,而对于方向向量的变换,只有方向感兴趣。

通常,正规矩阵是模型视图矩阵的左上3*3的mat3inversetransposed。参见

  • 为什么模型视图矩阵的转置逆用于变换法向量
  • 为什么要用模型视图矩阵的逆矩阵的转置来变换法线

mat3 norm_matrix;

vec3 = normalize(norm_matrix * vertNormal);

法线矩阵可以从模型视图矩阵计算:

mat4 mv_matrix;

mat3 norm_matrix = transpose(inverse(mat3(mv_matrix));
vec3 N = normalize(norm_matrix * vertNormal);

如果模型视图矩阵是正交矩阵,则可以跳过inversetranspose,因为逆矩阵等于转置矩阵
请参见在哪些情况下,逆矩阵等于转置?

vec3 N = normalize(mat3(mv_matrix)* vertNormal);

如果你想在视图空间中进行计算,那么你必须将顶点坐标从模型空间转换到视图空间:

vec4 P = mv_matrix * vec4(vertPos,1.0);

你必须将法向量的方向从模型空间转换为视图空间:

vec3 N = normalize(norm_matrix * vertNormal);

最新更新