diff options
author | Juan Linietsky <reduzio@gmail.com> | 2020-01-15 21:23:21 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2020-02-11 12:15:26 +0100 |
commit | f8b5c5f0631ac629c00795b5f3f8775c32a0368b (patch) | |
tree | f58d19c2a3480497ff37fe657dfcc76c45d556da /servers/visual/rasterizer_rd/shaders | |
parent | c05da81268ca754493e59f359ba08a60ec7092bf (diff) |
DOF fully implemented, can be edited on the fly.
Diffstat (limited to 'servers/visual/rasterizer_rd/shaders')
-rw-r--r-- | servers/visual/rasterizer_rd/shaders/bokeh_dof.glsl | 155 |
1 files changed, 137 insertions, 18 deletions
diff --git a/servers/visual/rasterizer_rd/shaders/bokeh_dof.glsl b/servers/visual/rasterizer_rd/shaders/bokeh_dof.glsl index 83e77a19fc..e4508d3c8c 100644 --- a/servers/visual/rasterizer_rd/shaders/bokeh_dof.glsl +++ b/servers/visual/rasterizer_rd/shaders/bokeh_dof.glsl @@ -15,9 +15,8 @@ layout(rgba16f, set = 0, binding = 0) uniform restrict image2D color_image; layout(set = 1, binding = 0) uniform sampler2D source_depth; #endif -#ifdef MODE_GEN_BOKEH -layout(set = 2, binding = 0) uniform sampler2D color_texture; -layout(set = 1, binding = 0) uniform sampler2D source_depth; +#if defined(MODE_BOKEH_BOX) || defined(MODE_BOKEH_HEXAGONAL) || defined(MODE_BOKEH_CIRCULAR) +layout(set = 1, binding = 0) uniform sampler2D color_texture; layout(rgba16f, set = 0, binding = 0) uniform restrict writeonly image2D bokeh_image; #endif @@ -26,7 +25,7 @@ layout(rgba16f, set = 0, binding = 0) uniform restrict image2D color_image; layout(set = 1, binding = 0) uniform sampler2D source_bokeh; #endif - +// based on https://www.shadertoy.com/view/Xd3GDl layout(push_constant, binding = 1, std430) uniform Params { @@ -37,19 +36,27 @@ layout(push_constant, binding = 1, std430) uniform Params { bool orthogonal; float blur_size; float blur_scale; - uint pad; + int blur_steps; bool blur_near_active; float blur_near_begin; float blur_near_end; bool blur_far_active; + float blur_far_begin; float blur_far_end; - uint pad2[2]; + bool second_pass; + bool half_size; + bool use_jitter; + float jitter_seed; + uint pad[2]; } params; -#ifndef MODE_COMPOSITE_BOKEH +//used to work around downsampling filter +#define DEPTH_GAP 0.0 + +#ifdef MODE_GEN_BLUR_SIZE float get_depth_at_pos(vec2 uv) { float depth = textureLod(source_depth,uv,0.0).x; @@ -61,14 +68,15 @@ float get_depth_at_pos(vec2 uv) { return depth; } + float get_blur_size(float depth) { if (params.blur_near_active && depth < params.blur_near_begin) { - return (1.0 - smoothstep(params.blur_near_end,params.blur_near_begin,depth) ) * params.blur_size; + return - (1.0 - smoothstep(params.blur_near_end,params.blur_near_begin,depth) ) * params.blur_size - DEPTH_GAP; //near blur is negative } if (params.blur_far_active && depth > params.blur_far_begin) { - return smoothstep(params.blur_far_begin,params.blur_far_end,depth) * params.blur_size; + return smoothstep(params.blur_far_begin,params.blur_far_end,depth) * params.blur_size + DEPTH_GAP; } return 0.0; @@ -78,6 +86,63 @@ float get_blur_size(float depth) { const float GOLDEN_ANGLE = 2.39996323; + +//note: uniform pdf rand [0;1[ +float hash12n(vec2 p) { + p = fract(p * vec2(5.3987, 5.4421)); + p += dot(p.yx, p.xy + vec2(21.5351, 14.3137)); + return fract(p.x * p.y * 95.4307); +} + +#if defined(MODE_BOKEH_BOX) || defined(MODE_BOKEH_HEXAGONAL) + +vec4 weighted_filter_dir(vec2 dir, vec2 uv, vec2 pixel_size) { + + dir *= pixel_size; + vec4 color = texture(color_texture,uv); + + vec4 accum = color; + float total = 1.0; + + float blur_scale = params.blur_size/float(params.blur_steps); + + if (params.use_jitter) { + uv += dir * (hash12n(uv+params.jitter_seed) - 0.5); + } + + for(int i=-params.blur_steps;i<=params.blur_steps;i++) { + + if (i==0) { + continue; + } + float radius = float(i) * blur_scale; + vec2 suv = uv + dir * radius; + radius = abs(radius); + + vec4 sample_color = texture(color_texture, suv); + float limit; + + if (sample_color.a < color.a) { + limit = abs(sample_color.a); + } else { + limit = abs(color.a); + } + + limit -= DEPTH_GAP; + + float m = smoothstep(radius-0.5, radius+0.5, limit); + + accum += mix(color, sample_color, m ); + + total += 1.0; + + } + + return accum / total; +} + +#endif + void main() { ivec2 pos = ivec2(gl_GlobalInvocationID.xy); @@ -100,14 +165,61 @@ void main() { imageStore(color_image,pos,color); #endif -#ifdef MODE_GEN_BOKEH +#ifdef MODE_BOKEH_BOX - pixel_size*=0.5; //resolution is doubled + //pixel_size*=0.5; //resolution is doubled + if (params.second_pass || !params.half_size) { + uv+=pixel_size * 0.5; //half pixel to read centers + } else { + uv+=pixel_size * 0.25; //half pixel to read centers from full res + } + + vec2 dir = (params.second_pass ? vec2(0.0,1.0) : vec2(1.0,0.0)); + + vec4 color = weighted_filter_dir(dir,uv,pixel_size); + + imageStore(bokeh_image,pos,color); + +#endif + +#ifdef MODE_BOKEH_HEXAGONAL + + + //pixel_size*=0.5; //resolution is doubled + if (params.second_pass || !params.half_size) { + uv+=pixel_size * 0.5; //half pixel to read centers + } else { + uv+=pixel_size * 0.25; //half pixel to read centers from full res + } + + vec2 dir = (params.second_pass ? normalize(vec2( 1.0, 0.577350269189626 )) : vec2(0.0,1.0)); + + vec4 color = weighted_filter_dir(dir,uv,pixel_size); + + if (params.second_pass) { + dir = normalize(vec2( -1.0, 0.577350269189626 )); + + vec4 color2 = weighted_filter_dir(dir,uv,pixel_size); + + color.rgb = min(color.rgb,color2.rgb); + color.a = (color.a + color2.a) * 0.5; + } + + imageStore(bokeh_image,pos,color); + + + +#endif + + +#ifdef MODE_BOKEH_CIRCULAR + + if (params.half_size) { + pixel_size*=0.5; //resolution is doubled + } uv+=pixel_size * 0.5; //half pixel to read centers - float depth = get_depth_at_pos(uv); - float size = get_blur_size(depth); vec4 color = texture(color_texture,uv); float accum = 1.0; float radius = params.blur_scale; @@ -116,12 +228,12 @@ void main() { vec2 suv = uv + vec2(cos(ang), sin(ang)) * pixel_size * radius; vec4 sample_color = texture(color_texture, suv); - float sample_depth = get_depth_at_pos(suv); - if (sample_depth > depth) { - sample_color.a = clamp(sample_color.a, 0.0, size*2.0); + float sample_size = abs(sample_color.a); + if (sample_color.a > color.a) { + sample_size = clamp(sample_size, 0.0, abs(color.a)*2.0); } - float m = smoothstep(radius-0.5, radius+0.5, sample_color.a); + float m = smoothstep(radius-0.5, radius+0.5, sample_size); color += mix(color/accum, sample_color, m); accum += 1.0; radius += params.blur_scale/radius; @@ -138,7 +250,14 @@ void main() { vec4 color = imageLoad(color_image,pos); vec4 bokeh = texture(source_bokeh,uv); - color.rgb = mix(color.rgb,bokeh.rgb,min(1.0,max(color.a,bokeh.a))); //blend between hires and lowres + float mix_amount; + if (bokeh.a < color.a) { + mix_amount = min(1.0,max(0.0,max(abs(color.a),abs(bokeh.a))-DEPTH_GAP)); + } else { + mix_amount = min(1.0,max(0.0,abs(color.a)-DEPTH_GAP)); + } + + color.rgb = mix(color.rgb,bokeh.rgb,mix_amount); //blend between hires and lowres color.a=0; //reset alpha imageStore(color_image,pos,color); |