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