#[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 inputImage;

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

layout( set = 2, binding = 0 ) 
uniform sampler2D depthSampler;



layout( push_constant, std430 )
uniform Params 
{
	vec2 amounts;

  float effectStrength;
  float rimOffsetX;
  float rimOffsetY;
  float minDepth;

  float contrastIntensity;

} params;

float sampleDepth( vec2 coord, vec2 size ) 
{
  coord = clamp( coord, vec2( 0 ), size - vec2( 1.0 ) );

  vec2 uv = ( vec2( coord ) + 0.5 ) / size;
  return texture( depthSampler, uv ).r;
}


void main( ) 
{
	ivec2 xy   = ivec2( gl_GlobalInvocationID.xy );
	ivec2 size = imageSize( outputImage );

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


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

  float depth    = sampleDepth( xy, size );
  float rimDepth = sampleDepth( xy + rimOffset, size );

  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( inputImage, xy );
  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 );
  
	imageStore( outputImage, xy, color );
}