Files
uarep-ctl/shaders/sector.gdshader
sasha80 2149724638 godot4
2023-08-15 13:45:54 +03:00

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