#version 330 core

uniform sampler2D normal_depth;
uniform sampler2D depth_buffer;

uniform vec2 TexelSize;
uniform vec3 CameraRange; // 2*near, (far + near), (far - near)

in vec2 uv;

layout (location = 0) out vec4 frag_color;

float sampleNormal(in sampler2D smp, in vec2 uv, in vec3 currentNormal)
{
	vec3 n = texture(smp, uv).xyz;
	return dot(currentNormal, n);
}

float sampleDepth(in sampler2D smp, in vec2 uv)
{
	// (2.0 * NearZ) / (FarZ + NearZ - depth*(FarZ - NearZ))
	return CameraRange.x / (CameraRange.y - texture(smp, uv).r*CameraRange.z);
}


void main()
{
	// find edges in normal map
	vec3 currentNormal = texture(normal_depth, uv).xyz;

	float dot00 = sampleNormal(normal_depth, uv + vec2(-TexelSize.x,  TexelSize.y), currentNormal);
	float dot01 = sampleNormal(normal_depth, uv + vec2(  0.0,  TexelSize.y), currentNormal);
	float dot02 = sampleNormal(normal_depth, uv + vec2( TexelSize.x,  TexelSize.y), currentNormal);
	float dot10 = sampleNormal(normal_depth, uv + vec2(-TexelSize.x,   0.0), currentNormal);
	float dot12 = sampleNormal(normal_depth, uv + vec2( TexelSize.x,   0.0), currentNormal);
	float dot20 = sampleNormal(normal_depth, uv + vec2(-TexelSize.x, -TexelSize.y), currentNormal);
	float dot21 = sampleNormal(normal_depth, uv + vec2(  0.0, -TexelSize.y), currentNormal);
	float dot22 = sampleNormal(normal_depth, uv + vec2( TexelSize.x, -TexelSize.y), currentNormal);
	
	float cosAngle = min(dot00, dot01);
	cosAngle = min(cosAngle, dot02);
	cosAngle = min(cosAngle, dot10);
	cosAngle = min(cosAngle, dot12);
	cosAngle = min(cosAngle, dot20);
	cosAngle = min(cosAngle, dot21);
	cosAngle = min(cosAngle, dot22);

	//float normalEdge = smoothstep(0.0, 1.0/16.0, 1.0 - cosAngle);
	float normalEdge = max(1.0 - cosAngle, 0.0);
	
	// find edges in depth map
	const float MagnitudeScale = 64.0;
	const float MagnitudeThreshold = 1.0 / MagnitudeScale;

	float currentDepth = sampleDepth(depth_buffer, uv);
	float depthDiff = 0.0;

	depthDiff += abs( sampleDepth(depth_buffer, uv + vec2(-TexelSize.x,  TexelSize.y)) - currentDepth );
	depthDiff += abs( sampleDepth(depth_buffer, uv + vec2(  0.0,  TexelSize.y)) - currentDepth );
	depthDiff += abs( sampleDepth(depth_buffer, uv + vec2( TexelSize.x,  TexelSize.y)) - currentDepth );
	depthDiff += abs( sampleDepth(depth_buffer, uv + vec2(-TexelSize.x,   0.0)) - currentDepth );
	depthDiff += abs( sampleDepth(depth_buffer, uv + vec2( TexelSize.x,   0.0)) - currentDepth );
	depthDiff += abs( sampleDepth(depth_buffer, uv + vec2(-TexelSize.x, -TexelSize.y)) - currentDepth );
	depthDiff += abs( sampleDepth(depth_buffer, uv + vec2(  0.0, -TexelSize.y)) - currentDepth );
	depthDiff += abs( sampleDepth(depth_buffer, uv + vec2( TexelSize.x, -TexelSize.y)) - currentDepth );
	
	//float depthEdge = depthDiff * MagnitudeScale;
	//if ( depthEdge < MagnitudeThreshold ) depthEdge = 0.0;
	float depthEdge = smoothstep(MagnitudeThreshold, 1.0, depthDiff * MagnitudeScale);

	//frag_color = vec4( max(normalEdge, depthEdge) );
	//frag_color = vec4( depthEdge );
	frag_color = vec4( normalEdge );
}
