Adjust erf estimation function (#15423)

Son created

Release Notes:

- Fixed a (potential) small error in erf estimation. Technically, the
error is negligible.

I am not sure where the current calculation for erf come from and if it
is intended or a simple mistake. However it looks slightly different
from the official calculation, notably
[this](https://en.wikipedia.org/wiki/Error_function#Approximation_with_elementary_functions)
from Wikipedia.

I will add a comment if it is intended.

Change summary

crates/gpui/Cargo.toml                      |  4 +++
crates/gpui/examples/shadow.rs              | 29 +++++++++++++++++++++++
crates/gpui/src/platform/blade/shaders.wgsl |  2 
crates/gpui/src/platform/mac/shaders.metal  |  6 ++--
4 files changed, 37 insertions(+), 4 deletions(-)

Detailed changes

crates/gpui/Cargo.toml 🔗

@@ -172,3 +172,7 @@ path = "examples/window_shadow.rs"
 [[example]]
 name = "input"
 path = "examples/input.rs"
+
+[[example]]
+name = "shadow"
+path = "examples/shadow.rs"

crates/gpui/examples/shadow.rs 🔗

@@ -0,0 +1,29 @@
+use gpui::*;
+
+struct Shadow {}
+
+impl Render for Shadow {
+    fn render(&mut self, _cx: &mut ViewContext<Self>) -> impl IntoElement {
+        div()
+            .flex()
+            .bg(rgb(0xffffff))
+            .size_full()
+            .justify_center()
+            .items_center()
+            .child(div().size_8().shadow_sm())
+    }
+}
+
+fn main() {
+    App::new().run(|cx: &mut AppContext| {
+        let bounds = Bounds::centered(None, size(px(300.0), px(300.0)), cx);
+        cx.open_window(
+            WindowOptions {
+                window_bounds: Some(WindowBounds::Windowed(bounds)),
+                ..Default::default()
+            },
+            |cx| cx.new_view(|_cx| Shadow {}),
+        )
+        .unwrap();
+    });
+}

crates/gpui/src/platform/blade/shaders.wgsl 🔗

@@ -150,7 +150,7 @@ fn gaussian(x: f32, sigma: f32) -> f32{
 fn erf(v: vec2<f32>) -> vec2<f32> {
     let s = sign(v);
     let a = abs(v);
-    let r1 = 1.0 + (0.278393 + (0.230389 + 0.078108 * (a * a)) * a) * a;
+    let r1 = 1.0 + (0.278393 + (0.230389 + (0.000972 + 0.078108 * a) * a) * a) * a;
     let r2 = r1 * r1;
     return s - s / (r2 * r2);
 }

crates/gpui/src/platform/mac/shaders.metal 🔗

@@ -657,9 +657,9 @@ float gaussian(float x, float sigma) {
 float2 erf(float2 x) {
   float2 s = sign(x);
   float2 a = abs(x);
-  x = 1. + (0.278393 + (0.230389 + 0.078108 * (a * a)) * a) * a;
-  x *= x;
-  return s - s / (x * x);
+  float2 r1 = 1. + (0.278393 + (0.230389 + (0.000972 + 0.078108 * a) * a) * a) * a;
+  float2 r2 = r1 * r1;
+  return s - s / (r2 * r2);
 }
 
 float blur_along_x(float x, float y, float sigma, float corner,