62 lines
2.2 KiB
GLSL
62 lines
2.2 KiB
GLSL
#[compute]
|
|
#version 450
|
|
|
|
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
|
|
|
|
layout(rgba16, set = 0, binding = 0) uniform restrict readonly image2D inputImage;
|
|
layout(rgba16, set = 1, binding = 0) uniform restrict readonly image2D originalImage;
|
|
layout(rgba16, set = 2, binding = 0) uniform restrict writeonly image2D outputImage;
|
|
layout(std430, set = 3, binding = 0) buffer restrict readonly OutlinesSizeBuffer { int size; } osb;
|
|
|
|
void main()
|
|
{
|
|
ivec2 current_position = ivec2(gl_GlobalInvocationID.xy);
|
|
vec4 current_pixel = imageLoad(inputImage, current_position);
|
|
ivec2 current_seed_position = ivec2(packUnorm2x16(current_pixel.xy), packUnorm2x16(current_pixel.zw));
|
|
|
|
// The "rough" outline generated by the Jump Flood Algorithm contains all the pixels of the desired outline + some more
|
|
// If the current pixel is not a seed, then it can't be part of the outline
|
|
if (current_seed_position.x == 0 && current_seed_position.y == 0)
|
|
{
|
|
imageStore(outputImage, current_position, vec4(0.0f));
|
|
return;
|
|
}
|
|
|
|
float distance_to_seed = distance(vec2(current_position), vec2(current_seed_position));
|
|
float outlinesSize = float(osb.size);
|
|
|
|
// The current pixel is outside the outline range
|
|
if (distance_to_seed > outlinesSize) {
|
|
imageStore(outputImage, current_position, vec4(0.0f));
|
|
return;
|
|
}
|
|
|
|
vec4 original_pixel = imageLoad(originalImage, current_seed_position);
|
|
|
|
// The current pixel is on the edge of the outline, outer side
|
|
if (distance_to_seed > outlinesSize - 1.0f)
|
|
{
|
|
float smoothing = 1.0f - (distance_to_seed - (outlinesSize - 1.0f));
|
|
imageStore(outputImage, current_position, vec4(original_pixel.xyz, smoothing));
|
|
return;
|
|
}
|
|
|
|
// The current pixel is part of the object to outline
|
|
if (distance_to_seed == 0.0f)
|
|
{
|
|
imageStore(outputImage, current_position, vec4(0.0f));
|
|
return;
|
|
}
|
|
|
|
// The current pixel is on the edge of the outline, inner side
|
|
if (distance_to_seed < 1.0f)
|
|
{
|
|
float smoothing = distance_to_seed;
|
|
imageStore(outputImage, current_position, vec4(original_pixel.xyz, smoothing));
|
|
return;
|
|
}
|
|
|
|
// The current pixel is part of the outline
|
|
imageStore(outputImage, current_position, vec4(original_pixel.xyz, original_pixel.a));
|
|
}
|