1import bevy_render::view::View; 2import bevy_render::globals::Globals; 7const PI: f32 = 3.14159265358979323846; 8const SAMPLES: u32 = constants::SHADOW_SAMPLES; 10@group(0) @binding(0) var<uniform> view: View; 12struct BoxShadowVertexOutput { 13 @builtin(position) position: vec4<f32>, 14 @location(0) point: vec2<f32>, 15 @location(1) color: vec4<f32>, 16 @location(2) @interpolate(flat) size: vec2<f32>, 17 @location(3) @interpolate(flat) radius_x: vec4<f32>, 18 @location(4) @interpolate(flat) radius_y: vec4<f32>, 19 @location(5) @interpolate(flat) blur: f32, 22fn gaussian(x: f32, sigma: f32) -> f32 { 23 return exp(-(x * x) / (2. * sigma * sigma)) / (sqrt(2. * PI) * sigma); 27fn erf(p: vec2<f32>) -> vec2<f32> { 31 var result = 1.0 + (0.278393 + (0.230389 + 0.078108 * (a * a)) * a) * a; 32 result = result * result; 33 return s - s / (result * result); 36fn horizontalRoundedBoxShadow(x: f32, y: f32, blur: f32, radius: vec2<f32>, half_size: vec2<f32>) -> f32 { 38 if 0.0 < min(radius.x, radius.y) { 39 let d = min(half_size.y - radius.y - abs(y), 0.); 40 c = half_size.x - radius.x + radius.x * sqrt(max(0., 1. - d * d / (radius.y * radius.y))); 42 let integral = 0.5 + 0.5 * erf((x + vec2(-c, c)) * (sqrt(0.5) / blur)); 43 return integral.y - integral.x; 54 let center = (lower + upper) * 0.5; 55 let half_size = (upper - lower) * 0.5; 56 let p = point - center; 57 let low = p.y - half_size.y; 58 let high = p.y + half_size.y; 59 let start = clamp(-3. * blur, low, high); 60 let end = clamp(3. * blur, low, high); 61 let step = (end - start) / f32(SAMPLES); 62 var y = start + step * 0.5; 64 for (var i: u32 = 0; i < SAMPLES; i++) { 65 let corner = select_corner_radius(p, corners_x, corners_y); 66 value += horizontalRoundedBoxShadow(p.x, p.y - y, blur, corner, half_size) * gaussian(y, blur) * step; 74 @location(0) vertex_position: vec3<f32>, 75 @location(1) uv: vec2<f32>, 76 @location(2) vertex_color: vec4<f32>, 77 @location(3) size: vec2<f32>, 78 @location(4) radius_x: vec4<f32>, 79 @location(5) radius_y: vec4<f32>, 80 @location(6) blur: f32, 81 @location(7) bounds: vec2<f32>, 82) -> BoxShadowVertexOutput { 83 var out: BoxShadowVertexOutput; 84 out.position = view.clip_from_world * vec4(vertex_position, 1.0); 85 out.point = (uv.xy - 0.5) * bounds; 86 out.color = vertex_color; 88 out.radius_x = radius_x; 89 out.radius_y = radius_y; 96 in: BoxShadowVertexOutput, 97) -> @location(0) vec4<f32> { 98 let g = in.color.a * roundedBoxShadow(-0.5 * in.size, 0.5 * in.size, in.point, max(in.blur, 0.01), in.radius_x, in.radius_y); 99 return vec4(in.color.rgb, g);