1
+ #![ cfg_attr( target_arch = "spirv" , no_std) ]
2
+ #![ allow( clippy:: missing_safety_doc) ]
3
+
4
+ use spirv_std:: { spirv, glam:: { mat3, vec3, vec4, Mat3 , Mat4 , Vec2 , Vec3 , Vec4 } , Image , num_traits:: Float } ;
5
+ use spirv_std:: image:: SampledImage ;
6
+
7
+ #[ repr( C ) ]
8
+ #[ derive( Copy , Clone ) ]
9
+ pub struct UboScene {
10
+ pub projection : Mat4 ,
11
+ pub view : Mat4 ,
12
+ pub light_pos : Vec4 ,
13
+ pub view_pos : Vec4 ,
14
+ }
15
+
16
+ #[ repr( C ) ]
17
+ #[ derive( Copy , Clone ) ]
18
+ pub struct PushConsts {
19
+ pub model : Mat4 ,
20
+ }
21
+
22
+ #[ spirv( vertex) ]
23
+ pub fn main_vs (
24
+ in_pos : Vec3 ,
25
+ in_normal : Vec3 ,
26
+ in_uv : Vec2 ,
27
+ in_color : Vec3 ,
28
+ in_tangent : Vec4 ,
29
+ #[ spirv( uniform, descriptor_set = 0 , binding = 0 ) ] ubo_scene : & UboScene ,
30
+ #[ spirv( push_constant) ] push_consts : & PushConsts ,
31
+ #[ spirv( position) ] out_position : & mut Vec4 ,
32
+ out_normal : & mut Vec3 ,
33
+ out_color : & mut Vec3 ,
34
+ out_uv : & mut Vec2 ,
35
+ out_view_vec : & mut Vec3 ,
36
+ out_light_vec : & mut Vec3 ,
37
+ out_tangent : & mut Vec4 ,
38
+ ) {
39
+ * out_normal = in_normal;
40
+ * out_color = in_color;
41
+ * out_uv = in_uv;
42
+ * out_tangent = in_tangent;
43
+ * out_position = ubo_scene. projection * ubo_scene. view * push_consts. model * vec4 ( in_pos. x , in_pos. y , in_pos. z , 1.0 ) ;
44
+
45
+ let model_mat3 = mat3 (
46
+ push_consts. model . x_axis . truncate ( ) ,
47
+ push_consts. model . y_axis . truncate ( ) ,
48
+ push_consts. model . z_axis . truncate ( ) ,
49
+ ) ;
50
+ * out_normal = model_mat3 * in_normal;
51
+ let pos = push_consts. model * vec4 ( in_pos. x , in_pos. y , in_pos. z , 1.0 ) ;
52
+ * out_light_vec = ubo_scene. light_pos . truncate ( ) - pos. truncate ( ) ;
53
+ * out_view_vec = ubo_scene. view_pos . truncate ( ) - pos. truncate ( ) ;
54
+ }
55
+
56
+ #[ cfg_attr( target_arch = "spirv" , spirv( fragment) ) ]
57
+ pub fn main_fs (
58
+ in_normal : Vec3 ,
59
+ in_color : Vec3 ,
60
+ in_uv : Vec2 ,
61
+ in_view_vec : Vec3 ,
62
+ in_light_vec : Vec3 ,
63
+ in_tangent : Vec4 ,
64
+ #[ spirv( descriptor_set = 1 , binding = 0 ) ] sampler_color_map : & SampledImage < Image ! ( 2 D , type =f32 , sampled) > ,
65
+ #[ spirv( descriptor_set = 1 , binding = 1 ) ] sampler_normal_map : & SampledImage < Image ! ( 2 D , type =f32 , sampled) > ,
66
+ #[ spirv( spec_constant( id = 0 , default = 0 ) ) ] alpha_mask : u32 ,
67
+ #[ spirv( spec_constant( id = 1 , default = 0 ) ) ] alpha_mask_cutoff_bits : u32 ,
68
+ out_frag_color : & mut Vec4 ,
69
+ ) {
70
+ let color = sampler_color_map. sample ( in_uv) * vec4 ( in_color. x , in_color. y , in_color. z , 1.0 ) ;
71
+
72
+ let alpha_mask_enabled = alpha_mask != 0 ;
73
+ let alpha_mask_cutoff = f32:: from_bits ( alpha_mask_cutoff_bits) ;
74
+
75
+ if alpha_mask_enabled {
76
+ if color. w < alpha_mask_cutoff {
77
+ #[ cfg( target_arch = "spirv" ) ]
78
+ spirv_std:: arch:: kill ( ) ;
79
+ }
80
+ }
81
+
82
+ let mut n = in_normal. normalize ( ) ;
83
+ let t = in_tangent. truncate ( ) . normalize ( ) ;
84
+ let b = in_normal. cross ( in_tangent. truncate ( ) ) * in_tangent. w ;
85
+ let tbn = Mat3 :: from_cols ( t, b, n) ;
86
+ let normal_sample = sampler_normal_map. sample ( in_uv) . truncate ( ) * 2.0 - vec3 ( 1.0 , 1.0 , 1.0 ) ;
87
+ n = tbn * normal_sample. normalize ( ) ;
88
+
89
+ const AMBIENT : f32 = 0.1 ;
90
+ let l = in_light_vec. normalize ( ) ;
91
+ let v = in_view_vec. normalize ( ) ;
92
+ let r = ( -l) . reflect ( n) ;
93
+ let diffuse = vec3 ( n. dot ( l) . max ( AMBIENT ) , n. dot ( l) . max ( AMBIENT ) , n. dot ( l) . max ( AMBIENT ) ) ;
94
+ let specular = r. dot ( v) . max ( 0.0 ) . powf ( 32.0 ) ;
95
+ * out_frag_color = vec4 (
96
+ diffuse. x * color. x + specular,
97
+ diffuse. y * color. y + specular,
98
+ diffuse. z * color. z + specular,
99
+ color. w
100
+ ) ;
101
+ }
0 commit comments