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
|
/**
* Virtual shadowmapping: Setup phase for tilemaps.
* During this phase we clear the visibility, usage and request bits.
* This is also where we shifts the whole tilemap for directional shadow clipmaps
*/
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_shader_shared.hh)
#pragma BLENDER_REQUIRE(eevee_shadow_page_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_shadow_tilemap_lib.glsl)
layout(local_size_x = SHADOW_TILEMAP_RES, local_size_y = SHADOW_TILEMAP_RES) in;
layout(std430, binding = 0) readonly buffer tilemaps_buf
{
ShadowTileMapData tilemaps[];
};
layout(std430, binding = 1) restrict buffer pages_free_buf
{
uint free_page_owners[];
};
layout(std430, binding = 3) restrict buffer pages_infos_buf
{
ShadowPagesInfoData infos;
};
layout(r32ui) restrict uniform uimage2D tilemaps_img;
uniform bool do_tilemap_setup;
void main()
{
ShadowTileMapData tilemap = tilemaps[gl_GlobalInvocationID.z];
ivec2 grid_shift = (do_tilemap_setup) ? tilemap.grid_shift : ivec2(0);
ivec2 tile_co = ivec2(gl_GlobalInvocationID.xy);
ivec2 tile_shifted = tile_co + grid_shift;
/* Still load a valid tile after the shifting in order to not loose any page reference.
* This way the tile can even be reused if it is needed. Also avoid negative modulo. */
ivec2 tile_wrapped = (tile_shifted + SHADOW_TILEMAP_RES) % SHADOW_TILEMAP_RES;
ivec2 texel_out = shadow_tile_coord_in_atlas(tile_co, tilemap.index, 0);
ivec2 texel_in = shadow_tile_coord_in_atlas(tile_wrapped, tilemap.index, 0);
ShadowTileData tile_data = shadow_tile_data_unpack(imageLoad(tilemaps_img, texel_in).x);
tile_data.is_visible = false;
tile_data.is_used = false;
tile_data.lod = 0;
if (!in_range_inclusive(tile_shifted, ivec2(0), ivec2(SHADOW_TILEMAP_RES - 1))) {
/* This tile was shifted in. */
tile_data.do_update = true;
}
if (grid_shift != ivec2(0) && tile_data.is_cached) {
/* Update page location after shift. */
free_page_owners[tile_data.free_page_owner_index] = packUvec2x16(uvec2(texel_out));
}
imageStore(tilemaps_img, texel_out, uvec4(shadow_tile_data_pack(tile_data)));
if (tilemap.is_cubeface) {
/* Cubemap shift update is always all or nothing. */
bool do_update = (grid_shift.x != 0);
/* Number of lod0 tiles covered by the current lod level (in one dimension). */
uint lod_stride = 1u << 1u;
uint lod_size = uint(SHADOW_TILEMAP_RES) >> 1u;
for (int lod = 1; lod <= SHADOW_TILEMAP_LOD; lod++, lod_size >>= 1u, lod_stride <<= 1u) {
if (all(lessThan(tile_co, ivec2(lod_size)))) {
ivec2 texel = shadow_tile_coord_in_atlas(tile_co, tilemap.index, lod);
ShadowTileData tile_data = shadow_tile_data_unpack(imageLoad(tilemaps_img, texel).x);
tile_data.is_visible = false;
tile_data.is_used = false;
tile_data.do_update = do_update;
tile_data.lod = 0;
imageStore(tilemaps_img, texel, uvec4(shadow_tile_data_pack(tile_data)));
}
}
}
if (gl_GlobalInvocationID == uvec3(0)) {
infos.page_free_next = max(-1, infos.page_free_next);
infos.page_free_next_prev = infos.page_free_next;
infos.page_updated_count = 0;
}
}
|