pub trait Material: 'static + AsBindGroup + Send + Sync + Clone + TypeUuid + Sized {
fn vertex_shader() -> ShaderRef { ... }
fn fragment_shader() -> ShaderRef { ... }
fn alpha_mode(&self) -> AlphaMode { ... }
fn depth_bias(&self) -> f32 { ... }
fn specialize(
pipeline: &MaterialPipeline<Self>,
descriptor: &mut RenderPipelineDescriptor,
layout: &Hashed<InnerMeshVertexBufferLayout, FixedState>,
key: MaterialPipelineKey<Self>
) -> Result<(), SpecializedMeshPipelineError> { ... }
}
Expand description
Materials are used alongside MaterialPlugin
and MaterialMeshBundle
to spawn entities that are rendered with a specific Material
type. They serve as an easy to use high level
way to render Mesh
entities with custom shader logic.
Materials 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 TypeUuid
so they can be treated as an Asset
.
Example
Here is a simple Material implementation. The AsBindGroup
derive has many features. To see what else is available,
check out the AsBindGroup
documentation.
#[derive(AsBindGroup, TypeUuid, Debug, Clone)]
#[uuid = "f690fdae-d598-45ab-8225-97e2a3f056e0"]
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 `Material` have default impls. You only need to implement the
// functions that are relevant for your material.
impl Material 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(MaterialMeshBundle {
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:
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;
Provided Methods§
fn vertex_shader() -> ShaderRef
fn vertex_shader() -> ShaderRef
Returns this material’s vertex shader. If ShaderRef::Default
is returned, the default mesh vertex shader
will be used.
fn fragment_shader() -> ShaderRef
fn fragment_shader() -> ShaderRef
Returns this material’s fragment shader. If ShaderRef::Default
is returned, the default mesh fragment shader
will be used.
fn alpha_mode(&self) -> AlphaMode
fn alpha_mode(&self) -> AlphaMode
Returns this material’s AlphaMode
. Defaults to AlphaMode::Opaque
.
fn depth_bias(&self) -> f32
fn depth_bias(&self) -> f32
Add a bias to the view depth of the mesh which can be used to force a specific render order for meshes with equal depth, to avoid z-fighting.
fn specialize(
pipeline: &MaterialPipeline<Self>,
descriptor: &mut RenderPipelineDescriptor,
layout: &Hashed<InnerMeshVertexBufferLayout, FixedState>,
key: MaterialPipelineKey<Self>
) -> Result<(), SpecializedMeshPipelineError>
fn specialize(
pipeline: &MaterialPipeline<Self>,
descriptor: &mut RenderPipelineDescriptor,
layout: &Hashed<InnerMeshVertexBufferLayout, FixedState>,
key: MaterialPipelineKey<Self>
) -> Result<(), SpecializedMeshPipelineError>
Customizes the default RenderPipelineDescriptor
for a specific entity using the entity’s
MaterialPipelineKey
and MeshVertexBufferLayout
as input.