1+ use crate :: alpha:: AlphaMode ;
2+ use crate :: opaque:: OpaqueRendererMethod ;
3+ use crate :: render:: MeshPipeline ;
14use crate :: render:: MeshPipelineKey ;
5+ use crate :: render_phase:: {
6+ DrawFunctionId , DrawFunctionLabel , InternedDrawFunctionLabel , InternedShaderLabel , ShaderLabel ,
7+ } ;
8+ use crate :: render_resource:: {
9+ BindGroupLayoutDescriptor , RenderPipelineDescriptor , SpecializedMeshPipelineError ,
10+ } ;
211use crate :: * ;
312use alloc:: sync:: Arc ;
13+ use bevy_asset:: Handle ;
14+ use bevy_ecs:: resource:: Resource ;
15+ use bevy_mesh:: MeshVertexBufferLayoutRef ;
416use bevy_platform:: hash:: FixedHasher ;
17+ use bevy_shader:: Shader ;
518use core:: any:: { Any , TypeId } ;
6- use core:: hash:: { BuildHasher , Hasher } ;
719use core:: hash:: Hash ;
20+ use core:: hash:: { BuildHasher , Hasher } ;
21+ use smallvec:: SmallVec ;
822
923pub const MATERIAL_BIND_GROUP_INDEX : usize = 3 ;
1024
25+ /// Render pipeline data for a given material.
26+ #[ derive( Resource , Clone ) ]
27+ pub struct MaterialPipeline {
28+ pub mesh_pipeline : MeshPipeline ,
29+ }
30+
1131#[ derive( Clone , Debug , PartialEq , Eq , Hash ) ]
1232pub struct ErasedMaterialPipelineKey {
1333 pub mesh_key : MeshPipelineKey ,
@@ -94,7 +114,83 @@ impl Default for ErasedMaterialKey {
94114 }
95115}
96116
97- // pub struct MaterialProperties {
117+ /// Common material properties, calculated for a specific material instance.
118+ #[ derive( Default ) ]
119+ pub struct MaterialProperties {
120+ /// Is this material should be rendered by the deferred renderer when.
121+ /// [`AlphaMode::Opaque`] or [`AlphaMode::Mask`]
122+ pub render_method : OpaqueRendererMethod ,
123+ /// The [`AlphaMode`] of this material.
124+ pub alpha_mode : AlphaMode ,
125+ /// The bits in the [`MeshPipelineKey`] for this material.
126+ ///
127+ /// These are precalculated so that we can just "or" them together.
128+ pub mesh_pipeline_key_bits : MeshPipelineKey ,
129+ /// Add a bias to the view depth of the mesh which can be used to force a specific render order
130+ /// for meshes with equal depth, to avoid z-fighting.
131+ /// The bias is in depth-texture units so large values may be needed to overcome small depth differences.
132+ pub depth_bias : f32 ,
133+ /// Whether the material would like to read from a view transmission texture
134+ ///
135+ /// This allows taking color output from the opaque 3d pass as an input, (for screen-space transmission) but requires
136+ /// rendering to take place in a separate transmissive 3d pass.
137+ pub reads_view_transmission_texture : bool ,
138+ pub render_phase_type : RenderPhaseType ,
139+ pub material_layout : Option < BindGroupLayoutDescriptor > ,
140+ /// Backing array is a size of 4 because the `StandardMaterial` needs 4 draw functions by default
141+ pub draw_functions : SmallVec < [ ( InternedDrawFunctionLabel , DrawFunctionId ) ; 4 ] > ,
142+ /// Backing array is a size of 3 because the `StandardMaterial` has 3 custom shaders (`frag`, `prepass_frag`, `deferred_frag`) which is the
143+ /// most common use case
144+ pub shaders : SmallVec < [ ( InternedShaderLabel , Handle < Shader > ) ; 3 ] > ,
145+ /// Whether this material *actually* uses bindless resources, taking the
146+ /// platform support (or lack thereof) of bindless resources into account.
147+ pub bindless : bool ,
148+ pub specialize : Option <
149+ fn (
150+ & MaterialPipeline ,
151+ & mut RenderPipelineDescriptor ,
152+ & MeshVertexBufferLayoutRef ,
153+ ErasedMaterialPipelineKey ,
154+ ) -> Result < ( ) , SpecializedMeshPipelineError > ,
155+ > ,
156+ /// The key for this material, typically a bitfield of flags that are used to modify
157+ /// the pipeline descriptor used for this material.
158+ pub material_key : ErasedMaterialKey ,
159+ /// Whether shadows are enabled for this material
160+ pub shadows_enabled : bool ,
161+ /// Whether prepass is enabled for this material
162+ pub prepass_enabled : bool ,
163+ }
164+
165+ impl MaterialProperties {
166+ pub fn get_shader ( & self , label : impl ShaderLabel ) -> Option < Handle < Shader > > {
167+ self . shaders
168+ . iter ( )
169+ . find ( |( inner_label, _) | inner_label == & label. intern ( ) )
170+ . map ( |( _, shader) | shader)
171+ . cloned ( )
172+ }
173+
174+ pub fn add_shader ( & mut self , label : impl ShaderLabel , shader : Handle < Shader > ) {
175+ self . shaders . push ( ( label. intern ( ) , shader) ) ;
176+ }
177+
178+ pub fn get_draw_function ( & self , label : impl DrawFunctionLabel ) -> Option < DrawFunctionId > {
179+ self . draw_functions
180+ . iter ( )
181+ . find ( |( inner_label, _) | inner_label == & label. intern ( ) )
182+ . map ( |( _, shader) | shader)
183+ . cloned ( )
184+ }
185+
186+ pub fn add_draw_function (
187+ & mut self ,
188+ label : impl DrawFunctionLabel ,
189+ draw_function : DrawFunctionId ,
190+ ) {
191+ self . draw_functions . push ( ( label. intern ( ) , draw_function) ) ;
192+ }
193+ }
98194
99195#[ derive( Clone , Copy , Default ) ]
100196pub enum RenderPhaseType {
@@ -104,4 +200,3 @@ pub enum RenderPhaseType {
104200 Transmissive ,
105201 Transparent ,
106202}
107-
0 commit comments