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

// Input from vertex 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;

// Uniforms
uniform lowp sampler2D uni_texture_water_depth;
uniform lowp sampler2D uni_texture_normal_map;
uniform lowp sampler2D uni_texture_depth_gradient;
uniform lowp sampler2D uni_texture_foam;

uniform vec4 uni_effect_params_frag[3];

///////////////////////////////////////////////////////////////////////////////

// Supported quality macros, #defined in common.vert!
//#define WATER_PER_PIXEL_DEPTH
//#define WATER_ENABLE_FOAM
//#define WATER_ENABLE_SPECULAR

///////////////////////////////////////////////////////////////////////////////

void main(void) 
{
	// FX control
	float depth_gradient_scaler 	= uni_effect_params_frag[0][0];
	float fake_refraction_distance 	= uni_effect_params_frag[0][1];
	float fake_refraction_ripple 	= uni_effect_params_frag[0][2];
	float specular_pow 				= uni_effect_params_frag[0][3];
	float specular_factor 			= uni_effect_params_frag[1][0];
	float max_foam_depth 			= uni_effect_params_frag[1][1];
	float foam_strength 			= uni_effect_params_frag[1][2];
	float shore_fade_depth 			= uni_effect_params_frag[1][3];
	float water_gradient_brightness = uni_effect_params_frag[2][0];
	float water_bottom_brightness 	= uni_effect_params_frag[2][1];
	float water_gradient_v_coord	= uni_effect_params_frag[2][2];

#ifdef WATER_PER_PIXEL_DEPTH
	// Dependent texture reads, slow on old iOS hardware
	float water_depth_eye_dir = texture2D(uni_texture_water_depth, frag_water_depth_uv).r;
	vec3 water_color = texture2D(uni_texture_depth_gradient, vec2(water_depth_eye_dir * depth_gradient_scaler, water_gradient_v_coord)).rgb;
	water_color *= water_gradient_brightness * frag_lighting_color;

#else
	// Samples the dependent reads per vertex and interpolates, looks worse but good
	// enough for the slower hardware

	vec3 water_color = frag_water_color_per_vertex;
#endif
	
	// Non-dependent texture fetches
#ifdef WATER_ENABLE_FOAM	
	float foam_1 = texture2D(uni_texture_foam, frag_foam_uv_1).r;
	float foam_2 = texture2D(uni_texture_foam, frag_foam_uv_2).r;
#endif	
	vec3 normal_1 = texture2D(uni_texture_normal_map, frag_normal_uv_1).xyz;
	vec3 normal_2 = texture2D(uni_texture_normal_map, frag_normal_uv_2).xyz;

	// Calculate surface normal by adhoc blending from normal map
	normal_1.xy = normal_1.xy * 2.0 - 1.0;
	normal_2.xy = normal_2.xy * 2.0 - 1.0;
	vec3 surface_normal = normalize(normal_1 + normal_2);

	vec2 lightmap_uv = frag_topdown_rt_uv + surface_normal.xy * fake_refraction_ripple - fake_refraction_distance;
	vec3 bottom_diffuse = sample_level_lightmap(lightmap_uv);
	water_color += bottom_diffuse * water_bottom_brightness; // TODO: multiplied inside sample_level_lightmap with scalar -> so this multiply could be combined to scalarxscalar

#ifdef WATER_ENABLE_SPECULAR
	// Specular highlights
	vec3 halfway = normalize(frag_halfway_vec_specular);
	water_color += specular_factor * pow(dot(surface_normal, halfway), specular_pow) * frag_lighting_luminance;
//	water_color += specular_factor * pow(saturate(dot(surface_normal, halfway)), specular_pow);
#endif	

#ifdef WATER_ENABLE_FOAM
	// Add foam to shallow areas (b&w additive)
	float foam_lerp = max(0.0, max_foam_depth - frag_depth);
	water_color += foam_lerp * (foam_1 + foam_2) * foam_strength * frag_lighting_luminance;
#endif	

	// A bit of transparency to shores
	float shore_transparency = smoothstep(0.0, shore_fade_depth, frag_depth);
	gl_FragColor = vec4(water_color * shore_transparency, shore_transparency);
//	gl_FragColor *= 0.001;
}
