#version 430 core

uniform vec2 detailParams; // uv-scale, intensity
uniform float smoothness[4];

uniform sampler2D mask;
uniform sampler2D pebbles_diffuse;
uniform sampler2D pebbles_normal;
uniform sampler2D grass_diffuse;
uniform sampler2D grass_normal;
uniform sampler2D rock_diffuse;
uniform sampler2D rock_normal;
uniform sampler2D sand_diffuse;
uniform sampler2D sand_normal;
uniform sampler2D details_diffuse;
uniform sampler2D details_normal;

in vec2 pos_zw;
in vec3 normal;
in vec4 tangent;
in vec3 ec_pos;
in vec2 uv;
in vec3 world_uvw;

#include <deferred/gbuffer_write_include.frag>

#include <deferred/tangentspace_include.frag>

vec4 readMask(in vec2 uv)
{
	vec4 m = texture(mask, uv);
	float l = dot(m.rgb, m.rgb);
	if ( l > 0.0 ) m.rgb = normalize(m.rgb);
	else m.rgb = vec3(0.0);
	//m.a = 1.0 - m.a;
	m.a = 1.0 - dot(m.rgb, vec3(1.0));
	return normalize(m);
}


vec4 cubeSampling(sampler2D smp, in vec3 uvw, in vec3 mask)
{
	return  texture(smp, uvw.xy) * mask.z +
		texture(smp, uvw.xz) * mask.y +
		texture(smp, uvw.zy) * mask.x;
}


void main()
{
#if 0
	vec3 t, b;
	vec3 n = normalize(normal);
	per_fragment_tangent_space(ec_pos, world_uvw.xz, t, b);
#else
	vec3 t = normalize(tangent.xyz);
	vec3 n = normalize(normal);
	//vec3 b = normalize( cross(n, t) * tangent.w );
	vec3 b = normalize( cross(n, t) );
#endif

	vec4 diff = vec4(0);
	vec4 norm = vec4(0);
	vec4 m = readMask(uv);

#if 1
	vec2 uv1 = world_uvw.xz;
	diff += texture(pebbles_diffuse, uv1) * m.r;
	diff += texture(grass_diffuse, uv1) * m.g;
	diff += texture(rock_diffuse, uv1) * m.b;
	diff += texture(sand_diffuse, uv1) * m.a;

	norm += texture(pebbles_normal, uv1) * m.r;
	norm += texture(grass_normal, uv1) * m.g;
	norm += texture(rock_normal, uv1) * m.b;
	norm += texture(sand_normal, uv1) * m.a;

	vec2 uv2 = world_uvw.xz * detailParams.x;
	diff *= vec4(1.0) - texture(details_diffuse, uv2) * detailParams.y;
	norm += (texture(details_normal, uv2)*2.0 - vec4(1.0)) * detailParams.y;
#else
	vec3 mask = abs(n);

	diff += cubeSampling(pebbles_diffuse, world_uvw, mask) * m.r;
	diff += cubeSampling(grass_diffuse, world_uvw, mask) * m.g;
	diff += cubeSampling(rock_diffuse, world_uvw, mask) * m.b;
	diff += cubeSampling(sand_diffuse, world_uvw, mask) * m.a;

	norm += cubeSampling(pebbles_normal, world_uvw, mask) * m.r;
	norm += cubeSampling(grass_normal, world_uvw, mask) * m.g;
	norm += cubeSampling(rock_normal, world_uvw, mask) * m.b;
	norm += cubeSampling(sand_normal, world_uvw, mask) * m.a;

	vec3 uvw = world_uvw * detailParams.x;
	diff *= vec4(1.0) - cubeSampling(details_diffuse, uvw, mask) * detailParams.y;
	norm += (cubeSampling(details_normal, uvw, mask)*2.0 - vec4(1.0)) * detailParams.y;
#endif

	mat3 mr = mat3(t, b, n);
	n = normalize(mr * (norm.xyz*2.0 - vec3(1.0)));

	gb_diffuse.rgb = diff.rgb;
	gb_diffuse.a = 0.0;

	gb_specular.rgb = diff.rgb * diff.a;
	gb_specular.a = smoothness[0]*m.r + smoothness[1]*m.g + smoothness[2]*m.b + smoothness[3]*m.a;

	gb_normal.xyz = n;
	gb_normal.w = 0.0;

	gb_light = vec4(0.0);
}
