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);
}
The shader code and all code snippets in this post are under CC0 license and can be used freely without the author's permission. Images and videos, and assets depicted in those, do not fall under this license. For more info, see our License terms.
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments