#version 430

layout(location = 0) in vec3 aPos;
layout(location = 1) in vec3 aNormal;
layout(location = 2) in vec2 aUV;

layout(std430, binding = 3) buffer ModelMatrices {
	mat4 models[];
};

uniform mat4 ModelMatrix;
uniform mat4 ViewMatrix;
uniform mat4 ProjectionMatrix;
uniform mat4 NormalMatrix;// Normal matrix (M^-1)T

smooth out vec3 camspace_position; // position for per fragment lighting
smooth out vec3 camspace_normal;   // normal for per fragment lighting
smooth out vec2 frag_uv_coordinate;// UV coordinate
smooth out vec3 frag_3D_position;

void main(){
	mat4 InstanceModelMatrix = models[gl_InstanceID];
	mat4 ModelMat = ModelMatrix * InstanceModelMatrix;
	gl_Position = ProjectionMatrix * ViewMatrix * ModelMat * vec4(aPos, 1.0f);

	mat4 MV = ModelMat * ViewMatrix;
	mat4 IV = inverse(ViewMatrix);
	vec4 global_position = MV * vec4(aPos, 1.0f);
	global_position = IV * global_position;

	camspace_position = ((ViewMatrix * ModelMat) * vec4(aPos.xyz, 1.0f)).xyz;
	camspace_normal = ((ViewMatrix * NormalMatrix) * vec4(aNormal, 0)).xyz;
	frag_uv_coordinate = aUV;
	frag_3D_position = global_position.xyz;
}