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