#version 140

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

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

varying vec4 fColor;
varying vec3 fNormal;
varying vec2 fUV;
varying float fLightingFactor;
varying 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;
}
