diff options
Diffstat (limited to 'source/blender/draw/engines/eevee/shaders/effect_dof_flatten_tiles_frag.glsl')
-rw-r--r-- | source/blender/draw/engines/eevee/shaders/effect_dof_flatten_tiles_frag.glsl | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/source/blender/draw/engines/eevee/shaders/effect_dof_flatten_tiles_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_dof_flatten_tiles_frag.glsl new file mode 100644 index 00000000000..bd81171c759 --- /dev/null +++ b/source/blender/draw/engines/eevee/shaders/effect_dof_flatten_tiles_frag.glsl @@ -0,0 +1,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); +} |