bevy/examples/ui/ui_material.rs
Markus Ort fd232ad360
Add UI Materials (#9506)
# Objective

- Add Ui Materials so that UI can render more complex and animated
widgets.
- Fixes #5607 

## Solution
- Create a UiMaterial trait for specifying a Shader Asset and Bind Group
Layout/Data.
- Create a pipeline for rendering these Materials inside the Ui
layout/tree.
- Create a MaterialNodeBundle for simple spawning.

## Changelog

- Created a `UiMaterial` trait for specifying a Shader asset and Bind
Group.
- Created a `UiMaterialPipeline` for rendering said Materials.
- Added Example [`ui_material`
](https://github.com/MarkusTheOrt/bevy/blob/ui_material/examples/ui/ui_material.rs)
for example usage.
- Created
[`UiVertexOutput`](https://github.com/MarkusTheOrt/bevy/blob/ui_material/crates/bevy_ui/src/render/ui_vertex_output.wgsl)
export as VertexData for shaders.
- Created
[`material_ui`](https://github.com/MarkusTheOrt/bevy/blob/ui_material/crates/bevy_ui/src/render/ui_material.wgsl)
shader as default for both Vertex and Fragment shaders.

---------

Co-authored-by: ickshonpe <david.curthoys@googlemail.com>
Co-authored-by: François <mockersf@gmail.com>
2023-11-03 22:33:01 +00:00

65 lines
1.9 KiB
Rust

//! Demonstrates the use of [`UiMaterials`](UiMaterial) and how to change material values
use bevy::prelude::*;
use bevy::reflect::TypePath;
use bevy::render::render_resource::*;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(UiMaterialPlugin::<CustomUiMaterial>::default())
.add_systems(Startup, setup)
.add_systems(Update, update)
.run();
}
fn update(time: Res<Time>, mut ui_materials: ResMut<Assets<CustomUiMaterial>>) {
for (_, material) in ui_materials.iter_mut() {
// rainbow color effect
let new_color = Color::hsl((time.elapsed_seconds() * 60.0) % 360.0, 1., 0.5);
material.color = new_color.into();
}
}
fn setup(mut commands: Commands, mut ui_materials: ResMut<Assets<CustomUiMaterial>>) {
// Camera so we can see UI
commands.spawn(Camera2dBundle::default());
commands
.spawn(NodeBundle {
style: Style {
width: Val::Percent(100.0),
height: Val::Percent(100.0),
align_items: AlignItems::Center,
justify_content: JustifyContent::Center,
..default()
},
..default()
})
.with_children(|parent| {
parent.spawn(MaterialNodeBundle {
style: Style {
position_type: PositionType::Absolute,
width: Val::Px(250.0),
height: Val::Px(250.0),
..default()
},
material: ui_materials.add(CustomUiMaterial {
color: Color::WHITE.into(),
}),
..default()
});
});
}
#[derive(AsBindGroup, Asset, TypePath, Debug, Clone)]
struct CustomUiMaterial {
#[uniform(0)]
color: Vec4,
}
impl UiMaterial for CustomUiMaterial {
fn fragment_shader() -> ShaderRef {
"shaders/circle_shader.wgsl".into()
}
}