sdf循环(circle_sdf)
在纯色背景中不断可八向移动的排列成矩阵的纯色sdf图形(Solid color SDF graphics) 排列在一个矩阵中,该矩阵可以在纯色背景中向八个方向连续移动)
Shader code
shader_type canvas_item;
group_uniforms Basis.Select;
uniform bool circle = false;
uniform bool box = false;
uniform bool rounded_box = false;
uniform bool oriented_box = false;
uniform bool segment = false;
group_uniforms Basis.Basis;
uniform int ranks = 1;
uniform float speed = 1.0;
group_uniforms Basis.position;
uniform float position_x : hint_range(0, 1) = 0.0;
uniform float position_y : hint_range(0, 1) = 0.0;
uniform float direction_x : hint_range(-1, 1, 1) = 1.0;
uniform float direction_y : hint_range(-1, 1, 1) = 0.0;
group_uniforms Basis.color;
uniform vec3 background_color : source_color = vec3(1,1,1);
uniform vec3 cycle_color : source_color = vec3(0,0,0);
group_uniforms Select.Circle;
uniform float c_radius : hint_range(0, 1) = 0.5;
group_uniforms Select.Box;
uniform float b_width : hint_range(0, 1) = 0.5;
uniform float b_height : hint_range(0, 1) = 0.5;
group_uniforms Select.Rounded_Box;
uniform float rb_width : hint_range(0, 1) = 0.5;
uniform float rb_height : hint_range(0, 1) = 0.5;
uniform float rb_lr_radius : hint_range(0, 1) = 0.05;
uniform float rb_tr_radius : hint_range(0, 1) = 0.05;
uniform float rb_ll_radius : hint_range(0, 1) = 0.05;
uniform float rb_tl_radius : hint_range(0, 1) = 0.05;
group_uniforms Select.oriented_box;
uniform float ob_a_x : hint_range(-1, 1) = 0.25;
uniform float ob_a_y : hint_range(-1, 1) = 0.25;
uniform float ob_b_x : hint_range(-1, 1) = 0.75;
uniform float ob_b_y : hint_range(-1, 1) = 0.75;
uniform float ob_width : hint_range(0, 1.5) = 0.5;
group_uniforms Select.segment;
uniform float s_a_x = 0.25;
uniform float s_a_y= 0.25;
uniform float s_b_x= 0.75;
uniform float s_b_y= 0.75;
float sdf_circle( vec2 p, float r ) {
return length(p) - r;
}
float sdf_box( in vec2 p, in vec2 b )
{
vec2 d = abs(p) - b;
return length(max(d, 0.0)) + min(max(d.x, d.y), 0.0);
}
float sdf_rounded_box( in vec2 p, in vec2 b, in vec4 r) {
r.xy = (p.x > 0.0) ? r.xy : r.zw;
r.x = (p.y > 0.0) ? r.x : r.y;
vec2 q = abs(p) - b + r.x;
return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - r.x;
}
float sdf_oriented_box( in vec2 p, in vec2 a, in vec2 b, float th )
{
float l = length(b - a);
vec2 d = (b - a) / l;
vec2 q = (p - (a + b) * 0.5);
q = mat2(vec2(d.x, -d.y),vec2(d.y, d.x)) * q;
q = abs(q) - vec2(l, th) * 0.5;
return length(max(q, 0.0)) + min(max(q.x, q.y), 0.0);
}
float sdf_segment( in vec2 p, in vec2 a, in vec2 b )
{
vec2 pa = p-a, ba = b-a;
float h = clamp( dot(pa, ba)/dot(ba, ba), 0.0, 1.0);
return length(pa - ba * h);
}
const int MAX_POSITIONS = 18;
vec2[MAX_POSITIONS] get_positions() {
vec2[MAX_POSITIONS] positions;
int p = 0;
for (float i = -1.0; i <= 1.0; i += 1.0) {
for (float j = -1.0; j <= 1.0; j += 1.0) {
if (p >= MAX_POSITIONS) break;
positions[p++] = vec2(position_x + i - 1.0, position_y + j) + vec2(direction_x, direction_y) * fract(TIME * speed);
positions[p++] = vec2(position_x + i, position_y + j) + vec2(direction_x, direction_y) * fract(TIME * speed);
}
}
return positions;
}
float cycle_circle(vec2 uv, float r) {
float cycle = 0.0;
vec2 positions[MAX_POSITIONS] = get_positions();
for (int p = 0; p < MAX_POSITIONS; p++) cycle += smoothstep(sdf_circle(uv - positions[p], r), sdf_circle(uv - positions[p], r) + 0.001, 0.01);
return cycle;
}
float cycle_box(vec2 uv, vec2 b) {
float cycle = 0.0;
vec2 positions[MAX_POSITIONS] = get_positions();
for (int p = 0; p < MAX_POSITIONS; p++) cycle += smoothstep(sdf_box(uv - positions[p], b), sdf_box(uv - positions[p], b) + 0.001, 0.01);
return cycle;
}
float cycle_rounded_box(vec2 uv, vec2 b, vec4 r) {
float cycle = 0.0;
vec2 positions[MAX_POSITIONS] = get_positions();
for (int p = 0; p < MAX_POSITIONS; p++) cycle += smoothstep(sdf_rounded_box(uv - positions[p], b, r), sdf_rounded_box(uv - positions[p], b, r) + 0.001, 0.01);
return cycle;
}
float cycle_oriented_box(vec2 uv, in vec2 a, in vec2 b, float th) {
float cycle = 0.0;
vec2 positions[MAX_POSITIONS] = get_positions();
for (int p = 0; p < MAX_POSITIONS; p++) cycle += smoothstep(sdf_oriented_box(uv - positions[p], a, b, th), sdf_oriented_box(uv - positions[p], a, b, th) + 0.001, 0.01);
return cycle;
}
float cycle_segment(vec2 uv, in vec2 a, in vec2 b) {
float cycle = 0.0;
vec2 positions[MAX_POSITIONS] = get_positions();
for (int p = 0; p < MAX_POSITIONS; p++) cycle += smoothstep(sdf_segment(uv - positions[p], a, b), sdf_segment(uv - positions[p], a, b) + 0.001, 0.01);
return cycle;
}
void fragment() {
vec2 ranks_uv = fract(UV * float(ranks));
float cycle = 0.0;
if (circle) cycle = cycle_circle(ranks_uv, c_radius / 2.0);
else if (box) cycle = cycle_box(ranks_uv, vec2(b_width/ 2.0, b_height/ 2.0));
else if (rounded_box) cycle = cycle_rounded_box(ranks_uv, vec2(rb_width / 2.0, rb_height/ 2.0), vec4(rb_lr_radius, rb_tr_radius, rb_ll_radius, rb_tl_radius));
else if (oriented_box) cycle = cycle_oriented_box(ranks_uv, vec2(ob_a_x, ob_a_y), vec2(ob_b_x, ob_b_y), ob_width);
else if (segment) cycle = cycle_segment(ranks_uv, vec2(s_a_x, s_a_y), vec2(s_b_x, s_b_y));
COLOR.rgb = background_color + cycle * (cycle_color - background_color);
}