#version 330 core

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 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()
{
	const float MagnitudeScale = 16.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 magnitude = depthDiff * MagnitudeScale;
	if ( magnitude < MagnitudeThreshold ) magnitude = 0.0;

	frag_color = vec4( magnitude );
}
