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

eevee_depth_of_field_tiles_dilate_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: dba8b5fd79de046e2a4c58173cc514d184148869 (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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97

/**
 * Tile dilate pass: Takes the 8x8 Tiles buffer and converts dilates the tiles with large CoC to
 * their neighborhood. This pass is repeated multiple time until the maximum CoC can be covered.
 *
 * Input & Output:
 * - Separated foreground and background CoC. 1/8th of half-res resolution. So 1/16th of full-res.
 **/

#pragma BLENDER_REQUIRE(eevee_depth_of_field_lib.glsl)

/* Error introduced by the random offset of the gathering kernel's center. */
const float bluring_radius_error = 1.0 + 1.0 / (float(DOF_GATHER_RING_COUNT) + 0.5);
const float tile_to_fullres_factor = float(DOF_TILES_SIZE * 2);

void main()
{
  ivec2 center_tile_pos = ivec2(gl_GlobalInvocationID.xy);

  CocTile ring_buckets[DOF_DILATE_RING_COUNT];

  for (int ring = 0; ring < ring_count && ring < DOF_DILATE_RING_COUNT; ring++) {
    ring_buckets[ring] = dof_coc_tile_init();

    int ring_distance = ring + 1;
    for (int sample_id = 0; sample_id < 4 * ring_distance; sample_id++) {
      ivec2 offset = dof_square_ring_sample_offset(ring_distance, sample_id);

      offset *= ring_width_multiplier;

      for (int i = 0; i < 2; i++) {
        ivec2 adj_tile_pos = center_tile_pos + ((i == 0) ? offset : -offset);

        CocTile adj_tile = dof_coc_tile_load(in_tiles_fg_img, in_tiles_bg_img, adj_tile_pos);

        if (DILATE_MODE_MIN_MAX) {
          /* Actually gather the "absolute" biggest coc but keeping the sign. */
          ring_buckets[ring].fg_min_coc = min(ring_buckets[ring].fg_min_coc, adj_tile.fg_min_coc);
          ring_buckets[ring].bg_max_coc = max(ring_buckets[ring].bg_max_coc, adj_tile.bg_max_coc);
        }
        else { /* DILATE_MODE_MIN_ABS */
          ring_buckets[ring].fg_max_coc = max(ring_buckets[ring].fg_max_coc, adj_tile.fg_max_coc);
          ring_buckets[ring].bg_min_coc = min(ring_buckets[ring].bg_min_coc, adj_tile.bg_min_coc);

          /* Should be tight as possible to reduce gather overhead (see slide 61). */
          float closest_neighbor_distance = length(max(abs(vec2(offset)) - 1.0, 0.0)) *
                                            tile_to_fullres_factor;

          ring_buckets[ring].fg_max_intersectable_coc = max(
              ring_buckets[ring].fg_max_intersectable_coc,
              adj_tile.fg_max_intersectable_coc + closest_neighbor_distance);
          ring_buckets[ring].bg_min_intersectable_coc = min(
              ring_buckets[ring].bg_min_intersectable_coc,
              adj_tile.bg_min_intersectable_coc + closest_neighbor_distance);
        }
      }
    }
  }

  /* Load center tile. */
  CocTile out_tile = dof_coc_tile_load(in_tiles_fg_img, in_tiles_bg_img, center_tile_pos);

  for (int ring = 0; ring < ring_count && ring < DOF_DILATE_RING_COUNT; ring++) {
    float ring_distance = float(ring + 1);

    ring_distance = (ring_distance * ring_width_multiplier - 1) * tile_to_fullres_factor;

    if (DILATE_MODE_MIN_MAX) {
      /* NOTE(fclem): Unsure if both sides of the inequalities have the same unit. */
      if (-ring_buckets[ring].fg_min_coc * bluring_radius_error > ring_distance) {
        out_tile.fg_min_coc = min(out_tile.fg_min_coc, ring_buckets[ring].fg_min_coc);
      }

      if (ring_buckets[ring].bg_max_coc * bluring_radius_error > ring_distance) {
        out_tile.bg_max_coc = max(out_tile.bg_max_coc, ring_buckets[ring].bg_max_coc);
      }
    }
    else { /* DILATE_MODE_MIN_ABS */
      /* Find minimum absolute CoC radii that will be intersected for the previously
       * computed maximum CoC values. */
      if (-out_tile.fg_min_coc * bluring_radius_error > ring_distance) {
        out_tile.fg_max_coc = max(out_tile.fg_max_coc, ring_buckets[ring].fg_max_coc);
        out_tile.fg_max_intersectable_coc = max(out_tile.fg_max_intersectable_coc,
                                                ring_buckets[ring].fg_max_intersectable_coc);
      }

      if (out_tile.bg_max_coc * bluring_radius_error > ring_distance) {
        out_tile.bg_min_coc = min(out_tile.bg_min_coc, ring_buckets[ring].bg_min_coc);
        out_tile.bg_min_intersectable_coc = min(out_tile.bg_min_intersectable_coc,
                                                ring_buckets[ring].bg_min_intersectable_coc);
      }
    }
  }

  ivec2 texel_out = ivec2(gl_GlobalInvocationID.xy);
  dof_coc_tile_store(out_tiles_fg_img, out_tiles_bg_img, texel_out, out_tile);
}