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