71 lines
2.1 KiB
Plaintext
71 lines
2.1 KiB
Plaintext
shader_type canvas_item;
|
|
|
|
/* Закрашенный сектор окружности ограниченный угловым сектором и радиусами */
|
|
|
|
uniform vec4 color: source_color = vec4(1, 1, 1, 1);
|
|
uniform vec4 clip_color: source_color = vec4(1.0, 0.5, 0.5, 1.0);
|
|
uniform float width: hint_range(0.0, 360.0, 0.1) = 45.0;
|
|
uniform float band: hint_range(0.0, 0.125) = 0.02;
|
|
uniform float radius: hint_range(0.0, 0.125) = 0.08;
|
|
uniform float dir: hint_range(0.0, 360.0) = 0.0;
|
|
uniform float inner_clip: hint_range(0.0, 0.125) = 0.045;
|
|
|
|
|
|
const vec2 center = vec2(0.125, 0.125); /* Центр должен быть в (0.5, 0.5), но это не так */
|
|
const float dsa = 0.0025; /* Относительное расстояние на котором выполняется сглаживание краёв по радиальным линиям */
|
|
const float dsr = 0.00025; /* Относительное расстояние на котором выполняется сглаживание краёв по круговым линиям */
|
|
|
|
|
|
float smooth_px(float r, float R, float ds)
|
|
{
|
|
return 1.0 - smoothstep(R - ds, R + ds, r);
|
|
}
|
|
|
|
|
|
vec4 sector(vec4 c, vec2 uv_pos, float r0, float r1, float w)
|
|
{
|
|
bool rc = false;
|
|
if (r1 > center.x)
|
|
{
|
|
rc = true;
|
|
r1 = center.x;
|
|
}
|
|
if (r0 < inner_clip)
|
|
{
|
|
rc = true;
|
|
r0 = inner_clip;
|
|
}
|
|
vec2 d = uv_pos - center;
|
|
float theta = atan(d.x, d.y);
|
|
w = radians(w / 2.0);
|
|
float l = distance(center, uv_pos);
|
|
float vr = smooth_px(r0, l, dsr) - smooth_px(r1, l, dsr);
|
|
float va = smooth_px(-w, theta, dsa) - smooth_px(w, theta, dsa);
|
|
if (rc)
|
|
{
|
|
c *= clip_color;
|
|
}
|
|
return c * sqrt(va * vr);
|
|
}
|
|
|
|
|
|
void rotate_vec2(inout vec2 vert, float a)
|
|
{
|
|
float sin_a = sin(a);
|
|
float cos_a = cos(a);
|
|
vert *= mat2(vec2(cos_a, sin_a), vec2(-sin_a, cos_a));
|
|
}
|
|
|
|
|
|
void vertex()
|
|
{
|
|
rotate_vec2(VERTEX, radians(90.0 - dir));
|
|
}
|
|
|
|
|
|
void fragment()
|
|
{
|
|
float dr = band / 2.0;
|
|
COLOR = sector(color, UV, radius - dr, radius + dr, width);
|
|
}
|