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\$
2
  • \$\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, 2015 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, 2015 at 20:05

1 Answer 1

1
\$\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));
}
\$\endgroup\$
6
  • 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, 2015 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, 2015 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, 2015 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, 2015 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\$ Mar 5, 2016 at 10:10

You must log in to answer this question.