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
|
/**
* 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.
*/
#pragma BLENDER_REQUIRE(effect_dof_lib.glsl)
/* Half resolution. */
uniform sampler2D halfResCocBuffer;
/* 1/8th of halfResCocBuffer resolution. So 1/16th of fullres. */
layout(location = 0) out vec4 outFgCoc;
layout(location = 1) out vec3 outBgCoc;
const int halfres_tile_divisor = DOF_TILE_DIVISOR / 2;
void main()
{
ivec2 halfres_bounds = textureSize(halfResCocBuffer, 0).xy - 1;
ivec2 tile_co = ivec2(gl_FragCoord.xy);
CocTile tile = dof_coc_tile_init();
for (int x = 0; x < halfres_tile_divisor; x++) {
/* OPTI: Could be done in separate passes. */
for (int y = 0; y < halfres_tile_divisor; y++) {
ivec2 sample_texel = tile_co * halfres_tile_divisor + ivec2(x, y);
vec2 sample_data = texelFetch(halfResCocBuffer, min(sample_texel, halfres_bounds), 0).rg;
float sample_coc = sample_data.x;
float sample_slight_focus_coc = sample_data.y;
float fg_coc = min(sample_coc, 0.0);
tile.fg_min_coc = min(tile.fg_min_coc, fg_coc);
tile.fg_max_coc = max(tile.fg_max_coc, fg_coc);
float bg_coc = max(sample_coc, 0.0);
tile.bg_min_coc = min(tile.bg_min_coc, bg_coc);
tile.bg_max_coc = max(tile.bg_max_coc, bg_coc);
if (sample_coc > 0.0) {
tile.bg_min_intersectable_coc = min(tile.bg_min_intersectable_coc, bg_coc);
}
if (sample_coc < 0.0) {
tile.fg_max_intersectable_coc = max(tile.fg_max_intersectable_coc, fg_coc);
}
tile.fg_slight_focus_max_coc = dof_coc_max_slight_focus(tile.fg_slight_focus_max_coc,
sample_slight_focus_coc);
}
}
dof_coc_tile_store(tile, outFgCoc, outBgCoc);
}
|