#[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 edgeThreshold; float edgeIntensity; float contrastThreshold; float contrastIntensity; float debugView; } params; float sampleDepth( ivec2 coord ) { coord = clamp( coord, ivec2( 0 ), ivec2( params.rasterSize ) - ivec2( 1 ) ); vec2 uv = ( vec2( coord ) + 0.5 ) / params.rasterSize; return texture( depth_sampler, uv ).r; } float getEdgeStrength( ivec2 uvOffset ) { float centerDepth = sampleDepth( uvOffset ); float top = sampleDepth( uvOffset + ivec2( 0, -1 ) ); float left = sampleDepth( uvOffset + ivec2( -1, 0 ) ); float gx = left - centerDepth; float gy = top - centerDepth; gx = 1.0 - clamp( abs( 10 * abs( gx ) - params.edgeThreshold ) * params.edgeIntensity, 0.0, 1.0 ); gy = 1.0 - clamp( abs( 10 * abs( gy ) - params.edgeThreshold ) * params.edgeIntensity, 0.0, 1.0 ); return length( vec2( gx, gy ) ); } void main( ) { ivec2 uv = ivec2( gl_GlobalInvocationID.xy ); ivec2 size = ivec2( params.rasterSize ); if ( uv.x >= size.x || uv.y >= size.y ) { return; } // float centerDepth = sampleDepth( uv ); // float top_left = sampleDepth( uv + ivec2( -1, -1 ) ); // float top = sampleDepth( uv + ivec2( 0, -1 ) ); // float top_right = sampleDepth( uv + ivec2( 1, -1 ) ); // float left = sampleDepth( uv + ivec2( -1, 0 ) ); // float right = sampleDepth( uv + ivec2( 1, 0 ) ); // float bottom_left = sampleDepth( uv + ivec2( -1, 1 ) ); // float bottom = sampleDepth( uv + ivec2( 0, 1 ) ); // float bottom_right = sampleDepth( uv + ivec2( 1, 1 ) ); // // ( l - c ) + ( c - r ); // // // float gx = left - centerDepth; // float gy = top - centerDepth; // gx = 1.0 - clamp( abs( 10 * abs( gx ) - params.edgeThreshold ) * params.edgeIntensity, 0.0, 1.0 ); // gy = 1.0 - clamp( abs( 10 * abs( gy ) - params.edgeThreshold ) * params.edgeIntensity, 0.0, 1.0 ); float edgeStrength = 0; float amount = 0; int radius = int( params.contrastThreshold ); for ( int x = -radius; x <= radius; x ++ ) { for ( int y = -radius; y <= radius; y ++ ) { ivec2 xy = ivec2( x, y ); float es = getEdgeStrength( uv + xy ); float a = 1.0 / ( 1.0 + length( xy ) ); edgeStrength += es; amount += pow( a, params.contrastIntensity ); } } edgeStrength /= amount; /* edgeStrength = min( abs( edgeStrength - params.edgeThreshold ) * params.edgeIntensity, 1.0 ); // float edgeStrength = abs( left - right ); // edgeStrength = clamp( ( edgeStrength - params.edgeThreshold ) * params.edgeIntensity, 0.0, 1.0 ); float edge = edgeStrength; vec4 color = imageLoad( color_image, uv ); vec4 color_left = imageLoad( color_image, uv + ivec2( -1, 0 ) ); vec4 color_left2 = imageLoad( color_image, uv + ivec2( -2, 0 ) ); vec4 color_right = imageLoad( color_image, uv + ivec2( 1, 0 ) ); vec4 color_right2 = imageLoad( color_image, uv + ivec2( 2, 0 ) ); float c = ( length( color_left - color_right ) - params.contrastThreshold ) * params.contrastIntensity; float d = min( 1.0, c ); edge = max( d, edge ); vec4 smoothedColor = color_left + color_left2 + 2.0 * color + color_right + color_right2; smoothedColor /= 6.0; smoothedColor =vec4( 0.0, 0.0, 0.0, 1.0 ); float gray = color.r * 0.2125 + color.g * 0.7154 + color.b * 0.0721; vec3 debugViewColor = vec3( params.amounts.x * gray, params.amounts.y * centerDepth, edge ); color.rgb = mix( color.rgb, smoothedColor.rgb, edge * params.effectStrength ); color.rgb = mix( color.rgb, debugViewColor, params.debugView ); */ vec4 color = imageLoad( color_image, uv ); color = mix( color, vec4( 0.0, 0.0, 0.0, 1.0 ), edgeStrength * params.effectStrength ); imageStore( color_image, uv, color ); }