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

eevee_shadow_tilemap_lod_mask_comp.glsl « shaders « eevee « engines « draw « blender « source - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: b4147c66b501f62f0c8e5080d93807ade4d4494b (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

/**
 * Virtual shadowmapping: LOD mask.
 *
 * Discard pages that are redundant in the mipmap chain.
 * We mask tiles that are completely covered by higher LOD tiles.
 */

#pragma BLENDER_REQUIRE(eevee_shadow_tilemap_lib.glsl)

/* Bitmap of usage tests. Use one uint per tile. One bit per lod level. */
shared uint lod_map[SHADOW_TILEMAP_RES * SHADOW_TILEMAP_RES];

void main()
{
  ShadowTileMapData tilemap_data = tilemaps_buf[gl_GlobalInvocationID.z];
  int tilemap_idx = tilemap_data.index;
  int lod_max = tilemap_data.is_cubeface ? SHADOW_TILEMAP_LOD : 0;

  /* For now there is nothing to do for directional shadows. */
  if (tilemap_data.is_cubeface) {
    ivec2 tile_co = ivec2(gl_GlobalInvocationID.xy);

    lod_map[SHADOW_TILEMAP_RES * tile_co.y + tile_co.x] = 0u;

    int map_index = tile_co.y * SHADOW_TILEMAP_RES + tile_co.x;
    for (int lod = 0; lod <= lod_max; lod++) {
      ivec2 tile_co_lod = ivec2(gl_GlobalInvocationID.xy) >> lod;
      ShadowTileData tile = shadow_tile_load_img(tilemaps_img, tile_co_lod, lod, tilemap_idx);

      if (tile.is_used && tile.is_visible) {
        lod_map[map_index] |= 1u << uint(lod);
      }
    }

    barrier();

    /* We mask tiles from lower LOD that are completely covered by the lods above it. */
    for (int lod = 1; lod <= SHADOW_TILEMAP_LOD; lod++) {
      uint stride = 1u << uint(lod);
      if ((gl_GlobalInvocationID.xy % stride) != uvec2(0)) {
        continue;
      }
      uint lod_mask = ~(~0x0u << uint(lod));
      bool tiles_covered = true;
      for (int x = 0; x < stride && tiles_covered; x++) {
        for (int y = 0; y < stride && tiles_covered; y++) {
          ivec2 tile_co = ivec2(gl_GlobalInvocationID.xy) + ivec2(x, y);
          uint lod_bits = lod_map[tile_co.y * SHADOW_TILEMAP_RES + tile_co.x];
          if ((lod_bits & lod_mask) == 0u) {
            tiles_covered = false;
          }
        }
      }
      if (tiles_covered) {
        ivec2 tile_co = ivec2(gl_GlobalInvocationID.xy >> uint(lod));
        shadow_tile_unset_flag(tilemaps_img, tile_co, lod, tilemap_idx, SHADOW_TILE_IS_USED);
      }
    }
  }
}