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