Skip to content

Commit d277fbf

Browse files
committed
SDF library improvements.
1 parent 4045d84 commit d277fbf

File tree

1 file changed

+39
-56
lines changed

1 file changed

+39
-56
lines changed

shaders/src/shaders/loading_repeating_circles.rs

Lines changed: 39 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ fn sdf_arc_filled(
297297
}
298298
}
299299

300-
SDFValue(sdf_value)
300+
SDFValue::new(sdf_value)
301301
}
302302

303303
/// Computes a circular angular fade-out based on direction from center.
@@ -355,6 +355,11 @@ fn arc_fade_out(
355355
}
356356
rel_angle = rel_angle.clamp(0.0, effective_arc_length_angle);
357357

358+
if opaque_percentage >= 1.0 - EPSILON {
359+
// If the opaque percentage is effectively 100%, we return 1.0.
360+
return 1.0;
361+
}
362+
358363
let norm_angle = rel_angle / effective_arc_length_angle;
359364

360365
let fade_center = fade_center_angle.rem_euclid(TWO_PI);
@@ -401,7 +406,7 @@ fn arc_fade_out(
401406
/// * `opaque_percentage`: Percentage of the arc that is opaque.
402407
/// The fade starts at the edges of the opaque region.
403408
///
404-
/// Returns a `Vec2` with the first component being the SDF value
409+
/// Returns a `Vec2` with the first component being the [`SDFValue`] for the arc outline,
405410
/// and the second component being the fade intensity.
406411
fn sdf_arc_outline(
407412
uv: Vec2,
@@ -414,14 +419,6 @@ fn sdf_arc_outline(
414419
fade_center_angle: f32,
415420
opaque_percentage: f32,
416421
) -> (SDFValue, f32) {
417-
let sdf_inner = sdf_arc_filled(
418-
uv,
419-
center_shape,
420-
start_angle,
421-
end_angle,
422-
spine_radius,
423-
inner_radius * 2.0,
424-
);
425422
let sdf_outer = sdf_arc_filled(
426423
uv,
427424
center_shape,
@@ -430,8 +427,7 @@ fn sdf_arc_outline(
430427
spine_radius,
431428
outer_radius * 2.0,
432429
);
433-
// remove m_inner from m_outer
434-
let sdf_value = sdf_outer.difference(sdf_inner);
430+
let sdf_value = sdf_outer.to_outline_asym(outer_radius - inner_radius, 0.0);
435431
let fade_intensity = arc_fade_out(
436432
uv,
437433
center_shape,
@@ -445,22 +441,19 @@ fn sdf_arc_outline(
445441
(sdf_value, fade_intensity)
446442
}
447443

448-
fn sdf_circle_outline(uv: Vec2, center: Vec2, radius: f32, stroke: f32) -> f32 {
449-
// Compute distance from pixel to circle center.
450-
let dist = (uv - center).length();
451-
// Half stroke for symmetric band.
452-
let half_th = stroke * 0.5;
453-
// Return 1 if pixel is within the stroke band.
454-
(dist - radius).abs().step(half_th)
455-
}
456-
457-
fn sdf_circle(uv: Vec2, center: Vec2, inner_radius: f32, outer_radius: f32) -> f32 {
458-
// Compute distance from pixel to circle center.
459-
let dist = (uv - center).length();
460-
// Return 1 if pixel is within the stroke band.
461-
(dist - inner_radius)
462-
.abs()
463-
.step(outer_radius - inner_radius)
444+
/// SDF for a filled circle.
445+
///
446+
/// * `uv`: The coordinates relative to the center of the circle.
447+
/// * `center`: The center of the circle.
448+
/// * `radius`: The radius of the circle.
449+
///
450+
/// Returns the [`SDFValue`] for the circle.
451+
fn sdf_circle_filled(uv: Vec2, center: Vec2, radius: f32) -> SDFValue {
452+
let p = uv - center;
453+
let d = p.length() - radius;
454+
let outside_distance = d.max(0.0);
455+
let inside_distance = d.min(0.0);
456+
SDFValue::new(outside_distance + inside_distance)
464457
}
465458

466459
/// Returns a value along an exponential curve shaped by `c`.
@@ -938,13 +931,13 @@ impl Inputs {
938931
.position;
939932
let middle_circle_radius = middle_circle_position.y.abs().max(target_radius);
940933

941-
let m_middle_circle_position_path = sdf_circle_outline(
934+
let m_middle_circle_position_path = sdf_circle_filled(
942935
uv,
943936
middle_circle_start_position / 2.0,
944937
middle_circle_start_radius / 2.0,
945-
target_stroke / 2.0,
946-
);
947-
debug_blue_alpha = debug_blue_alpha.max(m_middle_circle_position_path);
938+
)
939+
.to_outline(target_stroke / 2.0);
940+
debug_blue_alpha = debug_blue_alpha.max(m_middle_circle_position_path.to_alpha());
948941

949942
let middle_circle_moved_distance =
950943
(middle_circle_start_position - middle_circle_position).length();
@@ -958,23 +951,17 @@ impl Inputs {
958951
//middle_circle_position.y -=
959952
// (middle_circle_position.y + middle_circle_radius) * (1.0 - t_master);
960953

961-
let m_start_circle = sdf_circle_outline(uv, Vec2::ZERO, target_radius, target_stroke);
962-
debug_red_alpha = debug_red_alpha.max(m_start_circle);
963-
let m_middle_circle_path = sdf_circle_outline(
964-
uv,
965-
middle_circle_start_position,
966-
middle_circle_start_radius,
967-
target_stroke / 2.0,
968-
);
969-
debug_red_alpha = debug_red_alpha.max(m_middle_circle_path);
954+
let m_start_circle = sdf_circle_filled(uv, Vec2::ZERO, target_radius).to_outline(target_stroke);
955+
debug_red_alpha = debug_red_alpha.max(m_start_circle.to_alpha());
956+
let m_middle_circle_path =
957+
sdf_circle_filled(uv, middle_circle_start_position, middle_circle_start_radius)
958+
.to_outline(target_stroke / 2.0);
959+
debug_red_alpha = debug_red_alpha.max(m_middle_circle_path.to_alpha());
970960

971-
let m_middle_circle_outline = sdf_circle_outline(
972-
uv,
973-
middle_circle_position,
974-
middle_circle_radius,
975-
target_stroke / 2.0,
976-
);
977-
debug_blue_alpha = debug_blue_alpha.max(m_middle_circle_outline);
961+
let m_middle_circle_outline =
962+
sdf_circle_filled(uv, middle_circle_position, middle_circle_radius)
963+
.to_outline(target_stroke / 2.0);
964+
debug_blue_alpha = debug_blue_alpha.max(m_middle_circle_outline.to_alpha());
978965

979966
for i in 0..num_circles {
980967
// Compute the position of the circle based on the angle and radius.
@@ -1002,13 +989,9 @@ impl Inputs {
1002989
black_alpha = black_alpha.max(m.0.to_alpha() * (m.1 + t_assist_circle).min(1.0));
1003990
// * (m.y + 6.0 / 256.0));
1004991

1005-
let m = sdf_circle_outline(
1006-
uv,
1007-
middle_circle_position,
1008-
middle_circle_radius,
1009-
outer_circle_outer_radius * 2.0,
1010-
);
1011-
black_alpha = black_alpha.max((smoothstep(0.0, aa_width, m)) * t_assist_circle);
992+
let m = sdf_circle_filled(uv, middle_circle_position, middle_circle_radius)
993+
.to_outline(outer_circle_outer_radius * 2.0);
994+
black_alpha = black_alpha.max(m.to_alpha() * t_assist_circle);
1012995
}
1013996

1014997
if DEBUG {
@@ -1019,7 +1002,7 @@ impl Inputs {
10191002
PI / 4.0,
10201003
1.0,
10211004
0.1,
1022-
0.3,
1005+
0.5,
10231006
-PI / 4.0,
10241007
1.0,
10251008
);

0 commit comments

Comments
 (0)