1+ #![ cfg_attr( target_arch = "spirv" , no_std) ]
2+ #![ allow( clippy:: missing_safety_doc) ]
3+
4+ use spirv_std:: { spirv, glam:: { mat3, vec3, vec4, 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+ }
14+
15+ #[ repr( C ) ]
16+ #[ derive( Copy , Clone ) ]
17+ pub struct PushConsts {
18+ pub model : Mat4 ,
19+ }
20+
21+ #[ spirv( vertex) ]
22+ pub fn main_vs (
23+ in_pos : Vec3 ,
24+ in_normal : Vec3 ,
25+ in_uv : Vec2 ,
26+ in_color : Vec3 ,
27+ in_joint_indices : Vec4 ,
28+ in_joint_weights : Vec4 ,
29+ #[ spirv( uniform, descriptor_set = 0 , binding = 0 ) ] ubo_scene : & UboScene ,
30+ #[ spirv( push_constant) ] push_consts : & PushConsts ,
31+ #[ spirv( storage_buffer, descriptor_set = 1 , binding = 0 ) ] joint_matrices : & [ Mat4 ] ,
32+ #[ spirv( position) ] out_position : & mut Vec4 ,
33+ out_normal : & mut Vec3 ,
34+ out_color : & mut Vec3 ,
35+ out_uv : & mut Vec2 ,
36+ out_view_vec : & mut Vec3 ,
37+ out_light_vec : & mut Vec3 ,
38+ ) {
39+ * out_normal = in_normal;
40+ * out_color = in_color;
41+ * out_uv = in_uv;
42+
43+ // Calculate skinned matrix from weights and joint indices of the current vertex
44+ let skin_mat =
45+ in_joint_weights. x * joint_matrices[ in_joint_indices. x as usize ] +
46+ in_joint_weights. y * joint_matrices[ in_joint_indices. y as usize ] +
47+ in_joint_weights. z * joint_matrices[ in_joint_indices. z as usize ] +
48+ in_joint_weights. w * joint_matrices[ in_joint_indices. w as usize ] ;
49+
50+ * out_position = ubo_scene. projection * ubo_scene. view * push_consts. model * skin_mat * vec4 ( in_pos. x , in_pos. y , in_pos. z , 1.0 ) ;
51+
52+ // Transform normal with model and skin matrices (matching slang version)
53+ let model_mat3 = mat3 (
54+ push_consts. model . x_axis . truncate ( ) ,
55+ push_consts. model . y_axis . truncate ( ) ,
56+ push_consts. model . z_axis . truncate ( ) ,
57+ ) ;
58+ let skin_mat3 = mat3 (
59+ skin_mat. x_axis . truncate ( ) ,
60+ skin_mat. y_axis . truncate ( ) ,
61+ skin_mat. z_axis . truncate ( ) ,
62+ ) ;
63+ * out_normal = model_mat3 * skin_mat3 * in_normal;
64+
65+ let pos = ubo_scene. view * vec4 ( in_pos. x , in_pos. y , in_pos. z , 1.0 ) ;
66+ let view_mat3 = mat3 (
67+ ubo_scene. view . x_axis . truncate ( ) ,
68+ ubo_scene. view . y_axis . truncate ( ) ,
69+ ubo_scene. view . z_axis . truncate ( ) ,
70+ ) ;
71+ let l_pos = view_mat3 * ubo_scene. light_pos . truncate ( ) ;
72+ * out_light_vec = l_pos - pos. truncate ( ) ;
73+ * out_view_vec = -pos. truncate ( ) ;
74+ }
75+
76+ #[ spirv( fragment) ]
77+ pub fn main_fs (
78+ in_normal : Vec3 ,
79+ in_color : Vec3 ,
80+ in_uv : Vec2 ,
81+ in_view_vec : Vec3 ,
82+ in_light_vec : Vec3 ,
83+ #[ spirv( descriptor_set = 2 , binding = 0 ) ] sampler_color_map : & SampledImage < Image ! ( 2 D , type =f32 , sampled) > ,
84+ out_frag_color : & mut Vec4 ,
85+ ) {
86+ let color = sampler_color_map. sample ( in_uv) * vec4 ( in_color. x , in_color. y , in_color. z , 1.0 ) ;
87+
88+ let n = in_normal. normalize ( ) ;
89+ let l = in_light_vec. normalize ( ) ;
90+ let v = in_view_vec. normalize ( ) ;
91+ let r = ( -l) . reflect ( n) ;
92+ let diffuse = n. dot ( l) . max ( 0.5 ) * in_color;
93+ let specular = v. dot ( r) . max ( 0.0 ) . powf ( 16.0 ) * vec3 ( 0.75 , 0.75 , 0.75 ) ;
94+ * out_frag_color = vec4 ( diffuse. x * color. x + specular. x , diffuse. y * color. y + specular. y , diffuse. z * color. z + specular. z , 1.0 ) ;
95+ }
0 commit comments