Mai*_*ein 17 opengl 3d graphics glsl
我的普通矩阵有些麻烦.
vs.glsl
#version 440
in vec3 vPosition;
in vec3 vNormal;
out vec4 eyeCordFs;
out vec4 eyeNormalFs;
uniform mat4 model;
uniform mat4 view;
uniform mat4 proj;
void main()
{
mat4 modelView = view * model;
mat4 normalMatrix = view * transpose(inverse(model));
vec4 eyeNorm = normalize(normalMatrix * vec4(vNormal, 0.0));
vec4 eyeCord= modelView * vec4(vPosition, 1.0);
eyeCordFs = eyeCord;
eyeNormalFs = eyeNorm;
gl_Position = proj * modelView * vec4( vPosition,1.0);
}
Run Code Online (Sandbox Code Playgroud)
fs.glsl
#version 440
in vec4 eyeCordFs;
in vec4 eyeNormalFs;
out vec3 outputColor;
uniform vec4 lightPos;
void main()
{
vec4 s = normalize(lightPos - eyeCordFs) ;
vec4 r = reflect(-s,eyeNormalFs);
vec4 v = normalize(-eyeCordFs);
float spec = max( dot(v,r),0.0 );
float diff = max(dot(eyeNormalFs,s),0.0);
vec3 diffColor = diff * vec3(1,0,0);
vec3 specColor = pow(spec,3) * vec3(1,1,1);
vec3 ambientColor = vec3(0.1,0.1,0.1);
outputColor = diffColor + 0.5 * specColor + ambientColor;
}
Run Code Online (Sandbox Code Playgroud)
这个的输出看起来像

这对我来说似乎有点奇怪.但我知道我没有缩放任何东西所以我认为我可以使用modelView矩阵来转换我的法线.
所以我换了线
vec4 eyeNorm = normalize(normalMatrix * vec4(vNormal, 0.0));
Run Code Online (Sandbox Code Playgroud)
至
vec4 eyeNorm = normalize(modelView * vec4(vNormal, 0.0));
Run Code Online (Sandbox Code Playgroud)
输出现在看起来像这样

看起来很正确.我在计算normalMatrix错误的方法吗?
dat*_*olf 46
法线矩阵是模型视图矩阵的转置逆.所以在GLSL中它会是
mat4 normalMatrix = transpose(inverse(modelView));
Run Code Online (Sandbox Code Playgroud)
然而,你应该不计算着色器中正常的矩阵.在着色器中执行此操作会浪费大量宝贵的GPU周期.矩阵求逆不是一个开始的廉价操作,并且在着色器中执行它会迫使GPU一次又一次地执行每个顶点的计算.在CPU上预先计算并将其作为制服传递.