2025-04-23 12:00:43 +00:00
|
|
|
#[compute]
|
|
|
|
#version 450
|
|
|
|
|
|
|
|
layout( local_size_x = 32, local_size_y = 32, local_size_z = 1 ) in;
|
|
|
|
|
|
|
|
layout( rgba16f, set = 0, binding = 0 )
|
|
|
|
uniform image2D color_image;
|
|
|
|
|
|
|
|
layout( push_constant, std430 )
|
2025-04-24 13:39:00 +00:00
|
|
|
uniform Params
|
2025-04-23 12:00:43 +00:00
|
|
|
{
|
|
|
|
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( color_image );
|
|
|
|
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( color_image, sample_coord );
|
|
|
|
}
|
|
|
|
|
|
|
|
color /= float( num_samples );
|
|
|
|
vec4 original_color = imageLoad( color_image, texel_coord );
|
|
|
|
imageStore( color_image, texel_coord, mix( original_color, color, params.intensity ) );
|
|
|
|
}
|