Skip to main content

bevy_material/
lib.rs

1//! Provides a material abstraction for bevy
2#![expect(missing_docs, reason = "Not all docs are written yet, see #3492.")]
3#![cfg_attr(
4    any(docsrs, docsrs_dep),
5    expect(
6        internal_features,
7        reason = "rustdoc_internals is needed for fake_variadic"
8    )
9)]
10#![cfg_attr(any(docsrs, docsrs_dep), feature(rustdoc_internals))]
11#![cfg_attr(docsrs, feature(doc_cfg))]
12#![doc(
13    html_logo_url = "https://bevy.org/assets/icon.png",
14    html_favicon_url = "https://bevy.org/assets/icon.png"
15)]
16
17use bevy_asset::Handle;
18use bevy_shader::Shader;
19use smallvec::SmallVec;
20
21extern crate alloc;
22
23use crate::{
24    descriptor::BindGroupLayoutDescriptor,
25    key::{ErasedMaterialKey, ErasedMeshPipelineKey},
26    labels::{
27        DrawFunctionId, DrawFunctionLabel, InternedDrawFunctionLabel, InternedShaderLabel,
28        ShaderLabel,
29    },
30    specialize::{BaseSpecializeFn, PrepassSpecializeFn, UserSpecializeFn},
31};
32
33pub use crate::{alpha::AlphaMode, opaque::OpaqueRendererMethod, phase::RenderPhaseType};
34
35mod alpha;
36pub mod bind_group_layout_entries;
37pub mod descriptor;
38pub mod key;
39pub mod labels;
40mod opaque;
41mod phase;
42pub mod specialize;
43
44/// The material prelude.
45///
46/// This includes the most common types in this crate, re-exported for your convenience.
47pub mod prelude {
48    pub use crate::alpha::AlphaMode;
49}
50
51/// Common material properties, calculated for a specific material instance.
52#[derive(Default)]
53pub struct MaterialProperties {
54    /// Is this material should be rendered by the deferred renderer when.
55    /// [`AlphaMode::Opaque`] or [`AlphaMode::Mask`]
56    pub render_method: OpaqueRendererMethod,
57    /// The [`AlphaMode`] of this material.
58    pub alpha_mode: AlphaMode,
59    /// The bits in the [`ErasedMeshPipelineKey`] for this material.
60    ///
61    /// These are precalculated so that we can just "or" them together in
62    /// [`queue_material_meshes`](https://docs.rs/bevy/latest/bevy/pbr/fn.queue_material_meshes.html).
63    pub mesh_pipeline_key_bits: ErasedMeshPipelineKey,
64    /// Add a bias to the view depth of the mesh which can be used to force a specific render order
65    /// for meshes with equal depth, to avoid z-fighting.
66    /// The bias is in depth-texture units so large values may be needed to overcome small depth differences.
67    pub depth_bias: f32,
68    /// Whether the material would like to read from
69    /// [`ViewTransmissionTexture`](https://docs.rs/bevy/latest/bevy/core_pipeline/core_3d/struct.ViewTransmissionTexture.html).
70    ///
71    /// This allows taking color output from the [`Opaque3d`](https://docs.rs/bevy/latest/bevy/core_pipeline/core_3d/struct.Opaque3d.html)
72    /// pass as an input, (for screen-space transmission) but requires rendering to take place in a separate
73    /// [`Transmissive3d`](https://docs.rs/bevy/latest/bevy/core_pipeline/core_3d/struct.Transmissive3d.html) pass.
74    pub reads_view_transmission_texture: bool,
75    pub render_phase_type: RenderPhaseType,
76    pub material_layout: Option<BindGroupLayoutDescriptor>,
77    /// Backing array is a size of 4 because the [`StandardMaterial`](https://docs.rs/bevy/latest/bevy/pbr/struct.StandardMaterial.html)
78    /// needs 4 draw functions by default
79    pub draw_functions: SmallVec<[(InternedDrawFunctionLabel, DrawFunctionId); 4]>,
80    /// Backing array is a size of 3 because the [`StandardMaterial`](https://docs.rs/bevy/latest/bevy/pbr/struct.StandardMaterial.html)
81    /// has 3 custom shaders (`frag`, `prepass_frag`, `deferred_frag`) which is the
82    /// most common use case
83    pub shaders: SmallVec<[(InternedShaderLabel, Handle<Shader>); 3]>,
84    /// Whether this material *actually* uses bindless resources, taking the
85    /// platform support (or lack thereof) of bindless resources into account.
86    pub bindless: bool,
87    pub base_specialize: Option<BaseSpecializeFn>,
88    pub prepass_specialize: Option<PrepassSpecializeFn>,
89    pub user_specialize: Option<UserSpecializeFn>,
90    /// The key for this material, typically a bitfield of flags that are used to modify
91    /// the pipeline descriptor used for this material.
92    pub material_key: ErasedMaterialKey,
93    /// Whether shadows are enabled for this material
94    pub shadows_enabled: bool,
95    /// Whether prepass is enabled for this material
96    pub prepass_enabled: bool,
97}
98
99impl MaterialProperties {
100    pub fn get_shader(&self, label: impl ShaderLabel) -> Option<Handle<Shader>> {
101        self.shaders
102            .iter()
103            .find(|(inner_label, _)| inner_label == &label.intern())
104            .map(|(_, shader)| shader)
105            .cloned()
106    }
107
108    pub fn add_shader(&mut self, label: impl ShaderLabel, shader: Handle<Shader>) {
109        self.shaders.push((label.intern(), shader));
110    }
111
112    pub fn get_draw_function(&self, label: impl DrawFunctionLabel) -> Option<DrawFunctionId> {
113        self.draw_functions
114            .iter()
115            .find(|(inner_label, _)| inner_label == &label.intern())
116            .map(|(_, shader)| shader)
117            .cloned()
118    }
119
120    pub fn add_draw_function(
121        &mut self,
122        label: impl DrawFunctionLabel,
123        draw_function: DrawFunctionId,
124    ) {
125        self.draw_functions.push((label.intern(), draw_function));
126    }
127}