@@ -50,8 +50,9 @@ use crate::render::material::UntypedMaterial;
5050#[ derive( Asset , TypePath , Clone ) ]
5151pub struct CustomMaterial {
5252 pub shader : DynamicShader ,
53- pub vertex_shader : Option < Handle < ShaderAsset > > ,
54- pub fragment_shader : Option < Handle < ShaderAsset > > ,
53+ pub shader_handle : Handle < ShaderAsset > ,
54+ pub has_vertex : bool ,
55+ pub has_fragment : bool ,
5556}
5657
5758#[ derive( Component ) ]
@@ -197,34 +198,35 @@ pub fn destroy_shader(In(entity): In<Entity>, mut commands: Commands) -> Result<
197198}
198199
199200pub fn create_custom (
200- In ( ( vertex_entity , fragment_entity ) ) : In < ( Option < Entity > , Option < Entity > ) > ,
201+ In ( shader_entity ) : In < Entity > ,
201202 mut commands : Commands ,
202203 shader_programs : Query < & Shader > ,
203204 mut custom_materials : ResMut < Assets < CustomMaterial > > ,
204205) -> Result < Entity > {
205- let vertex_program = vertex_entity
206- . map ( |e| shader_programs. get ( e) )
207- . transpose ( )
208- . map_err ( |_| ProcessingError :: ShaderNotFound ) ?;
209- let fragment_program = fragment_entity
210- . map ( |e| shader_programs. get ( e) )
211- . transpose ( )
206+ let program = shader_programs
207+ . get ( shader_entity)
212208 . map_err ( |_| ProcessingError :: ShaderNotFound ) ?;
213209
214- // Prefer fragment module for reflection, fall back to vertex.
215- let reflection_module = fragment_program
216- . map ( |p| & p. module )
217- . or ( vertex_program. map ( |p| & p. module ) )
218- . ok_or ( ProcessingError :: ShaderNotFound ) ?;
219-
220- let mut shader = DynamicShader :: new ( reflection_module. clone ( ) )
210+ let has_vertex = program
211+ . module
212+ . entry_points
213+ . iter ( )
214+ . any ( |ep| ep. stage == naga:: ShaderStage :: Vertex ) ;
215+ let has_fragment = program
216+ . module
217+ . entry_points
218+ . iter ( )
219+ . any ( |ep| ep. stage == naga:: ShaderStage :: Fragment ) ;
220+
221+ let mut shader = DynamicShader :: new ( program. module . clone ( ) )
221222 . map_err ( |e| ProcessingError :: ShaderCompilationError ( e. to_string ( ) ) ) ?;
222223 shader. init ( ) ;
223224
224225 let material = CustomMaterial {
225226 shader,
226- vertex_shader : vertex_program. map ( |p| p. shader_handle . clone ( ) ) ,
227- fragment_shader : fragment_program. map ( |p| p. shader_handle . clone ( ) ) ,
227+ shader_handle : program. shader_handle . clone ( ) ,
228+ has_vertex,
229+ has_fragment,
228230 } ;
229231 let handle = custom_materials. add ( material) ;
230232 Ok ( commands. spawn ( UntypedMaterial ( handle. untyped ( ) ) ) . id ( ) )
@@ -401,11 +403,11 @@ impl ErasedRenderAsset for CustomMaterial {
401403 ..Default :: default ( )
402404 } ;
403405 properties. add_draw_function ( MainPassOpaqueDrawFunction , draw_function) ;
404- if let Some ( vertex ) = & source_asset. vertex_shader {
405- properties. add_shader ( MaterialVertexShader , vertex . clone ( ) ) ;
406+ if source_asset. has_vertex {
407+ properties. add_shader ( MaterialVertexShader , source_asset . shader_handle . clone ( ) ) ;
406408 }
407- if let Some ( fragment ) = & source_asset. fragment_shader {
408- properties. add_shader ( MaterialFragmentShader , fragment . clone ( ) ) ;
409+ if source_asset. has_fragment {
410+ properties. add_shader ( MaterialFragmentShader , source_asset . shader_handle . clone ( ) ) ;
409411 }
410412
411413 Ok ( PreparedMaterial {
0 commit comments