1
1
#define_import_path bevy_pbr ::shadows
2
2
3
3
fn fetch_point_shadow (light_id : u32 , frag_position : vec4 <f32 >, surface_normal : vec3 <f32 >) -> f32 {
4
- let light = point_lights . data[light_id ];
4
+ let light = & point_lights . data[light_id ];
5
5
6
6
// because the shadow maps align with the axes and the frustum planes are at 45 degrees
7
7
// we can get the worldspace depth by taking the largest absolute axis
8
- let surface_to_light = light . position_radius. xyz - frag_position . xyz;
8
+ let surface_to_light = (* light ) . position_radius. xyz - frag_position . xyz;
9
9
let surface_to_light_abs = abs (surface_to_light );
10
10
let distance_to_light = max (surface_to_light_abs . x, max (surface_to_light_abs . y, surface_to_light_abs . z));
11
11
12
12
// The normal bias here is already scaled by the texel size at 1 world unit from the light.
13
13
// The texel size increases proportionally with distance from the light so multiplying by
14
14
// distance to light scales the normal bias to the texel size at the fragment distance.
15
- let normal_offset = light . shadow_normal_bias * distance_to_light * surface_normal . xyz;
16
- let depth_offset = light . shadow_depth_bias * normalize (surface_to_light . xyz);
15
+ let normal_offset = (* light ) . shadow_normal_bias * distance_to_light * surface_normal . xyz;
16
+ let depth_offset = (* light ) . shadow_depth_bias * normalize (surface_to_light . xyz);
17
17
let offset_position = frag_position . xyz + normal_offset + depth_offset ;
18
18
19
19
// similar largest-absolute-axis trick as above, but now with the offset fragment position
20
- let frag_ls = light . position_radius. xyz - offset_position . xyz;
20
+ let frag_ls = (* light ) . position_radius. xyz - offset_position . xyz;
21
21
let abs_position_ls = abs (frag_ls );
22
22
let major_axis_magnitude = max (abs_position_ls . x, max (abs_position_ls . y, abs_position_ls . z));
23
23
24
24
// NOTE: These simplifications come from multiplying:
25
25
// projection * vec4(0, 0, -major_axis_magnitude, 1.0)
26
26
// and keeping only the terms that have any impact on the depth.
27
27
// Projection-agnostic approach:
28
- let zw = - major_axis_magnitude * light . light_custom_data. xy + light . light_custom_data. zw;
28
+ let zw = - major_axis_magnitude * (* light ) . light_custom_data. xy + (* light ) . light_custom_data. zw;
29
29
let depth = zw . x / zw . y;
30
30
31
31
// do the lookup, using HW PCF and comparison
@@ -42,27 +42,27 @@ fn fetch_point_shadow(light_id: u32, frag_position: vec4<f32>, surface_normal: v
42
42
}
43
43
44
44
fn fetch_spot_shadow (light_id : u32 , frag_position : vec4 <f32 >, surface_normal : vec3 <f32 >) -> f32 {
45
- let light = point_lights . data[light_id ];
45
+ let light = & point_lights . data[light_id ];
46
46
47
- let surface_to_light = light . position_radius. xyz - frag_position . xyz;
47
+ let surface_to_light = (* light ) . position_radius. xyz - frag_position . xyz;
48
48
49
49
// construct the light view matrix
50
- var spot_dir = vec3 <f32 >(light . light_custom_data. x, 0.0 , light . light_custom_data. y);
50
+ var spot_dir = vec3 <f32 >((* light ) . light_custom_data. x, 0.0 , (* light ) . light_custom_data. y);
51
51
// reconstruct spot dir from x/z and y-direction flag
52
52
spot_dir . y = sqrt (1.0 - spot_dir . x * spot_dir . x - spot_dir . z * spot_dir . z);
53
- if ((light . flags & POINT_LIGHT_FLAGS_SPOT_LIGHT_Y_NEGATIVE) != 0u ) {
53
+ if (((* light ) . flags & POINT_LIGHT_FLAGS_SPOT_LIGHT_Y_NEGATIVE) != 0u ) {
54
54
spot_dir . y = - spot_dir . y;
55
55
}
56
56
57
57
// view matrix z_axis is the reverse of transform.forward()
58
58
let fwd = - spot_dir ;
59
59
let distance_to_light = dot (fwd , surface_to_light );
60
- let offset_position =
61
- - surface_to_light
62
- + (light . shadow_depth_bias * normalize (surface_to_light ))
63
- + (surface_normal . xyz * light . shadow_normal_bias) * distance_to_light ;
60
+ let offset_position =
61
+ - surface_to_light
62
+ + ((* light ) . shadow_depth_bias * normalize (surface_to_light ))
63
+ + (surface_normal . xyz * (* light ) . shadow_normal_bias) * distance_to_light ;
64
64
65
- // the construction of the up and right vectors needs to precisely mirror the code
65
+ // the construction of the up and right vectors needs to precisely mirror the code
66
66
// in render/light.rs:spot_light_view_matrix
67
67
var sign = - 1.0 ;
68
68
if (fwd . z >= 0.0 ) {
@@ -74,14 +74,14 @@ fn fetch_spot_shadow(light_id: u32, frag_position: vec4<f32>, surface_normal: ve
74
74
let right_dir = vec3 <f32 >(- b , - sign - fwd . y * fwd . y * a , fwd . y);
75
75
let light_inv_rot = mat3x3 <f32 >(right_dir , up_dir , fwd );
76
76
77
- // because the matrix is a pure rotation matrix, the inverse is just the transpose, and to calculate
78
- // the product of the transpose with a vector we can just post-multiply instead of pre-multplying.
77
+ // because the matrix is a pure rotation matrix, the inverse is just the transpose, and to calculate
78
+ // the product of the transpose with a vector we can just post-multiply instead of pre-multplying.
79
79
// this allows us to keep the matrix construction code identical between CPU and GPU.
80
80
let projected_position = offset_position * light_inv_rot ;
81
81
82
82
// divide xy by perspective matrix "f" and by -projected.z (projected.z is -projection matrix's w)
83
83
// to get ndc coordinates
84
- let f_div_minus_z = 1.0 / (light . spot_light_tan_angle * - projected_position . z);
84
+ let f_div_minus_z = 1.0 / ((* light ) . spot_light_tan_angle * - projected_position . z);
85
85
let shadow_xy_ndc = projected_position . xy * f_div_minus_z ;
86
86
// convert to uv coordinates
87
87
let shadow_uv = shadow_xy_ndc * vec2 <f32 >(0.5 , - 0.5 ) + vec2 <f32 >(0.5 , 0.5 );
@@ -90,23 +90,23 @@ fn fetch_spot_shadow(light_id: u32, frag_position: vec4<f32>, surface_normal: ve
90
90
let depth = 0.1 / - projected_position . z;
91
91
92
92
#ifdef NO_ARRAY_TEXTURES_SUPPORT
93
- return textureSampleCompare (directional_shadow_textures , directional_shadow_textures_sampler ,
93
+ return textureSampleCompare (directional_shadow_textures , directional_shadow_textures_sampler ,
94
94
shadow_uv , depth );
95
95
#else
96
- return textureSampleCompareLevel (directional_shadow_textures , directional_shadow_textures_sampler ,
96
+ return textureSampleCompareLevel (directional_shadow_textures , directional_shadow_textures_sampler ,
97
97
shadow_uv , i32 (light_id ) + lights . spot_light_shadowmap_offset, depth );
98
98
#endif
99
99
}
100
100
101
101
fn fetch_directional_shadow (light_id : u32 , frag_position : vec4 <f32 >, surface_normal : vec3 <f32 >) -> f32 {
102
- let light = lights . directional_lights[light_id ];
102
+ let light = & lights . directional_lights[light_id ];
103
103
104
104
// The normal bias is scaled to the texel size.
105
- let normal_offset = light . shadow_normal_bias * surface_normal . xyz;
106
- let depth_offset = light . shadow_depth_bias * light . direction_to_light. xyz;
105
+ let normal_offset = (* light ) . shadow_normal_bias * surface_normal . xyz;
106
+ let depth_offset = (* light ) . shadow_depth_bias * (* light ) . direction_to_light. xyz;
107
107
let offset_position = vec4 <f32 >(frag_position . xyz + normal_offset + depth_offset , frag_position . w);
108
108
109
- let offset_position_clip = light . view_projection * offset_position ;
109
+ let offset_position_clip = (* light ) . view_projection * offset_position ;
110
110
if (offset_position_clip . w <= 0.0 ) {
111
111
return 1.0 ;
112
112
}
0 commit comments