#include "inc/uniforms.glsl"
#include "inc/utils.glsl"
#line 3 1


uniform sampler2D lightmap;

#ifdef VERTEX
#line 1 4
#include "inc/geometry_io.vs"
uniform float p_jump;
#line 10 12
#define pi (3.141592653589)
out vec3 ex_ModelPosition;
out vec3 ex_WorldLight;
void process() 
{
	vec4 p = in_Position;
	float alpha = pow(sin(p_beat*pi*0.5-pi*0.5), 2.0)*0.3;
	mat2x2 rot=mat2(cos(alpha), sin(alpha), -sin(alpha), cos(alpha));
	float len2 = sqrt(length(p.xz));
	//p.xz = rot*p.xz;
	//p.xz *= 1.0 - fract(p_beat)*0.2;
	//ex_UV = in_UV*3.0 + vec2(0.0, p_beat*0.05);
	// http://i.imgur.com/g7WFTMq.png
	//         saw              +            sinebump
	// max(0.0, (0.5-frac(x)) ) + max(0.0, -sin(x*2.0*PI))*0.2
	float frak = fract(p_beat);
	float jump =  max(0.0, (0.5-frak) ) + max(0.0, -sin(len2*1.0+p_beat*2.0*pi))*0.2;
	p.y *= 1.0 + jump*0.1*p_jump;
	p.y += jump*25.0*p_jump;
	
	ex_WorldLight = texture(lightmap, in_Position.xz*0.01 + vec2(0.5), 0.0).rgb;
	
	ex_Color = in_Color;
	ex_Position = (modelView)*p;
	ex_ModelPosition = in_Position.xyz;
	gl_Position = (modelViewProject)*p;
}

#define PROCESSING_FUNCTION process
#line 1 5
#include "inc/geometry.vs"

#endif

 
#ifdef FRAGMENT
#line 1 6
#include "inc/geometry_io.fs"
#line 1 44
#line 2
#define pi (3.141592653589)
uniform vec4 diffuseColor;
uniform vec4 specularColor;
uniform float colorBoost;
uniform float roughness;
uniform float metallic;

uniform vec4 envColor;
uniform float envUVMult;

in vec3 ex_ModelPosition;
in vec3 ex_WorldLight;

void main()
{
	vec3 V = normalize(-ex_Position.xyz);
	vec3 N = ex_Normal.xyz; // viewspace normal
	vec3 R = reflect(-V, normalize(N));
	
	vec4 sampld = texture(tex, ex_UV.xy);
	vec3 albedo = sampld.rgb * diffuseColor.rgb * ex_Color.rgb;
	
	vec3 spec = mix(specularColor.rgb, diffuseColor.rgb, metallic);
	vec3 col = vec3(0.0);
	
	vec3 final = vec3(0.0);
	#include "inc/lights.inc"
	
	float groundrough = clamp((-ex_ModelPosition.y + 10.0)*0.2, 0.0, 1.0);
	float ground = mix(1.0, ex_WorldLight.r, groundrough);
	
	for (int i = 0;i < 2 ; i++) {
		vec3 lightdir = lightDirs[i];
		lightdir = (viewMatrix*vec4(lightdir, 0.0)).xyz;
		vec3 L = -lightdir; // vector to light
		
		// these two are defined outside
		//vec3 V = normalize(-ex_Position.xyz);
		//vec3 N = ex_Normal.xyz; // viewspace normal
		
		float NdotL = max(0.0, dot(L, N));
		vec3 H = normalize(V + L);
		float HdotN = max(0.0, dot(H, N));
		float NdotV = max(0.0, dot(N, V));
		float HdotV = max(0.0, dot(H, V));
		
		vec3 diffuse = vec3(1.0/pi);// * mix(vec3(1.0), ex_WorldLight, groundrough);
		diffuse *= albedo * NdotL;
		diffuse *= ground;
		
		// Unreal Engine 4 shading
		float rough = roughness * clamp(1.0-pow(ex_Color.r, 2.2)*1.5, 0.0, 1.0);
		rough = min(1.0, roughness);
		float alpha = rough*rough;
		vec3 F0 = spec;

		// GGX/Trowbridge-Reitz
		float D = (alpha*alpha) / (pi * pow(HdotN*HdotN * (alpha*alpha - 1.0) + 1.0, 2.0));
		float k = pow(rough + 1.0, 2.0) / 8.0;
		float GL = NdotL / (NdotL*(1.0 - k) + k);
		float GV = NdotV / (NdotV*(1.0 - k) + k);
		float G = GL * GV;
		//spherical approximation and shit THANKS DICE
		vec3 F = F0 + (vec3(1.0) - F0) * pow(2.0, (-5.55473 * HdotV - 6.98316) * HdotV);
		
		float attenuation = 1.0 * ground;
		vec3 specular = vec3(D*F*G) * spec * specularColor.a;
		vec3 lightIntensity = lightIntensities[i];
		vec3 Li = lightIntensity * (diffuse + specular) * attenuation;
		
		final += Li * colorBoost;
	}

	vec2 envUV = R.xy + vec2(R.z*0.5, R.z);

	out_Color = vec4(final.rgb, 1.0);
}

#endif
