如何计算正常矩阵? [英] How to calculate the normal matrix?

查看:146
本文介绍了如何计算正常矩阵?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



vs.glsl

  #version 440 

在vec3 vPosition;
in vec3 vNormal;

out vec4 eyeCordFs;
out vec4 eyeNormalFs;

统一的mat4模型;
统一的mat4视图;
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);
}

fs.glsl

  #version 440 

在vec4 eyeCordFs;
在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;
}

这个输出看起来像



这对我来说似乎有点奇怪。但我知道我没有扩展任何东西,所以我想我可以使用modelView矩阵来转换我的法线。

所以我改变了行

  vec4 eyeNorm = normalize(normalMatrix * vec4(vNormal,0.0)); 

  vec4 eyeNorm = normalize(modelView * vec4(vNormal,0.0)); 

现在输出看起来像这样




>

我正在计算我的 normalMatrix 的方法错误吗? 正常矩阵是模型视图矩阵的转置逆。因此,在GLSL中,它将是

  mat4 normalMatrix = transpose(inverse(modelView)); 

但是,您应该 NOT 计算着色器中的常规矩阵。在着色器中这样做浪费了很多宝贵的GPU周期。矩阵求逆并不是一个便宜的操作,并且在着色器中执行它会迫使GPU一次又一次地为每个顶点执行计算。在CPU上预先计算并作为制服传递。

I have some trouble with my normal matrix.

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);
}

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; 
}

The output of this looks like

Which seemed a bit strange to me. But I knew that I am not scaling anything so I thought I could use the modelView matrix to transform my normals.

So I changed the line

vec4 eyeNorm = normalize(normalMatrix * vec4(vNormal, 0.0));

to

vec4 eyeNorm = normalize(modelView * vec4(vNormal, 0.0));

And the output now looks like this

which looks correct. Am I calculating my normalMatrix the wrong way?

解决方案

The normal matrix is the transpose inverse of the modelview matrix. So in GLSL it would be

mat4 normalMatrix = transpose(inverse(modelView));

However you should NOT calculate the normal matrix in the shader. Doing that in the shader wastes a lot of precious GPU cycles. Matrix inversion is not a cheap operation to start with and doing it in the shader forces the GPU to perform the calculation for each and every vertex again and again. Precalculate it on the CPU and pass it as a uniform.

这篇关于如何计算正常矩阵?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆