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;
group_uniforms Basis.Basis;
uniform int ranks = 2;
uniform float speed = 1.0;
group_uniforms Basis.position;
uniform float position_x : hint_range(0, 1) = 0.5;
uniform float position_y : hint_range(0, 1) = 0.5;
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;
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;
}
const int MAX_POSITIONS = 18;
vec2[MAX_POSITIONS] get_positions(float l) {
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(r);
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(b.x);
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(b.x);
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;
}
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));
COLOR.rgb = background_color + cycle * (cycle_color - background_color);
}