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