GLSL法线向量变换
Posted
技术标签:
【中文标题】GLSL法线向量变换【英文标题】:GLSL normal vector transformation 【发布时间】:2018-11-07 15:21:59 【问题描述】:在这个 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?
...
【问题讨论】:
反正这是错误的。对于Orthogonal matrix 和N = normalize(transpose(inverse(mat3(norm_matrix))) * vertNormal);
,它必须是N = normalize(mat3(norm_matrix) * vertNormal);
。
【参考方案1】:
模型视图矩阵如下所示:
( 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的mat3
和inverse
、transposed
。见
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);
如果模型视图矩阵是Orthogonal matrix,则可以跳过inverse
、transpose
,因为逆矩阵等于转置矩阵。
见In which cases is the inverse matrix equal to the transpose?
vec3 N = normalize(mat3(mv_matrix)* vertNormal);
如果要在视图空间中进行计算,则必须将顶点坐标从模型空间转换到视图空间:
vec4 P = mv_matrix * vec4(vertPos,1.0);
你必须将法线向量形式模型空间的方向转换到视图空间:
vec3 N = normalize(norm_matrix * vertNormal);
【讨论】:
以上是关于GLSL法线向量变换的主要内容,如果未能解决你的问题,请参考以下文章