#version 330 core layout (location = 0) in vec3 aPosition; layout (location = 1) in vec3 aNormal; layout (location = 2) in vec2 aTextureCoord; layout (location = 3) in vec3 aTangent; layout (location = 4) in vec3 aBitangent; struct Light { vec3 position; // Light colors RGB value vec3 ambient; vec3 diffuse; vec3 specular; }; uniform Light uLight; out VS_OUT { vec2 textureCoord; vec3 position; vec3 normal; vec3 tangentLight; vec3 tangentView; vec3 tangentFrag; Light light; } vOut; // Model View Projection matrix found by P * V * M struct MVP { mat4 model; mat4 view; mat4 projection; // Additional uniform to allow CPU to provide mat3(transpose(inverse(uModel))) // + Makes a big difference in quality of diffuse shading // + QMatrix4x4.normalMatrix() returns a mat3 that can be used as a uniform mat3 normalMatrix; }; uniform MVP uMVP; vec4 VertexPosition(in MVP mvp, in vec3 position) { return mvp.projection * mvp.view * mvp.model * vec4(position, 1.0f); } // Light object and camera position vectors uniform vec3 uCameraPosition; void main() { // Finx TBN 3x3 matrix values for normals vec3 T = normalize(vec3(uMVP.model * vec4(aTangent, 0.0))); vec3 B = normalize(vec3(uMVP.model * vec4(aBitangent, 0.0))); vec3 N = normalize(vec3(uMVP.model * vec4(aNormal, 0.0))); mat3 TBN = transpose(mat3(T, B, N)); // Set tangent postiions for fragment shader vOut.tangentLight = TBN * uLight.position; vOut.tangentView = TBN * uCameraPosition; vOut.tangentFrag = TBN * vec3(uMVP.model * vec4(aPosition, 1.0f)); // Set normal, position, and texture coordinate for frag shader vOut.textureCoord = aTextureCoord; vOut.normal = uMVP.normalMatrix * aNormal; vOut.position = vec3(uMVP.model * vec4(aPosition, 1.0f)); vOut.light = uLight; gl_Position = VertexPosition(uMVP, aPosition); }