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