#version 450

layout(push_constant) uniform constants {
    mat4 lightSpaceMatrix;
};

layout(set = 0, binding = 0) uniform Global {
    mat4 view;
    mat4 proj;
};

layout(std430, set = 5, binding = 0) readonly buffer JointBuffer {
    mat4 jointMatrices[];
};

layout(location = 0) in vec3 aVertexPos;
layout(location = 1) in vec3 aVertexNormal;
layout(location = 2) in vec2 aVertexCoord;
layout(location = 3) in uvec4 aVertexJoint;
layout(location = 4) in vec4 aVertexWeight;
layout(location = 5) in mat4 model;
layout(location = 9) in int materialIndex;

layout(location = 0) out vec3 oFragPos;
layout(location = 1) out vec3 oNormal;
layout(location = 2) out vec2 oFragTexCoord;
layout(location = 3) out vec4 oColor;
layout(location = 4) out vec4 oLightFragPos;
layout(location = 5) out flat int oMaterialIndex;


void main() {
    oMaterialIndex = materialIndex;

    //oColor = (aVertexNormal + 1) / 2;
    //oColor = pow(oColor, vec3(2.2)) * color;
    oColor = vec4(0, 1, 0, 1);
    if (aVertexJoint.x > 16) oColor = vec4(1, 0, 0, 1); // Rot bei ungültigem Index

    mat4 skinMat =
		aVertexWeight.x * jointMatrices[aVertexJoint.x] +
		aVertexWeight.y * jointMatrices[aVertexJoint.y] +
		aVertexWeight.z * jointMatrices[aVertexJoint.z] +
		aVertexWeight.w * jointMatrices[aVertexJoint.w];

    mat4 modelView = view * skinMat;
    oFragPos = vec3(modelView * vec4(aVertexPos, 1.0));
    oLightFragPos = lightSpaceMatrix * skinMat * vec4(aVertexPos, 1.0f);

    // compute normal position in view space
    mat3 normalMatrix = transpose(inverse(mat3(modelView)));
    oNormal = normalize(normalMatrix * aVertexNormal);

    oFragTexCoord = aVertexCoord;

    gl_Position = proj * modelView * vec4(aVertexPos, 1);
}
