1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
/**
* Create the Zbins from Z-sorted lights.
* Perform min-max operation in LDS memory for speed.
* For this reason, we only dispatch 1 thread group.
*/
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_light_iter_lib.glsl)
/* Fits the limit of 32KB. */
shared uint zbin_max[CULLING_ZBIN_COUNT];
shared uint zbin_min[CULLING_ZBIN_COUNT];
void main()
{
const uint zbin_iter = CULLING_ZBIN_COUNT / gl_WorkGroupSize.x;
const uint zbin_local = gl_LocalInvocationID.x * zbin_iter;
uint src_index = gl_GlobalInvocationID.x;
for (uint i = 0u, l = zbin_local; i < zbin_iter; i++, l++) {
zbin_max[l] = 0x0u;
zbin_min[l] = ~0x0u;
}
barrier();
uint light_iter = divide_ceil(light_cull_buf.visible_count, gl_WorkGroupSize.x);
for (uint i = 0u; i < light_iter; i++) {
uint index = i * gl_WorkGroupSize.x + gl_LocalInvocationID.x;
if (index >= light_cull_buf.visible_count) {
continue;
}
vec3 P = light_buf[index]._position;
/* TODO(fclem): Could have better bounds for spot and area lights. */
float radius = light_buf[index].influence_radius_max;
float z_dist = dot(cameraForward, P) - dot(cameraForward, cameraPos);
int z_min = culling_z_to_zbin(
light_cull_buf.zbin_scale, light_cull_buf.zbin_bias, z_dist + radius);
int z_max = culling_z_to_zbin(
light_cull_buf.zbin_scale, light_cull_buf.zbin_bias, z_dist - radius);
z_min = clamp(z_min, 0, CULLING_ZBIN_COUNT - 1);
z_max = clamp(z_max, 0, CULLING_ZBIN_COUNT - 1);
/* Register to Z bins. */
for (int z = z_min; z <= z_max; z++) {
atomicMin(zbin_min[z], index);
atomicMax(zbin_max[z], index);
}
}
barrier();
/* Write result to zbins buffer. Pack min & max into 1 uint. */
for (uint i = 0u, l = zbin_local; i < zbin_iter; i++, l++) {
out_zbin_buf[l] = (zbin_max[l] << 16u) | (zbin_min[l] & 0xFFFFu);
}
}
|