Jak obliczyć macierz normalną?

Mam problemy z moją normalną matrycą.

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

Wyjście tego wygląda następująco Tutaj wpisz opis obrazka

Co wydawało mi się trochę dziwne. Ale wiedziałem, że nie skaluję niczego, więc pomyślałem, że mogę użyć matrycy modelView do przekształcenia moich normalnych.

Więc zmieniłem linię

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

Do

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

I wyjście wygląda teraz tak

Tutaj wpisz opis obrazka

Który wygląda poprawnie. Czy obliczam moje normalMatrix zła droga?

Author: code_dredd, 2014-01-13

1 answers

Macierz normalna jest odwrotnością transpozycyjną macierzy modelview. Więc w GLSL byłoby to

mat4 normalMatrix = transpose(inverse(modelView));

Należy jednak nie obliczyć normalną macierz w cieniu. Robienie tego w shaderze marnuje wiele cennych cykli GPU. Inwersja matrycy nie jest tanią operacją, a wykonanie jej w shaderze zmusza GPU do wykonywania obliczeń dla każdego wierzchołka raz za razem. Wstępnie Oblicz go na procesorze i przekaż jako jednolity.

 42
Author: datenwolf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-12 20:13:03