diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2018-09-10 17:26:18 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2018-09-10 19:05:11 +0300 |
commit | 5e7a56dc646596c8cdac6f7ade8665c3ccbe201b (patch) | |
tree | 358c280f0e2c393194631ababb759cceef9b6d4a /source | |
parent | ec64cad5a88ca892a8c2189574344a4b90cfa80d (diff) |
Eevee: Cleanup DoF implementation
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl | 49 | ||||
-rw-r--r-- | source/blender/draw/engines/eevee/shaders/effect_dof_vert.glsl | 10 |
2 files changed, 24 insertions, 35 deletions
diff --git a/source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl index 4e47df04bd2..d816d72c1e3 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl @@ -31,12 +31,11 @@ uniform vec2 nearFar; /* Near & far view depths values */ ? (nearFar.x * nearFar.y) / (z * (nearFar.x - nearFar.y) + nearFar.y) \ : (z * 2.0 - 1.0) * nearFar.y) -#define weighted_sum(a, b, c, d, e) (a * e.x + b * e.y + c * e.z + d * e.w) +#define weighted_sum(a, b, c, d, e) (a * e.x + b * e.y + c * e.z + d * e.w) / max(1e-6, dot(e, vec4(1.0))); float max_v4(vec4 v) { return max(max(v.x, v.y), max(v.z, v.w)); } -#define THRESHOLD 0.0 -#define SIMILAR_COC_THRESHOLD 2.0 +#define THRESHOLD 1.0 #ifdef STEP_DOWNSAMPLE @@ -70,23 +69,17 @@ void main(void) vec4 coc_near = calculate_coc(zdepth); vec4 coc_far = -coc_near; - /* now we need to write the near-far fields premultiplied by the coc */ - /* Also reject pixels that have a much lower coc than the max coc pixel. */ - vec4 near_weights = step(THRESHOLD, coc_near) * step(max_v4(coc_near) - SIMILAR_COC_THRESHOLD, coc_near); - vec4 far_weights = step(THRESHOLD, coc_far) * step(max_v4(coc_far) - SIMILAR_COC_THRESHOLD, coc_far); + cocData.x = max(max_v4(coc_near), 0.0); + cocData.y = max(max_v4(coc_far), 0.0); + + /* now we need to write the near-far fields premultiplied by the coc + * also use bilateral weighting by each coc values to avoid bleeding. */ + vec4 near_weights = step(THRESHOLD, coc_near) * clamp(1.0 - abs(cocData.x - coc_near), 0.0, 1.0); + vec4 far_weights = step(THRESHOLD, coc_far) * clamp(1.0 - abs(cocData.y - coc_far), 0.0, 1.0); /* now write output to weighted buffers. */ nearColor = weighted_sum(color1, color2, color3, color4, near_weights); farColor = weighted_sum(color1, color2, color3, color4, far_weights); - - /* Normalize the color (don't divide by 0.0) */ - nearColor /= max(1e-6, dot(near_weights, near_weights)); - farColor /= max(1e-6, dot(far_weights, far_weights)); - - float max_near_coc = max(max_v4(coc_near), 0.0); - float max_far_coc = max(max_v4(coc_far), 0.0); - - cocData = vec2(max_near_coc, max_far_coc); } #elif defined(STEP_SCATTER) @@ -199,26 +192,20 @@ void main(void) float coc_far = max(-coc_signed, 0.0); float coc_near = max(coc_signed, 0.0); - vec2 texelSize = vec2(0.5, 1.0) / vec2(textureSize(scatterBuffer, 0)); - vec4 srccolor = textureLod(colorBuffer, uv, 0.0); + vec4 focus_col = textureLod(colorBuffer, uv, 0.0); + vec2 texelSize = vec2(0.5, 1.0) / vec2(textureSize(scatterBuffer, 0)); vec2 near_uv = uv * vec2(0.5, 1.0); vec2 far_uv = near_uv + vec2(0.5, 0.0); - vec4 farcolor = upsample_filter(scatterBuffer, far_uv, texelSize); - vec4 nearcolor = upsample_filter(scatterBuffer, near_uv, texelSize); - - float farweight = farcolor.a; - float nearweight = nearcolor.a; - - if (farcolor.a > 0.0) farcolor /= farcolor.a; - if (nearcolor.a > 0.0) nearcolor /= nearcolor.a; + vec4 near_col = upsample_filter(scatterBuffer, near_uv, texelSize); + vec4 far_col = upsample_filter(scatterBuffer, far_uv, texelSize); - float mixfac = smoothstep(1.0, MERGE_THRESHOLD, abs(coc_signed)); + float far_w = far_col.a; + float near_w = near_col.a; + float focus_w = 1.0 - smoothstep(1.0, MERGE_THRESHOLD, abs(coc_signed)); + focus_col *= focus_w; /* Premul */ - float totalweight = nearweight + farweight; - farcolor = mix(srccolor, farcolor, mixfac); - nearcolor = mix(srccolor, nearcolor, mixfac); - fragColor = mix(farcolor, nearcolor, nearweight / max(1e-6, totalweight)); + fragColor = (far_col + near_col + focus_col) / (near_w + focus_w + far_w); } #endif diff --git a/source/blender/draw/engines/eevee/shaders/effect_dof_vert.glsl b/source/blender/draw/engines/eevee/shaders/effect_dof_vert.glsl index 6e43115d799..ec8b474b431 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_dof_vert.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_dof_vert.glsl @@ -47,7 +47,9 @@ void main() color = texelFetch(farBuffer, texelco, 0); } /* find the area the pixel will cover and divide the color by it */ - color.a = 1.0 / (coc * coc * M_PI); + /* HACK: 4.0 out of nowhere (I suppose it's 4 pixels footprint for coc 0?) + * Makes near in focus more closer to 1.0 alpha. */ + color.a = 4.0 / (coc * coc * M_PI); color.rgb *= color.a; /* Compute edge to discard fragment that does not belong to the other layer. */ @@ -92,7 +94,9 @@ void main() gl_Position.xy += (0.5 + vec2(texelco) * 2.0) * texel_size; /* Push far plane to left side. */ - gl_Position.x += (!is_near) ? 1.0 : 0.0; + if (!is_near) { + gl_Position.x += 2.0 / 2.0; + } /* don't do smoothing for small sprites */ if (coc > 3.0) { @@ -101,6 +105,4 @@ void main() else { smoothFac = 1.0; } - - int tex_width = textureSize(cocBuffer, 0).x; } |