//Low Detail Vertex Shader
#version 150

// vsPosition was bound to attribute index 0 and vsColor was bound to attribute index 1
in vec3 vsPosition;
in vec3 vsNormal;
in vec4 vsColor;
in vec2 vsTextureUV;

// Our outputs the next shader (fragment) in the chain
out vec4 fsColor;
out vec2 fsTextureUV;

out vec3 fsDirectionVS;
out vec3 fsPositionEye;
out vec3 fsNormalVS;
out vec3 fsNormalWS;
out vec3 fsSunDirectionVS;
out mat4 fsInvView;

uniform mat4 uObjectToProjection;
uniform mat4 uObjectToView;
uniform mat4 uObjectToWorld;
uniform mat4 uWorldToView;
uniform mat4 uViewToProjection;
uniform mat4 uSunCameraView;

//Expected to be a unit vector and in world space already. Pointing FROM origin TO the sun.
uniform vec4 uSunLightDirection = vec4(-0.447766751, 0.373415232, 0.812444329, 0.422158539);

uniform int uInstancedRendering;
layout (std140) uniform ubInstancedObjectTransforms //NOT A STRUCT
{
	mat4 instancedTransforms[256];
};

void main(void)
{
	mat4 objectToWorld = uObjectToWorld;
	mat4 objectToView = uObjectToView;
	mat4 objectToProjection = uObjectToProjection;
	if (1 == uInstancedRendering)
	{
		objectToWorld = instancedTransforms[gl_InstanceID];
		objectToView = objectToWorld * uWorldToView;
		objectToProjection = objectToView * uViewToProjection;
	}

	mat4 uWorldToSunView = uSunCameraView;

	gl_Position = vec4(vsPosition, 1.0) * objectToProjection;

	fsNormalWS = normalize(vsNormal.xyz * inverse(transpose(mat3(objectToWorld))));
	fsColor = vsColor;
	fsTextureUV = vsTextureUV;

	mat4 modelSunView = objectToWorld * uWorldToSunView;

	fsPositionEye = (vec4(vsPosition, 1.0) * objectToView).xyz;

	fsNormalVS = fsNormalWS * mat3(uWorldToView);
	fsSunDirectionVS = (vec4(vec3(uSunLightDirection), 0.0) * uWorldToView).xyz;

	fsInvView = inverse(uWorldToView);

	// vec3 mirror_dir = reflect(-view_dir, normal);
	// mirror_dir = vec3(inverse(uWorldToView) * vec4(mirror_dir, 0.0));

	// mat3 normalMatrix = objectToWorld; /* this will break for non-uniform scaling */
	// vec3 normalW = normalize(vsNormal * normalMatrix);
	// vec3 tangentW = normalize(vec3(objectToWorld * vec4(a_tangent.xyz, 0.0)));
	// vec3 bitangentW = cross(normalW, tangentW) * a_tangent.w;
	// fsTbnMatrix = mat3(tangentW, bitangentW, normalW);

	vec4 wpos = vec4(vsPosition, 1.0) * objectToWorld;
	vec4 vpos = wpos * uWorldToView;
	fsDirectionVS = -vpos.xyz;
}
