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 11 because the [`StandardMaterial`](https://docs.rs/bevy/latest/bevy/pbr/struct.StandardMaterial.html)
78    /// needs 11 draw functions by default
79    pub draw_functions: SmallVec<[(InternedDrawFunctionLabel, DrawFunctionId); 11]>,
80    /// Backing array is a size of 6 because the [`StandardMaterial`](https://docs.rs/bevy/latest/bevy/pbr/struct.StandardMaterial.html)
81    /// has 6 custom shaders (`frag`, `prepass_frag`, `deferred_frag`, `vertex`, `prepass_vertex`,
82    /// `deferred vertex`) which is the most common use case
83    pub shaders: SmallVec<[(InternedShaderLabel, Handle<Shader>); 6]>,
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    /// Whether OIT is enabled for this material
98    pub oit_enabled: bool,
99}
100
101impl MaterialProperties {
102    pub fn get_shader(&self, label: impl ShaderLabel) -> Option<Handle<Shader>> {
103        self.shaders
104            .iter()
105            .find(|(inner_label, _)| inner_label == &label.intern())
106            .map(|(_, shader)| shader)
107            .cloned()
108    }
109
110    pub fn add_shader(&mut self, label: impl ShaderLabel, shader: Handle<Shader>) {
111        self.shaders.push((label.intern(), shader));
112    }
113
114    pub fn get_draw_function(&self, label: impl DrawFunctionLabel) -> Option<DrawFunctionId> {
115        self.draw_functions
116            .iter()
117            .find(|(inner_label, _)| inner_label == &label.intern())
118            .map(|(_, shader)| shader)
119            .cloned()
120    }
121
122    pub fn add_draw_function(
123        &mut self,
124        label: impl DrawFunctionLabel,
125        draw_function: DrawFunctionId,
126    ) {
127        self.draw_functions.push((label.intern(), draw_function));
128    }
129}