Add a border to the UI material example (#15120)

# Objective

There aren't any examples of how to draw a ui material with borders.

## Solution

Add border rendering to the `ui_material` example's shader.

## Showcase

<img width="395" alt="bordermat"
src="https://github.com/user-attachments/assets/109c59c1-f54b-4542-96f7-acff63f5057f">

---------

Co-authored-by: charlotte <charlotte.c.mcelwain@gmail.com>
This commit is contained in:
ickshonpe 2024-09-09 17:34:24 +01:00 committed by GitHub
parent 79f6fcd1eb
commit 09d2292016
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 19 additions and 1 deletions

View file

@ -5,10 +5,21 @@
@group(1) @binding(1) var<uniform> slider: f32;
@group(1) @binding(2) var material_color_texture: texture_2d<f32>;
@group(1) @binding(3) var material_color_sampler: sampler;
@group(1) @binding(4) var<uniform> border_color: vec4<f32>;
@fragment
fn fragment(in: UiVertexOutput) -> @location(0) vec4<f32> {
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;

View file

@ -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<Image>,
/// 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();
}
}
}