#version 330

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

out vec3 vPos;
out vec3 vNormal;
out vec3 vEye;
out vec2 vTexCoord;

uniform mat4 uViewMatrix;
uniform mat4 uProjectionMatrix;
uniform mat4 uModelMatrix;

uniform sampler2D uNoiseSampler;

float CalcHeight( vec2 inPosition )
{
	vec4 noiseValue = texture( uNoiseSampler, inPosition );
	float heightVal = 0.0;
	
	float midBias = distance( inPosition, vec2( 0.5 ) ) / 2.0;
	
	float heightMod = 0.0;
	heightMod += noiseValue.x * 0.5;
	heightMod += noiseValue.y * 0.25;
	heightMod += noiseValue.z * 0.125;
	heightMod += noiseValue.z * 0.0625;
	
	heightVal += heightMod * 750.0;
	heightVal += midBias * 1000.0;
	
	return heightVal;
}

void main()
{
	float x = mod( float(gl_VertexID), 1024.0 );
	float z = floor( float(gl_VertexID) / 1024.0 );
	vec2 texCoord = vec2( x, z ) / 1024.0;
	vTexCoord = texCoord;
	
	vec3 position = InVertex;
	float height = CalcHeight( texCoord );
	
	float invTexelSize = 1.0 / 1024.0;
	float heightR = CalcHeight( texCoord + vec2( invTexelSize, 0.0 ) );
	float heightL = CalcHeight( texCoord + vec2( -invTexelSize, 0.0 ) );
	float heightT = CalcHeight( texCoord + vec2( 0.0, invTexelSize ) );
	float heightB = CalcHeight( texCoord + vec2( 0.0, -invTexelSize ) );
	
	position.y += height;
	
	float dx = heightR - heightL;
	float dz = heightT - heightB;
	vec3 normalVal = vec3( -dx, 2.0, -dz );
	
	vPos = vec3( ( uModelMatrix ) * vec4( position, 1.0 ) );
	vEye = vec3( ( uViewMatrix * uModelMatrix ) * vec4( position, 1.0 ) );
	vNormal = normalize( transpose( inverse( mat3( uModelMatrix ) ) ) * normalVal );
	gl_Position = uProjectionMatrix * uViewMatrix * uModelMatrix * vec4( position, 1.0 );
}