// Copyright (C) Kimmo Lahtinen - All Rights Reserved

// Uniforms
uniform highp vec3 uni_camera_look_at;
uniform highp vec3 uni_camera_dir;
uniform highp vec3 uni_sun_light_dir;
uniform highp vec4 uni_offsets_foam;
uniform highp vec4 uni_offsets_normals;
uniform highp vec4 uni_effect_params_vert;

uniform lowp sampler2D uni_texture_water_depth;
uniform lowp sampler2D uni_texture_depth_gradient;

uniform vec4 uni_effect_params_frag[3];

// Input from engine (per vertex)
attribute highp vec4 in_pos_and_depth;

// Output to pixel shader
varying vec2 frag_water_depth_uv;
varying highp vec2 frag_foam_uv_1;
varying highp vec2 frag_foam_uv_2;
varying highp vec2 frag_normal_uv_1;
varying highp vec2 frag_normal_uv_2;
varying vec2 frag_topdown_rt_uv;

varying vec3 frag_water_color_per_vertex;
varying vec3 frag_lighting_color;
varying float frag_depth;
varying vec3 frag_halfway_vec_specular;
varying float frag_lighting_luminance;

// http://stackoverflow.com/questions/596216/formula-to-determine-brightness-of-rgb-color
float luminance(vec3 l)
{
	return sqrt(0.299*l.r*l.r + 0.587*l.g*l.g + 0.114*l.b*l.b);
}

void main(void)
{
	highp float specular_eye_distance = uni_effect_params_vert.x;
	highp float foam_scale 			= uni_effect_params_vert.y;
	highp float normal_scale_1 		= uni_effect_params_vert.z;
	highp float normal_scale_2 		= uni_effect_params_vert.w;

	// Texture UVs
	frag_foam_uv_1		= in_pos_and_depth.xy * foam_scale + uni_offsets_foam.xy;
	frag_foam_uv_2		= in_pos_and_depth.xy * foam_scale + uni_offsets_foam.zw;
	frag_normal_uv_1	= in_pos_and_depth.xy * normal_scale_1 + uni_offsets_normals.xy;
	frag_normal_uv_2	= in_pos_and_depth.xy * normal_scale_2 + uni_offsets_normals.zw;
	frag_topdown_rt_uv	= in_pos_and_depth.xy / uni_map_size_max;

	// Transform
	highp vec4 pos_out = to_screen_pos_3d(in_pos_and_depth.xyz);

	// Water depth, screen space
	frag_water_depth_uv	= pos_out.xy * 0.5 + 0.5;

	// Water depth, to down
	frag_depth			= -in_pos_and_depth.w;

	// Lighting
	frag_lighting_color = light_surface(vec3(0, 0, 1));
	frag_lighting_luminance = luminance(frag_lighting_color);

	// Per vertex color for the low quality version	
	float water_depth_eye_dir = texture2D(uni_texture_water_depth, frag_water_depth_uv).r;
	float depth_gradient_scaler	= uni_effect_params_frag[0][0];
	float water_gradient_brightness = uni_effect_params_frag[2][0];
	float water_gradient_v_coord	= uni_effect_params_frag[2][2];
	frag_water_color_per_vertex = texture2D(uni_texture_depth_gradient, vec2(water_depth_eye_dir * depth_gradient_scaler, water_gradient_v_coord)).rgb;
	frag_water_color_per_vertex *= water_gradient_brightness * frag_lighting_color;

	// Specular halfway vec
	highp vec3 eye_pos 		= uni_camera_look_at - (specular_eye_distance * uni_camera_dir);
	highp vec3 eye_dir		= normalize(eye_pos - in_pos_and_depth.xyz);
	highp vec3 light_dir 	= -uni_sun_light_dir;

	frag_halfway_vec_specular = normalize(eye_dir + light_dir);

	// Fragment position
	gl_Position = pos_out;
}
