rj-action-library/Runtime/Rendering/CompositorEffects/TextureDilation/JFA_Assign.glsl

62 lines
2.2 KiB
Plaintext
Raw Normal View History

2025-04-24 13:39:00 +00:00
#[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));
}