1
+ #![ cfg_attr( target_arch = "spirv" , no_std) ]
2
+ #![ allow( clippy:: missing_safety_doc) ]
3
+ #![ feature( asm_experimental_arch) ]
4
+
5
+ use spirv_std:: { spirv, glam:: { vec4, Mat3 , Mat4 , Vec2 , Vec3 , Vec4 } } ;
6
+ use spirv_std:: ray_tracing:: { AccelerationStructure , RayFlags , RayQuery , CommittedIntersection } ;
7
+
8
+ #[ repr( C ) ]
9
+ #[ derive( Copy , Clone ) ]
10
+ pub struct Ubo {
11
+ pub projection : Mat4 ,
12
+ pub view : Mat4 ,
13
+ pub model : Mat4 ,
14
+ pub light_pos : Vec3 ,
15
+ }
16
+
17
+ #[ spirv( vertex) ]
18
+ pub fn main_vs (
19
+ in_pos : Vec3 ,
20
+ _in_uv : Vec2 ,
21
+ in_color : Vec3 ,
22
+ in_normal : Vec3 ,
23
+ #[ spirv( uniform, descriptor_set = 0 , binding = 0 ) ] ubo : & Ubo ,
24
+ #[ spirv( position) ] out_position : & mut Vec4 ,
25
+ out_normal : & mut Vec3 ,
26
+ out_color : & mut Vec3 ,
27
+ out_view_vec : & mut Vec3 ,
28
+ out_light_vec : & mut Vec3 ,
29
+ out_world_pos : & mut Vec3 ,
30
+ ) {
31
+ * out_color = in_color;
32
+ * out_position = ubo. projection * ubo. view * ubo. model * vec4 ( in_pos. x , in_pos. y , in_pos. z , 1.0 ) ;
33
+ let pos = ubo. model * vec4 ( in_pos. x , in_pos. y , in_pos. z , 1.0 ) ;
34
+ * out_world_pos = ( ubo. model * vec4 ( in_pos. x , in_pos. y , in_pos. z , 1.0 ) ) . truncate ( ) ;
35
+ let model_mat3 = Mat3 :: from_cols (
36
+ ubo. model . x_axis . truncate ( ) ,
37
+ ubo. model . y_axis . truncate ( ) ,
38
+ ubo. model . z_axis . truncate ( ) ,
39
+ ) ;
40
+ * out_normal = model_mat3 * in_normal;
41
+ * out_light_vec = ( ubo. light_pos - in_pos) . normalize ( ) ;
42
+ * out_view_vec = -pos. truncate ( ) ;
43
+ }
44
+
45
+ const AMBIENT : f32 = 0.1 ;
46
+
47
+ #[ spirv( fragment) ]
48
+ pub fn main_fs (
49
+ in_normal : Vec3 ,
50
+ in_color : Vec3 ,
51
+ _in_view_vec : Vec3 ,
52
+ in_light_vec : Vec3 ,
53
+ in_world_pos : Vec3 ,
54
+ #[ spirv( descriptor_set = 0 , binding = 1 ) ] top_level_as : & AccelerationStructure ,
55
+ out_frag_color : & mut Vec4 ,
56
+ ) {
57
+ let n = in_normal. normalize ( ) ;
58
+ let l = in_light_vec. normalize ( ) ;
59
+ let diffuse = n. dot ( l) . max ( AMBIENT ) * in_color;
60
+
61
+ * out_frag_color = vec4 ( diffuse. x , diffuse. y , diffuse. z , 1.0 ) ;
62
+
63
+ unsafe {
64
+ spirv_std:: ray_query!( let mut ray_query) ;
65
+ ray_query. initialize (
66
+ top_level_as,
67
+ RayFlags :: TERMINATE_ON_FIRST_HIT ,
68
+ 0xFF ,
69
+ in_world_pos,
70
+ 0.01 ,
71
+ l,
72
+ 1000.0
73
+ ) ;
74
+
75
+ // Traverse the acceleration structure
76
+ ray_query. proceed ( ) ;
77
+
78
+ // If the intersection has hit a triangle, the fragment is shadowed
79
+ if ray_query. get_committed_intersection_type ( ) == CommittedIntersection :: Triangle {
80
+ * out_frag_color *= 0.1 ;
81
+ }
82
+ }
83
+ }
0 commit comments