1
1
//! Wrapper for extending a `Material` with `rust-gpu` shader functionality.
2
2
3
- use std:: marker:: PhantomData ;
3
+ use std:: { any :: TypeId , marker:: PhantomData , sync :: RwLock } ;
4
4
5
5
use bevy:: {
6
6
pbr:: MaterialPipelineKey ,
@@ -9,8 +9,10 @@ use bevy::{
9
9
MaterialPlugin , Plugin , Shader ,
10
10
} ,
11
11
reflect:: TypeUuid ,
12
- render:: render_resource:: { AsBindGroup , PreparedBindGroup } ,
12
+ render:: render_resource:: { AsBindGroup , PreparedBindGroup , ShaderRef } ,
13
+ utils:: HashMap ,
13
14
} ;
15
+ use once_cell:: sync:: Lazy ;
14
16
15
17
use crate :: {
16
18
prelude:: { EntryPoint , Export , ExportHandle , RustGpuMaterial , SHADER_META } ,
@@ -25,6 +27,8 @@ const SHADER_DEFS: &[&'static str] = &[
25
27
"SIXTEEN_BYTE_ALIGNMENT" ,
26
28
] ;
27
29
30
+ static MATERIAL_SETTINGS : Lazy < RwLock < HashMap < TypeId , RustGpuSettings > > > = Lazy :: new ( default) ;
31
+
28
32
/// Configures backend support for [`RustGpu<M>`].
29
33
pub struct RustGpuMaterialPlugin < M >
30
34
where
63
67
}
64
68
}
65
69
70
+ /// Type-level RustGpu material settings
71
+ #[ derive( Debug , Default , Copy , Clone ) ]
72
+ pub struct RustGpuSettings {
73
+ /// If true, use M::vertex as a fallback instead of ShaderRef::default
74
+ pub fallback_base_vertex : bool ,
75
+ /// If true, use M::fragment as a fallback instead of ShaderRef::default
76
+ pub fallback_base_fragment : bool ,
77
+ }
78
+
66
79
/// [`RustGpu`] pipeline key.
67
80
pub struct RustGpuKey < M >
68
81
where
@@ -241,11 +254,29 @@ where
241
254
M : RustGpuMaterial ,
242
255
{
243
256
fn vertex_shader ( ) -> bevy:: render:: render_resource:: ShaderRef {
244
- M :: vertex_shader ( )
257
+ if let Some ( true ) = MATERIAL_SETTINGS
258
+ . read ( )
259
+ . unwrap ( )
260
+ . get ( & TypeId :: of :: < Self > ( ) )
261
+ . map ( |settings| settings. fallback_base_vertex )
262
+ {
263
+ M :: vertex_shader ( )
264
+ } else {
265
+ ShaderRef :: Default
266
+ }
245
267
}
246
268
247
269
fn fragment_shader ( ) -> bevy:: render:: render_resource:: ShaderRef {
248
- M :: fragment_shader ( )
270
+ if let Some ( true ) = MATERIAL_SETTINGS
271
+ . read ( )
272
+ . unwrap ( )
273
+ . get ( & TypeId :: of :: < Self > ( ) )
274
+ . map ( |settings| settings. fallback_base_vertex )
275
+ {
276
+ M :: fragment_shader ( )
277
+ } else {
278
+ ShaderRef :: Default
279
+ }
249
280
}
250
281
251
282
fn alpha_mode ( & self ) -> bevy:: prelude:: AlphaMode {
@@ -300,10 +331,13 @@ where
300
331
let metas = SHADER_META . read ( ) . unwrap ( ) ;
301
332
if let Some ( vertex_meta) = metas. get ( & vertex_shader) {
302
333
info ! ( "Vertex meta is valid" ) ;
334
+ info ! ( "Checking entry point {entry_point:}" ) ;
303
335
if !vertex_meta. entry_points . contains ( & entry_point) {
304
336
warn ! ( "Missing entry point {entry_point:}" ) ;
305
337
apply = false ;
306
338
}
339
+ } else {
340
+ apply = false ;
307
341
}
308
342
}
309
343
@@ -350,10 +384,13 @@ where
350
384
let metas = SHADER_META . read ( ) . unwrap ( ) ;
351
385
if let Some ( fragment_meta) = metas. get ( & fragment_shader) {
352
386
info ! ( "Fragment meta is valid" ) ;
387
+ info ! ( "Checking entry point {entry_point:}" ) ;
353
388
if !fragment_meta. entry_points . contains ( & entry_point) {
354
389
apply = false ;
355
390
warn ! ( "Missing entry point {entry_point:}, falling back to default fragment shader." ) ;
356
391
}
392
+ } else {
393
+ apply = false ;
357
394
}
358
395
}
359
396
@@ -384,3 +421,13 @@ where
384
421
Ok ( ( ) )
385
422
}
386
423
}
424
+
425
+ impl < M > RustGpu < M >
426
+ where
427
+ M : ' static ,
428
+ {
429
+ pub fn map_settings < F : FnOnce ( & mut RustGpuSettings ) > ( f : F ) {
430
+ let mut settings = MATERIAL_SETTINGS . write ( ) . unwrap ( ) ;
431
+ f ( & mut settings. entry ( TypeId :: of :: < Self > ( ) ) . or_default ( ) ) ;
432
+ }
433
+ }
0 commit comments