#[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( push_constant, std430 ) 
uniform Params 
{
    vec2 center;     // 8 bytes
    float radius;    // 4 bytes
    float intensity; // 4 bytes
    float samples;   // 4 bytes ( will be cast to int )
    vec2 _padding;   // 8 bytes ( matches 32-byte total )

} params;

void main( ) 
{
    ivec2 img_size = imageSize( inputImage );
    ivec2 texel_coord = ivec2( gl_GlobalInvocationID.xy );
    
    if ( any( greaterThanEqual( texel_coord, img_size ) )  ) 
    {
      return;
    }

    vec2 uv = ( vec2( texel_coord ) + 0.5 ) / vec2( img_size );
    vec2 dir = normalize( uv - params.center );
    int num_samples = int( clamp( params.samples, 1.0, 64.0 ) );

    vec4 color = vec4( 0.0 );

    for ( int i = 0; i < num_samples; i++ ) 
    {
      float t = float( i ) / float( num_samples );
      vec2 sample_uv = clamp( uv + dir * t * params.radius, vec2( 0.0 ), vec2( 1.0 ) );
      ivec2 sample_coord = ivec2( sample_uv * vec2( img_size ) );
      sample_coord = clamp( sample_coord, ivec2( 0 ), img_size - ivec2( 1 ) );
      color += imageLoad( inputImage, sample_coord );
    }
    
    color /= float( num_samples );
    vec4 original_color = imageLoad( inputImage, texel_coord );
    imageStore( outputImage, texel_coord, mix( original_color, color, params.intensity ) );
}