#version 150

in vec3 inPos;
in vec3 inNormal;
in vec2 inUV;
in vec4 inColor;

in vec4 inInstanceColor;
in vec4 inTransform0;
in vec4 inTransform1;
in vec4 inTransform2;
in vec3 inUVTransform0;
in vec3 inUVTransform1;
in float inLightingFactor;
in float inTextureFactor;

out vec4 fColor;
out vec3 fNormal;
out vec2 fUV;
out float fLightingFactor;
out float fTextureFactor;

uniform mat4 uView;
uniform mat4 uProj;

vec4 colorToLinear(vec4 source) {
    bvec3 cutoff = lessThan(source.rgb, vec3(0.04045));
    vec3  higher = pow((source.rgb + vec3(0.055)) / vec3(1.055), vec3(2.4));
    vec3  lower  = source.rgb / vec3(12.92);

    return vec4(mix(higher, lower, cutoff), source.a);
}

void main() {
    mat4 transform = transpose(mat4(inTransform0, inTransform1, inTransform2, vec4(0, 0, 0, 1)));
    fNormal = mat3(transpose(inverse(transform))) * inNormal;
    gl_Position = uProj * uView * transform * vec4(inPos, 1);

    mat3 uvTransform = transpose(mat3(inUVTransform0, inUVTransform1, vec3(0, 0, 1)));
    fUV = (uvTransform * vec3(inUV, 1)).xy;

    fColor = inInstanceColor * colorToLinear(inColor);
    fLightingFactor = inLightingFactor;
    fTextureFactor = inTextureFactor;
}
