#version 330

layout( location = 0 ) in vec3 InVertex;
layout( location = 1 ) in vec3 InNormal;
layout( location = 2 ) in vec3 InOffset;

out vec3 vPos;
out vec3 vNormal;
out vec3 vSunPosition;
out vec3 vEye;

uniform mat4 uViewMatrix;
uniform mat4 uProjectionMatrix;
uniform mat4 uModelMatrix;
uniform vec3 uSunPosition;
uniform float uSurfaceLength;
uniform float uPatchLength;
uniform float uTiltAngle;

void main()
{
	vec3 position = InVertex + InOffset;
	float x = mod( gl_InstanceID, uSurfaceLength );
	float z = floor( gl_InstanceID / uSurfaceLength );
	vec3 centerPos = vec3( uSurfaceLength * uPatchLength, 0.0, uSurfaceLength * uPatchLength ) / 4.0;
	position += vec3( uPatchLength * x, 0.0, uPatchLength * z ) - centerPos;
	vPos = vec3( ( uModelMatrix ) * vec4( position, 1.0 ) );
	vEye = vec3( ( uViewMatrix * uModelMatrix ) * vec4( position, 1.0 ) );
	vSunPosition = vec3( ( uViewMatrix ) * vec4( uSunPosition, 1.0 ) );
	vec3 rotAxis = normalize( cross( normalize( -vEye ), InNormal ) );
	vec3 rotNormal = InNormal * cos( uTiltAngle ) + cross( rotAxis, InNormal ) * sin( uTiltAngle ) + rotAxis * dot( rotAxis, InNormal ) * ( 1.0 - cos( uTiltAngle ) );
	vNormal = normalize( transpose( inverse( mat3( uViewMatrix * uModelMatrix ) ) ) * InNormal );
	gl_Position = uProjectionMatrix * uViewMatrix * uModelMatrix * vec4( position, 1.0 );
}