• 9
• 9
• 11
• 12
• 9

# GLSL Mat3 troubles

This topic is 432 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Having recently gotten tangent vectors working, I wanted to try out normal mapping. I'm constructing a TBN matrix in my vertex shader like so (including the whole thing for clarity):

// basic.vert
#version 430 core

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

in vec3 v_position;
in vec3 v_normal;
in vec3 v_tangent;
in vec2 v_texcoord;

out VS_OUT {
vec3 position;
vec2 texcoord;
vec3 tangent;
vec3 bitangent;
vec3 normal;
mat3 TBN;
} vs_out;

void main()
{
gl_Position = projection * view * model * vec4(v_position, 1);
vs_out.position = (model * vec4(v_position, 1)).xyz;

// Compute TBN matrix
// Not using bitangent sign, I was *going* to add that next
vec3 v_bitangent = cross(v_normal, v_tangent);
vec3 T = normalize(vec3(model * vec4(v_tangent,   0.0)));
vec3 B = normalize(vec3(model * vec4(v_bitangent,  0.0)));
vec3 N = normalize(vec3(model * vec4(v_normal,    0.0)));
vs_out.tangent = T;
vs_out.bitangent = B;
vs_out.normal = N;
vs_out.TBN = mat3(T, B, N);
}



You may have noticed that some of my shader outputs are redundent with the TBN matrix, I'll get to that.

So just to test this out, I wrote my fragment shader like so:

// basic.frag
#version 430 core

uniform sampler2D diffuse;

in VS_OUT {
vec3 position;
vec2 texcoord;
vec3 tangent;
vec3 bitangent;
vec3 normal;
mat3 TBN;
} fs_in;

layout (location = 0) out vec3 out_position;
layout (location = 1) out vec3 out_normal;
layout (location = 2) out vec4 out_diffuse;
layout (location = 3) out float out_specular;

void main()
{
out_position = fs_in.position;
out_normal = fs_in.TBN[2];
out_diffuse = texture(diffuse, fs_in.texcoord);
out_specular = 0.3;
}



Finally, the viewport shader just outputs the normal buffer instead of doing any shading. However, I just get a black screen, with no errors.

So I changed the out_normal assignment line in my fragment shader to:

out_normal = fs_in.normal;


And it works. After a lot of head scratching, I ended up with this.

// basic.vert
//...
out VS_OUT {
//...
mat4 TBN;
} vs_out;

//...
vs_out = mat4(vec4(T, 0), vec4(B, 0), vec4(N, 0), vec4(0, 0, 0, 1));


// basic.frag
//...
in VS_OUT {
//...
mat4 TBN;
} fs_in;

//...
out_normal = TBN[2].xyz;


And it works. That obviously isn't really what I'd want, but I have no idea what to believe anymore. Is this a driver bug, or am I doing something stupid (it wouldn't be the first time)?

Using (when TBN is a mat3):

out_normal = fs_in.TBN[0];


Outputs the bitangent vector, and:

out_normal = fs_in.TBN[1];


Outputs the normal vector.

fs_in.tangent/bitangent/normal always returns the expected result, so I may end up just constructing the TBN matrix in the fragment shader.

Edited by Easy Rider

##### Share on other sites

Don't have a direct answer but a side note: you need to normalize your t,b,n vectors in the fragement shader, or they will give you incorrect lighting results.

##### Share on other sites

Thanks for the heads up. Is that due to OpenGL doing interpolation between vertices to get the values for the fragment shader?

Anyway, ultimately I've come to the conclusion that this is a driver bug. I'm developing on a Surface Book with that wacky hybrid GPU thing, and when I run my game with the integrated GPU it works, but when I run it with the dedicated Nvidia GPU it does not. I"ll just stick to constructing the TBN matrix in the fragment shader.

Edited by Easy Rider