summaryrefslogtreecommitdiff
path: root/servers/visual/rasterizer_rd/shaders
diff options
context:
space:
mode:
authorJuan Linietsky <reduzio@gmail.com>2020-01-15 21:23:21 -0300
committerJuan Linietsky <reduzio@gmail.com>2020-02-11 12:15:26 +0100
commitf8b5c5f0631ac629c00795b5f3f8775c32a0368b (patch)
treef58d19c2a3480497ff37fe657dfcc76c45d556da /servers/visual/rasterizer_rd/shaders
parentc05da81268ca754493e59f359ba08a60ec7092bf (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.glsl155
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);