pub trait Material: Asset + AsBindGroup + Clone + Sized {
// Provided methods
fn vertex_shader() -> ShaderRef { ... }
fn fragment_shader() -> ShaderRef { ... }
fn alpha_mode(&self) -> AlphaMode { ... }
fn opaque_render_method(&self) -> OpaqueRendererMethod { ... }
fn depth_bias(&self) -> f32 { ... }
fn reads_view_transmission_texture(&self) -> bool { ... }
fn prepass_vertex_shader() -> ShaderRef { ... }
fn prepass_fragment_shader() -> ShaderRef { ... }
fn deferred_vertex_shader() -> ShaderRef { ... }
fn deferred_fragment_shader() -> ShaderRef { ... }
fn specialize(
pipeline: &MaterialPipeline<Self>,
descriptor: &mut RenderPipelineDescriptor,
layout: &MeshVertexBufferLayout,
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.
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, Debug, Clone, Asset, TypePath)]
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:
@group(2) @binding(0) var<uniform> color: vec4<f32>;
@group(2) @binding(1) var color_texture: texture_2d<f32>;
@group(2) @binding(2) var color_sampler: sampler;
Provided Methods§
sourcefn 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.
sourcefn 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.
sourcefn alpha_mode(&self) -> AlphaMode
fn alpha_mode(&self) -> AlphaMode
Returns this material’s AlphaMode
. Defaults to AlphaMode::Opaque
.
sourcefn opaque_render_method(&self) -> OpaqueRendererMethod
fn opaque_render_method(&self) -> OpaqueRendererMethod
Returns if this material should be rendered by the deferred or forward renderer.
for AlphaMode::Opaque
or AlphaMode::Mask
materials.
If OpaqueRendererMethod::Auto
, it will default to what is selected in the DefaultOpaqueRendererMethod
resource.
sourcefn 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 similar depth, to avoid z-fighting. The bias is in depth-texture units so large values may be needed to overcome small depth differences.
sourcefn reads_view_transmission_texture(&self) -> bool
fn reads_view_transmission_texture(&self) -> bool
Returns whether the material would like to read from ViewTransmissionTexture
.
This allows taking color output from the Opaque3d
pass as an input, (for screen-space transmission) but requires
rendering to take place in a separate Transmissive3d
pass.
sourcefn prepass_vertex_shader() -> ShaderRef
fn prepass_vertex_shader() -> ShaderRef
Returns this material’s prepass vertex shader. If ShaderRef::Default
is returned, the default prepass vertex shader
will be used.
This is used for the various prepasses as well as for generating the depth maps required for shadow mapping.
sourcefn prepass_fragment_shader() -> ShaderRef
fn prepass_fragment_shader() -> ShaderRef
Returns this material’s prepass fragment shader. If ShaderRef::Default
is returned, the default prepass fragment shader
will be used.
This is used for the various prepasses as well as for generating the depth maps required for shadow mapping.
sourcefn deferred_vertex_shader() -> ShaderRef
fn deferred_vertex_shader() -> ShaderRef
Returns this material’s deferred vertex shader. If ShaderRef::Default
is returned, the default deferred vertex shader
will be used.
sourcefn deferred_fragment_shader() -> ShaderRef
fn deferred_fragment_shader() -> ShaderRef
Returns this material’s deferred fragment shader. If ShaderRef::Default
is returned, the default deferred fragment shader
will be used.
sourcefn specialize(
pipeline: &MaterialPipeline<Self>,
descriptor: &mut RenderPipelineDescriptor,
layout: &MeshVertexBufferLayout,
key: MaterialPipelineKey<Self>
) -> Result<(), SpecializedMeshPipelineError>
fn specialize( pipeline: &MaterialPipeline<Self>, descriptor: &mut RenderPipelineDescriptor, layout: &MeshVertexBufferLayout, key: MaterialPipelineKey<Self> ) -> Result<(), SpecializedMeshPipelineError>
Customizes the default RenderPipelineDescriptor
for a specific entity using the entity’s
MaterialPipelineKey
and MeshVertexBufferLayout
as input.