summaryrefslogtreecommitdiff
path: root/servers/visual/rasterizer_rd/shaders/bokeh_dof.glsl
diff options
context:
space:
mode:
Diffstat (limited to 'servers/visual/rasterizer_rd/shaders/bokeh_dof.glsl')
-rw-r--r--servers/visual/rasterizer_rd/shaders/bokeh_dof.glsl141
1 files changed, 141 insertions, 0 deletions
diff --git a/servers/visual/rasterizer_rd/shaders/bokeh_dof.glsl b/servers/visual/rasterizer_rd/shaders/bokeh_dof.glsl
new file mode 100644
index 0000000000..7042b72d2a
--- /dev/null
+++ b/servers/visual/rasterizer_rd/shaders/bokeh_dof.glsl
@@ -0,0 +1,141 @@
+/* clang-format off */
+[compute]
+/* clang-format on */
+#version 450
+
+VERSION_DEFINES
+
+#define BLOCK_SIZE 8
+
+layout(local_size_x = BLOCK_SIZE, local_size_y = BLOCK_SIZE, local_size_z = 1) in;
+
+
+#ifdef MODE_GEN_BLUR_SIZE
+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;
+layout(rgba16f, set = 0, binding = 0) uniform restrict writeonly image2D bokeh_image;
+#endif
+
+#ifdef MODE_COMPOSITE_BOKEH
+layout(rgba16f, set = 0, binding = 0) uniform restrict image2D color_image;
+layout(set = 1, binding = 0) uniform sampler2D source_bokeh;
+#endif
+
+
+
+
+layout(push_constant, binding = 1, std430) uniform Params {
+ ivec2 size;
+ float z_far;
+ float z_near;
+
+ bool orthogonal;
+ float blur_size;
+ float blur_scale;
+ uint pad;
+
+ 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];
+
+} params;
+
+#ifndef MODE_COMPOSITE_BOKEH
+
+float get_depth_at_pos(vec2 uv) {
+ float depth = textureLod(source_depth,uv,0.0).x;
+ if (params.orthogonal) {
+ depth = ((depth + (params.z_far + params.z_near) / (params.z_far - params.z_near)) * (params.z_far - params.z_near)) / 2.0;
+ } else {
+ depth = 2.0 * params.z_near * params.z_far / (params.z_far + params.z_near - depth * (params.z_far - params.z_near));
+ }
+ return depth;
+}
+
+float get_blur_size(float depth) {
+
+ if (params.blur_near_active && depth < params.blur_near_begin) {
+ return smoothstep(params.blur_near_end,params.blur_near_begin,depth) * params.blur_size;
+ }
+
+ 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 0.0;
+}
+
+#endif
+
+const float GOLDEN_ANGLE = 2.39996323;
+
+void main() {
+
+ ivec2 pos = ivec2(gl_GlobalInvocationID.xy);
+
+ if (any(greaterThan(pos,params.size))) { //too large, do nothing
+ return;
+ }
+
+ vec2 uv = vec2(pos) / vec2(params.size);
+
+#ifdef MODE_GEN_BLUR_SIZE
+ //precompute size in alpha channel
+ float depth = get_depth_at_pos(uv);
+ float size = get_blur_size(depth);
+
+ vec4 color = imageLoad(color_image,pos);
+ color.a = size;
+ imageStore(color_image,pos,color);
+#endif
+
+#ifdef MODE_GEN_BOKEH
+
+ 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;
+ vec2 pixel_size = 1.0/vec2(params.size);
+
+ for (float ang = 0.0; radius < params.blur_size; ang += GOLDEN_ANGLE) {
+
+ 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 m = smoothstep(radius-0.5, radius+0.5, sample_color.a);
+ color += mix(color/accum, sample_color, m);
+ accum += 1.0;
+ radius += params.blur_size/radius;
+ }
+
+ color /= accum;
+
+ imageStore(bokeh_image,pos,color);
+#endif
+
+#ifdef MODE_COMPOSITE_BOKEH
+
+ vec4 color = imageLoad(color_image,pos);
+ vec4 bokeh = texture(source_bokeh,uv);
+ if (max(color.a,bokeh.a) > 0.5) { //there is some blur in this pixel, so use bokeh
+ color = bokeh;
+ }
+ color.a=0; //reset alpha
+ imageStore(color_image,pos,color);
+#endif
+
+}