Trait bevy_ui::ui_material::UiMaterial
source · pub trait UiMaterial: AsBindGroup + Asset + Clone + Sized {
// Provided methods
fn vertex_shader() -> ShaderRef { ... }
fn fragment_shader() -> ShaderRef { ... }
fn specialize(
descriptor: &mut RenderPipelineDescriptor,
key: UiMaterialKey<Self>
) { ... }
}
Expand description
Materials are used alongside UiMaterialPlugin
and MaterialNodeBundle
to spawn entities that are rendered with a specific UiMaterial
type. They serve as an easy to use high level
way to render Node
entities with custom shader logic.
UiMaterials
must implement AsBindGroup
to define how data will be transferred to the GPU and bound in shaders.
AsBindGroup
can be derived, which makes generating bindings straightforward. See the AsBindGroup
docs for details.
Materials must also implement Asset
so they can be treated as such.
If you are only using the fragment shader, make sure your shader imports the UiVertexOutput
from bevy_ui::ui_vertex_output
and uses it as the input of your fragment shader like the
example below does.
Example
Here is a simple UiMaterial
implementation. The AsBindGroup
derive has many features. To see what else is available,
check out the AsBindGroup
documentation.
#[derive(AsBindGroup, Asset, TypePath, Debug, Clone)]
pub struct CustomMaterial {
// Uniform bindings must implement `ShaderType`, which will be used to convert the value to
// its shader-compatible equivalent. Most core math types already implement `ShaderType`.
#[uniform(0)]
color: Color,
// Images can be bound as textures in shaders. If the Image's sampler is also needed, just
// add the sampler attribute with a different binding index.
#[texture(1)]
#[sampler(2)]
color_texture: Handle<Image>,
}
// All functions on `UiMaterial` have default impls. You only need to implement the
// functions that are relevant for your material.
impl UiMaterial for CustomMaterial {
fn fragment_shader() -> ShaderRef {
"shaders/custom_material.wgsl".into()
}
}
// Spawn an entity using `CustomMaterial`.
fn setup(mut commands: Commands, mut materials: ResMut<Assets<CustomMaterial>>, asset_server: Res<AssetServer>) {
commands.spawn(MaterialNodeBundle {
style: Style {
width: Val::Percent(100.0),
..Default::default()
},
material: materials.add(CustomMaterial {
color: Color::RED,
color_texture: asset_server.load("some_image.png"),
}),
..Default::default()
});
}
In WGSL shaders, the material’s binding would look like this:
If you only use the fragment shader make sure to import UiVertexOutput
from
bevy_ui::ui_vertex_output
in your wgsl shader.
Also note that bind group 0 is always bound to the View Uniform
and the Globals Uniform
.
#import bevy_ui::ui_vertex_output UiVertexOutput
struct CustomMaterial {
color: vec4<f32>,
}
@group(1) @binding(0)
var<uniform> material: CustomMaterial;
@group(1) @binding(1)
var color_texture: texture_2d<f32>;
@group(1) @binding(2)
var color_sampler: sampler;
@fragment
fn fragment(in: UiVertexOutput) -> @location(0) vec4<f32> {
}
Provided Methods§
sourcefn vertex_shader() -> ShaderRef
fn vertex_shader() -> ShaderRef
Returns this materials vertex shader. If ShaderRef::Default
is returned, the default UI
vertex shader will be used.
sourcefn fragment_shader() -> ShaderRef
fn fragment_shader() -> ShaderRef
Returns this materials fragment shader. If ShaderRef::Default
is returned, the default
UI fragment shader will be used.