1import bevy_render::view::View; 3 draw_uinode_background, 7import bevy_render::color_operations::{ 24import bevy_render::maths::PI; 26const TAU: f32 = 2. * PI; 28const RIGHT_VERTEX = 2u; 29const BOTTOM_VERTEX = 4u; 31const RADIAL: u32 = 16u; 32const FILL_START: u32 = 32u; 33const FILL_END: u32 = 64u; 34const CONIC: u32 = 128u; 35const BORDER_LEFT: u32 = 256u; 36const BORDER_TOP: u32 = 512u; 37const BORDER_RIGHT: u32 = 1024u; 38const BORDER_BOTTOM: u32 = 2048u; 39const BORDER_ANY: u32 = BORDER_LEFT + BORDER_TOP + BORDER_RIGHT + BORDER_BOTTOM; 41fn enabled(flags: u32, mask: u32) -> bool { 42 return (flags & mask) != 0u; 45@group(0) @binding(0) var<uniform> view: View; 47struct GradientVertexOutput { 48 @location(0) uv: vec2<f32>, 49 @location(1) @interpolate(flat) size: vec2<f32>, 50 @location(2) @interpolate(flat) flags: u32, 51 @location(3) @interpolate(flat) radius_x: vec4<f32>, 52 @location(4) @interpolate(flat) radius_y: vec4<f32>, 53 @location(5) @interpolate(flat) border: vec4<f32>, 56 @location(6) point: vec2<f32>, 57 @location(7) @interpolate(flat) g_start: vec2<f32>, 58 @location(8) @interpolate(flat) dir: vec2<f32>, 59 @location(9) @interpolate(flat) start_color: vec4<f32>, 60 @location(10) @interpolate(flat) start_len: f32, 61 @location(11) @interpolate(flat) end_len: f32, 62 @location(12) @interpolate(flat) end_color: vec4<f32>, 63 @location(13) @interpolate(flat) hint: f32, 64 @builtin(position) position: vec4<f32>, 69 @location(0) vertex_position: vec3<f32>, 70 @location(1) vertex_uv: vec2<f32>, 71 @location(2) flags: u32, 74 @location(3) radius_x: vec4<f32>, 75 @location(4) radius_y: vec4<f32>, 78 @location(5) border: vec4<f32>, 79 @location(6) size: vec2<f32>, 80 @location(7) point: vec2<f32>, 81 @location(8) @interpolate(flat) g_start: vec2<f32>, 82 @location(9) @interpolate(flat) dir: vec2<f32>, 83 @location(10) @interpolate(flat) start_color: vec4<f32>, 84 @location(11) @interpolate(flat) start_len: f32, 85 @location(12) @interpolate(flat) end_len: f32, 86 @location(13) @interpolate(flat) end_color: vec4<f32>, 87 @location(14) @interpolate(flat) hint: f32 88) -> GradientVertexOutput { 89 var out: GradientVertexOutput; 90 out.position = view.clip_from_world * vec4(vertex_position, 1.0); 94 out.radius_x = radius_x; 95 out.radius_y = radius_y; 99 out.start_color = start_color; 100 out.start_len = start_len; 101 out.end_len = end_len; 102 out.end_color = end_color; 103 out.g_start = g_start; 110fn fragment(in: GradientVertexOutput) -> @location(0) vec4<f32> { 112 if enabled(in.flags, RADIAL) { 113 g_distance = radial_distance(in.point, in.g_start, in.dir.x); 114 } else if enabled(in.flags, CONIC) { 115 g_distance = conic_distance(in.dir.x, in.point, in.g_start); 117 g_distance = linear_distance(in.point, in.g_start, in.dir); 120 let gradient_color = interpolate_gradient( 130 if enabled(in.flags, BORDER_ANY) { 131 return draw_uinode_border(gradient_color, in.point, in.size, in.radius_x, in.radius_y, in.border, in.flags); 133 return draw_uinode_background(gradient_color, in.point, in.size, in.radius_x, in.radius_y, in.border, in.flags); 137fn rem_euclid(a: f32, b: f32) -> f32 { 138 return ((a % b) + b) % b; 149 return dot(point - g_start, g_dir); 157 let d = point - center; 158 return length(vec2(d.x, d.y * ratio)); 166 let d = point - center; 167 let angle = atan2(-d.x, d.y) + PI; 168 return (((angle - start) % TAU) + TAU) % TAU; 173 start_color: vec3<f32>, 174 end_color: vec3<f32>, 178 return mix_oklch(start_color, end_color, t); 180 return mix_oklch_long(start_color, end_color, t); 182 return mix_hsv(start_color, end_color, t); 184 return mix_hsv_long(start_color, end_color, t); 186 return mix_hsl(start_color, end_color, t); 188 return mix_hsl_long(start_color, end_color, t); 190 return mix_okhsl(start_color, end_color, t); 192 return mix_okhsl_long(start_color, end_color, t); 195 return mix(start_color, end_color, t); 199fn convert_to_linear_rgba( 203 let rgb = oklch_to_linear_rgb(color.xyz); 205 let rgb = oklch_to_linear_rgb(color.xyz); 207 let rgb = okhsl_to_linear_rgb(color.xyz); 209 let rgb = okhsl_to_linear_rgb(color.xyz); 211 let rgb = hsv_to_linear_rgb(color.xyz); 213 let rgb = hsv_to_linear_rgb(color.xyz); 215 let rgb = hsl_to_linear_rgb(color.xyz); 217 let rgb = hsl_to_linear_rgb(color.xyz); 219 let rgb = oklab_to_linear_rgb(color.xyz); 221 let rgb = srgb_to_linear(color.xyz); 225 return vec4(rgb, color.a); 228fn interpolate_gradient( 230 start_color: vec4<f32>, 232 end_color: vec4<f32>, 237 if start_distance == end_distance { 238 if distance <= start_distance && enabled(flags, FILL_START) { 239 return convert_to_linear_rgba(start_color); 241 if start_distance <= distance && enabled(flags, FILL_END) { 242 return convert_to_linear_rgba(end_color); 247 var t = (distance - start_distance) / (end_distance - start_distance); 250 if enabled(flags, FILL_START) { 251 return convert_to_linear_rgba(start_color); 257 if enabled(flags, FILL_END) { 258 return convert_to_linear_rgba(end_color); 266 t = 0.5 * (1 + (t - hint) / (1.0 - hint)); 269 return convert_to_linear_rgba(vec4(mix_colors(start_color.xyz, end_color.xyz, t), mix(start_color.a, end_color.a, t)));