验证顶点着色器中的变换矩阵用法。正确或正常的转变

时间:2018-02-09 22:48:24

标签: opengl matrix glsl normals homogenous-transformation

我需要能够根据变换矩阵修改顶点坐标,但我有每顶点光照,所以我不确定,我的方法对于法线是正确的:

#version 120
uniform mat4 transformationMatrix;
void main() {
    vec3 normal, lightDir;
    vec4 diffuse, ambient, globalAmbient;
    float NdotL;
    // Transformation part
    normal = gl_NormalMatrix * gl_Normal * transpose(mat3(transformationMatrix));
    gl_Position = gl_ModelViewProjectionMatrix * transformationMatrix * gl_Vertex;
    // Calculate color
    lightDir = normalize(vec3(gl_LightSource[0].position));
    NdotL = max(abs(dot(normal, lightDir)), 0.0);
    diffuse = gl_Color * gl_LightSource[0].diffuse;
    ambient = gl_Color * gl_LightSource[0].ambient;
    globalAmbient = gl_LightModel.ambient * gl_Color;
    gl_FrontColor =  NdotL * diffuse + globalAmbient + ambient;
 } 

我在第8-9行执行所有转换。 你能否评论一下是否正确?

2 个答案:

答案 0 :(得分:3)

如果你想创建一个普通矩阵,那么你必须使用4 * 4矩阵左上角3 * 3的inverse transpose

Why transforming normals with the transpose of the inverse of the modelview matrix?
Why is the transposed inverse of the model view matrix used to transform the normal vectors?

这意味着您必须像这样编写代码:

normal = gl_NormalMatrix * transpose(inverse(mat3(transformationMatrix))) * gl_Normal;


但是,如果向量乘以左边的矩阵,则结果对应于将列向量与右侧的转置矩阵相乘。

请参阅GLSL Programming/Vector and Matrix Operations

这意味着您可以编写这样的代码并避免transpose操作:

normal = gl_NormalMatrix * (gl_Normal * inverse(mat3(transformationMatrix)));


如果4 * 4矩阵transformationMatrixOrthogonal matrix,这意味着X,Y和Z轴是Orthonormal(单位向量并且它们彼此正常),那么它是足够使用左上角3 * 3。在这种情况下,逆矩阵等于转置矩阵。

请参阅In which cases is the inverse matrix equal to the transpose?

这将简化您的代码:

normal = gl_NormalMatrix * mat3(transformationMatrix) * gl_Normal;

当然,这也可以这样表达:

normal = gl_NormalMatrix * (gl_Normal * transpose(mat3(transformationMatrix)));

请注意,这与您在代码中的操作不同,因为从左到右处理*操作(请参阅GLSL - The OpenGL Shading Language 4.6, 5.1 Operators, page 97)和

的结果
vec3 v;
mat3 m1, m2;

(m1 * v) * m2

不等于

m1 * (v * m2);

答案 1 :(得分:1)

正常转换看起来不正确。

由于v * transpose(M)与M * v完全相同,因此您根本没有对非均匀缩放进行任何特殊处理。

您正在寻找的最有可能是使用反转置矩阵:

normal = gl_NormalMatrix * transpose(inverse(mat3(transformationMatrix))) * gl_Normal;

有关此背后数学的更多详细信息,请查看this