diff --git a/resources/core/shader/dof_coc_fs.sc b/resources/core/shader/dof_coc_fs.sc new file mode 100644 index 0000000..e78ada9 --- /dev/null +++ b/resources/core/shader/dof_coc_fs.sc @@ -0,0 +1,53 @@ +// spiral sampling from https://blog.voxagon.se/2018/05/04/bokeh-depth-of-field-in-single-pass.html + +#include + +SAMPLER2D(u_color, 0); +SAMPLER2D(u_attr0, 1); + +uniform vec4 u_params; // x: focus point, y: focus_length + +#define GOLDEN_ANGLE 2.39996323 +#define MAX_BLUR_SIZE 20.0 +#define RAD_SCALE 0.75 // Smaller = nicer blur, larger = faster + +float ComputeCoC(float depth) { + return clamp(abs(depth - u_params.x) / u_params.y, 0.0, 1.0) * MAX_BLUR_SIZE; +} + +void main() { + // reference pixel + vec2 uv = gl_FragCoord.xy / uResolution.xy; + vec4 ref_color = texture2D(u_color, uv); + float ref_depth = texture2D(u_attr0, uv).w; + + float ref_coc = ComputeCoC(ref_depth); + + // sample CoC + float smp_count = 1.0; + vec4 dof_out = ref_color; + + float radius = RAD_SCALE; + + for (float a = 0.0; radius < MAX_BLUR_SIZE; a += GOLDEN_ANGLE) { + vec2 smp_uv = (gl_FragCoord.xy + vec2(cos(a) * radius, sin(a) * radius)) / uResolution.xy; + + float smp_depth = texture2D(u_attr0, smp_uv).w; + vec4 smp_color = texture2D(u_color, smp_uv); + + float coc = ref_coc; + + if (smp_depth <= ref_depth) { + float smp_coc = ComputeCoC(smp_depth); + coc = min(ref_coc, smp_coc); + } + + float k = smoothstep(radius - 0.5, radius + 0.5, coc); + dof_out += mix(dof_out / smp_count, smp_color, k); + + smp_count += 1.0; + radius += RAD_SCALE / radius; + } + + gl_FragColor = dof_out / smp_count; +} diff --git a/resources/core/shader/dof_coc_varying.def b/resources/core/shader/dof_coc_varying.def new file mode 100644 index 0000000..8fdde79 --- /dev/null +++ b/resources/core/shader/dof_coc_varying.def @@ -0,0 +1,4 @@ +vec2 v_texcoord0 : TEXCOORD0; + +vec3 a_position : POSITION; +vec2 a_texcoord0 : TEXCOORD0; diff --git a/resources/core/shader/dof_coc_vs.sc b/resources/core/shader/dof_coc_vs.sc new file mode 100644 index 0000000..968f4f2 --- /dev/null +++ b/resources/core/shader/dof_coc_vs.sc @@ -0,0 +1,8 @@ +$input a_position, a_texcoord0 + +// HARFANG(R) Copyright (C) 2022 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details. +#include + +void main() { + gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0)); +}