1#![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
44pub mod prelude {
48 pub use crate::alpha::AlphaMode;
49}
50
51#[derive(Default)]
53pub struct MaterialProperties {
54 pub render_method: OpaqueRendererMethod,
57 pub alpha_mode: AlphaMode,
59 pub mesh_pipeline_key_bits: ErasedMeshPipelineKey,
64 pub depth_bias: f32,
68 pub reads_view_transmission_texture: bool,
75 pub render_phase_type: RenderPhaseType,
76 pub material_layout: Option<BindGroupLayoutDescriptor>,
77 pub draw_functions: SmallVec<[(InternedDrawFunctionLabel, DrawFunctionId); 4]>,
80 pub shaders: SmallVec<[(InternedShaderLabel, Handle<Shader>); 3]>,
84 pub bindless: bool,
87 pub base_specialize: Option<BaseSpecializeFn>,
88 pub prepass_specialize: Option<PrepassSpecializeFn>,
89 pub user_specialize: Option<UserSpecializeFn>,
90 pub material_key: ErasedMaterialKey,
93 pub shadows_enabled: bool,
95 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}