1
\$\begingroup\$

So, I got a model matrix (Via uniform variable) in the shader, is there any way to use the model matrix to transform the normal of a vertex that has been transformed with glm::transform/rotate?

If you want, here is the code:

VERTEX SHADER:

#version 330 core

layout(location = 0) in vec3 vertexPosition_modelspace;
layout(location = 1) in vec3 vertexColor;
layout(location = 2) in vec2 vertexUV;
layout(location = 3) in vec3 vertexNormal;

out vec3 Normal;
out vec3 fragmentColor;
out vec3 vertPos;
out vec2 UV;

uniform mat4 MVP;

void main(){
    gl_Position =  MVP * vec4(vertexPosition_modelspace,1.0f);
    UV = vertexUV;
    fragmentColor = vertexColor;
    vertPos = vertexPosition_modelspace;
    Normal = vertexNormal;
}

FRAGMENT SHADER:

#version 330 core

in vec3 Normal;
in vec3 fragmentColor;
in vec3 vertPos;
in vec2 UV;

out vec3 color;

uniform sampler2D textureSampler;
uniform mat4 Model;

void main(){
    vec3 lightPos = vec3(1, 1, 1);
    mat3 normalMatrix = transpose(inverse(mat3(Model))); // I think this line could do it, but it doesn't seem to work.
    vec3 normal = normalize(normalMatrix * Normal);
    vec3 fragPosition = vec3(Model * vec4(vertPos, 1));
    vec3 surfaceToLight = lightPos - fragPosition;

    float brightness = dot(normal, surfaceToLight) / (length(surfaceToLight) * length(normal));
    brightness = clamp(brightness, 0.2, 1);

    color = vec3(brightness * 1 * (texture(textureSampler, UV).rgb * fragmentColor));

}
\$\endgroup\$
  • \$\begingroup\$ You say it doesn't seem to work, how doesn't it work? Also * length(normal) when calculating brightness is pretty redundant since the normal is always normalized meaning its length is 1. \$\endgroup\$ – Christer Dec 5 '15 at 19:53
  • \$\begingroup\$ Ive managed to fix the normals by using the mvp, but now if I translate(not rotate) the quad, the light seems to follow it. Ive given the light its own model matrix, but it has the same issue. \$\endgroup\$ – user68817 Dec 5 '15 at 20:05
2
\$\begingroup\$

Managed to fix it:

VERTEX SHADER:

#version 330 core

layout(location = 0) in vec3 vertexPosition_modelspace;
layout(location = 1) in vec3 vertexColor;
layout(location = 2) in vec2 vertexUV;
layout(location = 3) in vec3 vertexNormal;

out vec3 Normal;
out vec3 fragmentColor;
out vec4 vertPos;
out vec2 UV;
out mat4 mvp;

uniform mat4 MVP;

void main(){
    gl_Position =  MVP * vec4(vertexPosition_modelspace,1.0f);
    UV = vertexUV;
    fragmentColor = vertexColor;
    vertPos = MVP * vec4(vertexPosition_modelspace,1.0f);
    Normal = vertexNormal;
    mvp = MVP;
}

FRAGMENT SHADER:

#version 330 core

in vec3 Normal;
in vec3 fragmentColor;
in vec4 vertPos;
in vec2 UV;
in mat4 mvp;

out vec3 color;

uniform sampler2D textureSampler;
uniform mat4 Model;
uniform mat4 lmvp;

void main(){
    vec4 lightPos = lmvp * vec4(-0.5, 0.5, -0.5, 1);
    mat3 normalMatrix = transpose(inverse(mat3(Model)));
    vec3 normal = normalize(normalMatrix * Normal);
    vec3 fragPosition = vec3(Model * vec4(vertPos.xyz, 1));
    vec3 surfaceToLight = lightPos.xyz - fragPosition;

    float brightness = dot(normal, surfaceToLight) / (length(surfaceToLight) * length(normal));
    brightness = clamp(brightness, 0.2, 1);

    color = vec3(brightness * 1 * (texture(textureSampler, UV).rgb * fragmentColor));
}
| improve this answer | |
\$\endgroup\$
  • 3
    \$\begingroup\$ Well it seems you have solved your own problem. Honestly I don't think the normals ever really was your problem. Also try giving some time to figuring it out yourself before asking questions. Problem solving skills is one of the most important skills to learn. \$\endgroup\$ – Christer Dec 5 '15 at 20:22
  • 1
    \$\begingroup\$ And a tips transpose(inverse(mat3(Model))); is maybe redundant and a bit expensive. The inverse and the transpose cancel out if the model matrix consist only of translation, rotation and uniform scaling, leaving only mat3(Model). Second, inverse can be a costly operation and you are doing it for every pixel. I recommend moving it to the vertex shader and passing the normal to the fragment shader after transformation with the model matrix. \$\endgroup\$ – Christer Dec 5 '15 at 20:27
  • \$\begingroup\$ Thanks for the tip, but I probably don't have to worry about that right now. (Since I'm at 3000 fps :D) \$\endgroup\$ – user68817 Dec 5 '15 at 20:53
  • \$\begingroup\$ I agree, you should rather worry about these small optimizations later. Especially if it gets in the way of your programming. Also even though 3000 fps sounds pretty cool, don't become this guy. gamedev.stackexchange.com/q/112166/75055 , use milliseconds ;) \$\endgroup\$ – Christer Dec 5 '15 at 21:24
  • \$\begingroup\$ This code dump "answer" doesn't say what the problem was without very careful source reading and trying to guess what it is. Please try to condense the things you believe were the problem into text instead, so it reads like a real answer. \$\endgroup\$ – Lars Viklund Mar 5 '16 at 10:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy