Rounded corners
Rounded corners for nodes. See comments for more information. Designed for Widgets. Please, read instructions before using.
Cover image source: https://unsplash.com/photos/hXNGeAFOgT4
Shader code
shader_type canvas_item;
// Shader to round corners of a canvas. The 'radius_scale' is multiplied by
// minimum(width, height)/2.0 to calculate the radius of the corners.
//
// Instructions:
// 1) The node that uses this shader must have signals 'tree_entered' and
// 'item_rect_changed' connected to a callable with the next code:
// material.set_shader_parameter("width", size.x)
// material.set_shader_parameter("height", size.y)
//
// Known issues:
// 1) If used on 'TextureRect', take care of 'expand_mode' and 'stretch_mode',
// because image corners might be outside node rectangle and therefore clipped.
// Corners are rounded, but they are outside node's rectangle.
uniform float radius_scale: hint_range(0.0, 1.0, 0.1) = 0.1;
uniform bool rounded_corner_top_left = true;
uniform bool rounded_corner_top_right = true;
uniform bool rounded_corner_bottom_left = true;
uniform bool rounded_corner_bottom_right = true;
uniform float width = 1.0;
uniform float height = 1.0;
void fragment() {
vec4 image = texture(TEXTURE, UV);
vec2 pos = vec2(UV.x*width, UV.y*height);
float radius = min(width, height)*radius_scale/2.0;
float dist;
// Top left corner
if (rounded_corner_top_left) {
dist = length(pos - vec2(radius));
if (dist > radius && pos.x < radius && pos.y < radius) {
image.a = 0.0;
}
// debugging only
// if (dist < radius){image.r = 1.0;}
}
// Top right corner
if (rounded_corner_top_right) {
dist = length(pos - vec2(width-radius, radius));
if (dist > radius && pos.x > width-radius && pos.y < radius) {
image.a = 0.0;
}
// debugging only
// if (dist < radius){image.r = 1.0;}
}
// Bottom left corner
if (rounded_corner_bottom_left) {
dist = length(pos - vec2(radius, height-radius));
if (dist > radius && pos.x < radius && pos.y > height-radius) {
image.a = 0.0;
}
// debugging only
// if (dist < radius){image.r = 1.0;}
}
// Bottom right corner
if (rounded_corner_bottom_right) {
dist = length(pos - vec2(width-radius, height-radius));
if (dist > radius && pos.x > width-radius && pos.y > height-radius) {
image.a = 0.0;
}
// debugging only
// if (dist < radius){image.r = 1.0;}
}
COLOR = image;
}