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
|
/**
* Tile flatten pass: Takes the halfres CoC buffer and converts it to 8x8 tiles.
*
* Output min and max values for each tile and for both foreground & background.
* Also outputs min intersectable CoC for the background, which is the minimum CoC
* that comes from the background pixels.
*
* Input:
* - Half-resolution Circle of confusion. Out of setup pass.
* 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)
/**
* In order to use atomic operations, we have to use uints. But this means having to deal with the
* negative number ourselves. Luckily, each ground have a nicely defined range of values we can
* remap to positive float.
*/
shared uint fg_min_coc;
shared uint fg_max_coc;
shared uint fg_max_intersectable_coc;
shared uint bg_min_coc;
shared uint bg_max_coc;
shared uint bg_min_intersectable_coc;
const uint dof_tile_large_coc_uint = floatBitsToUint(dof_tile_large_coc);
void main()
{
if (all(equal(gl_LocalInvocationID.xy, uvec2(0)))) {
/* NOTE: Min/Max flipped because of inverted fg_coc sign. */
fg_min_coc = floatBitsToUint(0.0);
fg_max_coc = dof_tile_large_coc_uint;
fg_max_intersectable_coc = dof_tile_large_coc_uint;
bg_min_coc = dof_tile_large_coc_uint;
bg_max_coc = floatBitsToUint(0.0);
bg_min_intersectable_coc = dof_tile_large_coc_uint;
}
barrier();
ivec2 sample_texel = min(ivec2(gl_GlobalInvocationID.xy), textureSize(coc_tx, 0).xy - 1);
vec2 sample_data = texelFetch(coc_tx, sample_texel, 0).rg;
float sample_coc = sample_data.x;
uint fg_coc = floatBitsToUint(max(-sample_coc, 0.0));
/* NOTE: atomicMin/Max flipped because of inverted fg_coc sign. */
atomicMax(fg_min_coc, fg_coc);
atomicMin(fg_max_coc, fg_coc);
atomicMin(fg_max_intersectable_coc, (sample_coc < 0.0) ? fg_coc : dof_tile_large_coc_uint);
uint bg_coc = floatBitsToUint(max(sample_coc, 0.0));
atomicMin(bg_min_coc, bg_coc);
atomicMax(bg_max_coc, bg_coc);
atomicMin(bg_min_intersectable_coc, (sample_coc > 0.0) ? bg_coc : dof_tile_large_coc_uint);
barrier();
if (all(equal(gl_LocalInvocationID.xy, uvec2(0)))) {
if (fg_max_intersectable_coc == dof_tile_large_coc_uint) {
fg_max_intersectable_coc = floatBitsToUint(0.0);
}
CocTile tile;
/* Foreground sign is flipped since we compare unsigned representation. */
tile.fg_min_coc = -uintBitsToFloat(fg_min_coc);
tile.fg_max_coc = -uintBitsToFloat(fg_max_coc);
tile.fg_max_intersectable_coc = -uintBitsToFloat(fg_max_intersectable_coc);
tile.bg_min_coc = uintBitsToFloat(bg_min_coc);
tile.bg_max_coc = uintBitsToFloat(bg_max_coc);
tile.bg_min_intersectable_coc = uintBitsToFloat(bg_min_intersectable_coc);
ivec2 tile_co = ivec2(gl_WorkGroupID.xy);
dof_coc_tile_store(out_tiles_fg_img, out_tiles_bg_img, tile_co, tile);
}
}
|