#[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 ); }