@@ -11,17 +11,23 @@ wesl::wesl_pkg!(lygia);
1111
1212use bevy:: {
1313 asset:: { AsAssetId , AssetEventSystems } ,
14- core_pipeline:: core_3d:: Opaque3d ,
14+ core_pipeline:: core_3d:: { Opaque3d , Transparent3d } ,
1515 ecs:: system:: {
1616 SystemParamItem ,
1717 lifetimeless:: { SRes , SResMut } ,
1818 } ,
19- material:: { MaterialProperties , key:: ErasedMeshPipelineKey } ,
19+ material:: {
20+ MaterialProperties ,
21+ descriptor:: RenderPipelineDescriptor ,
22+ key:: { ErasedMaterialKey , ErasedMaterialPipelineKey , ErasedMeshPipelineKey } ,
23+ specialize:: SpecializedMeshPipelineError ,
24+ } ,
25+ mesh:: MeshVertexBufferLayoutRef ,
2026 pbr:: {
2127 DrawMaterial , EntitiesNeedingSpecialization , MainPassOpaqueDrawFunction ,
22- MaterialBindGroupAllocator , MaterialBindGroupAllocators , MaterialFragmentShader ,
23- MaterialVertexShader , MeshPipelineKey , PreparedMaterial , RenderMaterialBindings ,
24- RenderMaterialInstance , RenderMaterialInstances , base_specialize,
28+ MainPassTransparentDrawFunction , MaterialBindGroupAllocator , MaterialBindGroupAllocators ,
29+ MaterialFragmentShader , MaterialVertexShader , MeshPipelineKey , PreparedMaterial ,
30+ RenderMaterialBindings , RenderMaterialInstance , RenderMaterialInstances , base_specialize,
2531 } ,
2632 prelude:: * ,
2733 reflect:: { PartialReflect , ReflectMut , ReflectRef , structs:: Struct } ,
@@ -31,7 +37,9 @@ use bevy::{
3137 erased_render_asset:: { ErasedRenderAsset , ErasedRenderAssetPlugin , PrepareAssetError } ,
3238 render_asset:: RenderAssets ,
3339 render_phase:: DrawFunctions ,
34- render_resource:: { BindGroupLayoutDescriptor , BindingResources , UnpreparedBindGroup } ,
40+ render_resource:: {
41+ BindGroupLayoutDescriptor , BindingResources , BlendState , UnpreparedBindGroup ,
42+ } ,
3543 renderer:: RenderDevice ,
3644 sync_world:: MainEntity ,
3745 texture:: GpuImage ,
@@ -42,17 +50,43 @@ use bevy_naga_reflect::dynamic_shader::DynamicShader;
4250
4351use bevy:: shader:: Shader as ShaderAsset ;
4452
53+ use std:: any:: Any ;
54+
4555use crate :: material:: MaterialValue ;
4656use crate :: render:: material:: UntypedMaterial ;
4757use processing_core:: config:: { Config , ConfigKey } ;
4858use processing_core:: error:: { ProcessingError , Result } ;
4959
60+ #[ derive( Clone , Hash , PartialEq ) ]
61+ struct CustomMaterialKey {
62+ blend_state : Option < BlendState > ,
63+ }
64+
65+ fn custom_blend_specialize (
66+ key : & dyn Any ,
67+ descriptor : & mut RenderPipelineDescriptor ,
68+ _layout : & MeshVertexBufferLayoutRef ,
69+ _pipeline_key : ErasedMaterialPipelineKey ,
70+ ) -> std:: result:: Result < ( ) , SpecializedMeshPipelineError > {
71+ if let Some ( key) = key. downcast_ref :: < CustomMaterialKey > ( ) {
72+ if let Some ( blend_state) = key. blend_state {
73+ if let Some ( fragment_state) = & mut descriptor. fragment {
74+ for target in fragment_state. targets . iter_mut ( ) . flatten ( ) {
75+ target. blend = Some ( blend_state) ;
76+ }
77+ }
78+ }
79+ }
80+ Ok ( ( ) )
81+ }
82+
5083#[ derive( Asset , TypePath , Clone ) ]
5184pub struct CustomMaterial {
5285 pub shader : DynamicShader ,
5386 pub shader_handle : Handle < ShaderAsset > ,
5487 pub has_vertex : bool ,
5588 pub has_fragment : bool ,
89+ pub blend_state : Option < bevy:: render:: render_resource:: BlendState > ,
5690}
5791
5892#[ derive( Component ) ]
@@ -227,6 +261,7 @@ pub fn create_custom(
227261 shader_handle : program. shader_handle . clone ( ) ,
228262 has_vertex,
229263 has_fragment,
264+ blend_state : None ,
230265 } ;
231266 let handle = custom_materials. add ( material) ;
232267 Ok ( commands. spawn ( UntypedMaterial ( handle. untyped ( ) ) ) . id ( ) )
@@ -393,13 +428,22 @@ impl ErasedRenderAsset for CustomMaterial {
393428
394429 let draw_function = opaque_draw_functions. read ( ) . id :: < DrawMaterial > ( ) ;
395430
431+ let blend_state = source_asset. blend_state ;
396432 let mut properties = MaterialProperties {
397433 mesh_pipeline_key_bits : ErasedMeshPipelineKey :: new ( MeshPipelineKey :: empty ( ) ) ,
398434 base_specialize : Some ( base_specialize) ,
399435 material_layout : Some ( bind_group_layout) ,
436+ material_key : ErasedMaterialKey :: new ( CustomMaterialKey { blend_state } ) ,
437+ user_specialize : Some ( custom_blend_specialize) ,
438+ alpha_mode : if blend_state. is_some ( ) {
439+ AlphaMode :: Blend
440+ } else {
441+ AlphaMode :: Opaque
442+ } ,
400443 ..Default :: default ( )
401444 } ;
402445 properties. add_draw_function ( MainPassOpaqueDrawFunction , draw_function) ;
446+ properties. add_draw_function ( MainPassTransparentDrawFunction , draw_function) ;
403447 if source_asset. has_vertex {
404448 properties. add_shader ( MaterialVertexShader , source_asset. shader_handle . clone ( ) ) ;
405449 }
0 commit comments