#[compute]
#version 450


layout( local_size_x = 8, local_size_y = 8, local_size_z = 1 ) in;

layout( rgba16f, set = 0, binding = 0 ) 
uniform image2D color_image;

layout( set = 1, binding = 0 ) 
uniform sampler2D depth_sampler;


layout( push_constant, std430 )
uniform Params 
{
	vec2 rasterSize;
	vec2 amounts;
  float effectStrength;
  float rimOffsetX;
  float rimOffsetY;
  float minDepth;
  float contrastIntensity;
  float debugView;

} params;

float sampleDepth( vec2 coord ) 
{
  coord = clamp( coord, vec2( 0 ), vec2( params.rasterSize ) - vec2( 1.0 ) );

  vec2 uv = ( vec2( coord ) + 0.5 ) / params.rasterSize;
  return texture( depth_sampler, uv ).r;
}


void main( ) 
{
	ivec2 uv   = ivec2( gl_GlobalInvocationID.xy );
	ivec2 size = ivec2( params.rasterSize );

	if ( uv.x >= size.x || uv.y >= size.y ) 
  {
		return;
	}


  vec2 rimOffset = vec2( params.rimOffsetX,  params.rimOffsetY );

  float depth    = sampleDepth( uv );
  float rimDepth = sampleDepth( uv + rimOffset );  

  float rimStrength = min( 1.0, max( 0.0, depth - rimDepth ) * params.contrastIntensity );

  float amount = 1.0 - min( 1.0, pow( depth * params.amounts.x + params.amounts.y, params.minDepth ) ); 

 
  vec4 color = imageLoad( color_image, uv );
  float combinedAmount = max( 0.0, min( 1.0, amount * rimStrength * params.effectStrength ) );
  color = mix( color, vec4( 1.0, 1.0, 1.0, 1.0 ), combinedAmount );
  
  color = mix( color, vec4( amount, amount, amount, 1.0 ), params.debugView );
	imageStore( color_image, uv, color );
}