diff --git a/assets/shaders/custom_ui_material.wgsl b/assets/shaders/custom_ui_material.wgsl index fa0344930d..2b7eb01e92 100644 --- a/assets/shaders/custom_ui_material.wgsl +++ b/assets/shaders/custom_ui_material.wgsl @@ -5,10 +5,21 @@ @group(1) @binding(1) var slider: f32; @group(1) @binding(2) var material_color_texture: texture_2d; @group(1) @binding(3) var material_color_sampler: sampler; +@group(1) @binding(4) var border_color: vec4; @fragment fn fragment(in: UiVertexOutput) -> @location(0) vec4 { + let r = in.uv - 0.5; + let b = vec2( + select(in.border_widths.x, in.border_widths.y, r.x < 0.), + select(in.border_widths.z, in.border_widths.w, r.y < 0.) + ); + + if any(0.5 - b < abs(r)) { + return border_color; + } + if in.uv.x < slider { let output_color = textureSample(material_color_texture, material_color_sampler, in.uv) * color; return output_color; diff --git a/examples/ui/ui_material.rs b/examples/ui/ui_material.rs index bfd06ad58f..6aacc9bb8d 100644 --- a/examples/ui/ui_material.rs +++ b/examples/ui/ui_material.rs @@ -42,12 +42,14 @@ fn setup( position_type: PositionType::Absolute, width: Val::Px(905.0 * banner_scale_factor), height: Val::Px(363.0 * banner_scale_factor), + border: UiRect::all(Val::Px(10.)), ..default() }, material: ui_materials.add(CustomUiMaterial { color: LinearRgba::WHITE.to_f32_array().into(), slider: 0.5, color_texture: asset_server.load("branding/banner.png"), + border_color: LinearRgba::WHITE.to_f32_array().into(), }), ..default() }); @@ -67,6 +69,9 @@ struct CustomUiMaterial { #[texture(2)] #[sampler(3)] color_texture: Handle, + /// Color of the image's border + #[uniform(4)] + border_color: Vec4, } impl UiMaterial for CustomUiMaterial { @@ -87,9 +92,11 @@ fn animate( if let Some(material) = materials.get_mut(handle) { // rainbow color effect let new_color = Color::hsl((time.elapsed_seconds() * 60.0) % 360.0, 1., 0.5); - material.color = LinearRgba::from(new_color).to_f32_array().into(); + let border_color = Color::hsl((time.elapsed_seconds() * 60.0) % 360.0, 0.75, 0.75); + material.color = new_color.to_linear().to_vec4(); material.slider = ((time.elapsed_seconds() % (duration * 2.0)) - duration).abs() / duration; + material.border_color = border_color.to_linear().to_vec4(); } } }