Welcome to mirror list, hosted at ThFree Co, Russian Federation.

eevee_light_culling_zbin_comp.glsl « shaders « eevee_next « engines « draw « blender « source - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: d96f191fb774586470943d01bd6b3e1d72e09576 (plain)
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_u(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);
  }
}