Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl182
-rw-r--r--source/blender/draw/engines/workbench/workbench_deferred.c7
-rw-r--r--source/blender/draw/engines/workbench/workbench_effect_dof.c49
-rw-r--r--source/blender/draw/engines/workbench/workbench_private.h7
4 files changed, 175 insertions, 70 deletions
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl
index 8d2cd719c25..0185e192f5c 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl
@@ -8,6 +8,7 @@ uniform mat4 ProjectionMatrix;
uniform vec2 invertedViewportSize;
uniform vec2 nearFar;
uniform vec3 dofParams;
+uniform float noiseOffset;
uniform sampler2D inputCocTex;
uniform sampler2D maxCocTilesTex;
uniform sampler2D sceneColorTex;
@@ -15,6 +16,7 @@ uniform sampler2D sceneDepthTex;
uniform sampler2D backgroundTex;
uniform sampler2D halfResColorTex;
uniform sampler2D blurTex;
+uniform sampler2D noiseTex;
#define dof_aperturesize dofParams.x
#define dof_distance dofParams.y
@@ -57,7 +59,6 @@ void main()
vec4 color3 = texelFetch(sceneColorTex, texel.zy, 0);
vec4 color4 = texelFetch(sceneColorTex, texel.xw, 0);
- vec3 ofs = vec3(invertedViewportSize.xy, 0.0);
vec4 depths;
depths.x = texelFetch(sceneDepthTex, texel.xy, 0).x;
depths.y = texelFetch(sceneDepthTex, texel.zw, 0).x;
@@ -77,15 +78,61 @@ void main()
vec4 far_weights = step(0.0, cocs_far) * clamp(1.0 - abs(coc_far - cocs_far), 0.0, 1.0);
/* now write output to weighted buffers. */
- vec4 w = near_weights + far_weights;
+ /* Take far plane pixels in priority. */
+ vec4 w = any(notEqual(far_weights, vec4(0.0))) ? far_weights : near_weights;
float tot_weight = dot(w, vec4(1.0));
halfResColor = weighted_sum(color1, color2, color3, color4, w, tot_weight);
+ halfResColor = clamp(halfResColor, 0.0, 3.0);
normalizedCoc = encode_coc(coc_near, coc_far);
}
#endif
/**
+ * ----------------- STEP 0.5 ------------------
+ * Custom Coc aware downsampling. Quater res pass.
+ **/
+#ifdef DOWNSAMPLE
+
+layout(location = 0) out vec4 outColor;
+layout(location = 1) out vec2 outCocs;
+
+void main()
+{
+ ivec4 texel = ivec4(gl_FragCoord.xyxy) * 2 + ivec4(0, 0, 1, 1);
+
+ vec4 color1 = texelFetch(sceneColorTex, texel.xy, 0);
+ vec4 color2 = texelFetch(sceneColorTex, texel.zw, 0);
+ vec4 color3 = texelFetch(sceneColorTex, texel.zy, 0);
+ vec4 color4 = texelFetch(sceneColorTex, texel.xw, 0);
+
+ vec4 depths;
+ vec2 cocs1 = texelFetch(inputCocTex, texel.xy, 0).rg;
+ vec2 cocs2 = texelFetch(inputCocTex, texel.zw, 0).rg;
+ vec2 cocs3 = texelFetch(inputCocTex, texel.zy, 0).rg;
+ vec2 cocs4 = texelFetch(inputCocTex, texel.xw, 0).rg;
+
+ vec4 cocs_near = vec4(cocs1.r, cocs2.r, cocs3.r, cocs4.r) * MAX_COC_SIZE;
+ vec4 cocs_far = vec4(cocs1.g, cocs2.g, cocs3.g, cocs4.g) * MAX_COC_SIZE;
+
+ float coc_near = max_v4(cocs_near);
+ float coc_far = max_v4(cocs_far);
+
+ /* 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(0.0, cocs_near) * clamp(1.0 - abs(coc_near - cocs_near), 0.0, 1.0);
+ vec4 far_weights = step(0.0, cocs_far) * clamp(1.0 - abs(coc_far - cocs_far), 0.0, 1.0);
+
+ /* now write output to weighted buffers. */
+ vec4 w = any(notEqual(far_weights, vec4(0.0))) ? far_weights : near_weights;
+ float tot_weight = dot(w, vec4(1.0));
+ outColor = weighted_sum(color1, color2, color3, color4, w, tot_weight);
+
+ outCocs = encode_coc(coc_near, coc_far);
+}
+#endif
+
+/**
* ----------------- STEP 1 ------------------
* Flatten COC buffer using max filter.
**/
@@ -168,42 +215,17 @@ layout(std140) uniform dofSamplesBlock {
vec4 samples[NUM_SAMPLES];
};
-#if 0 /* Spilar sampling. Better but slower */
-void main()
+vec2 get_random_vector(float offset)
{
- /* Half Res pass */
- vec2 uv = gl_FragCoord.xy * invertedViewportSize * 2.0;
-
- vec2 size = vec2(textureSize(halfResColorTex, 0).xy);
- ivec2 texel = ivec2(uv * size);
-
- vec4 color = texelFetch(halfResColorTex, texel, 0);
- float coc = decode_signed_coc(texelFetch(inputCocTex, texel, 0).rg);
-
- /* TODO Ensure alignement */
- vec2 max_radii = texture(maxCocTilesTex, (0.5 + floor(gl_FragCoord.xy / 8.0)) / vec2(textureSize(maxCocTilesTex, 0))).rg;
- float max_radius = decode_coc(max_radii);
-
- float center_coc = coc;
- float tot = 1.0;
-
- for (int i = 0; i < NUM_SAMPLES; ++i) {
- vec2 tc = uv + samples[i].xy * invertedViewportSize * max_radius;
-
- vec4 samp = texture(halfResColorTex, tc);
- coc = decode_signed_coc(texture(inputCocTex, tc).rg);
- if (coc > center_coc) {
- coc = clamp(abs(coc), 0.0, abs(center_coc) * 2.0);
- }
- float radius = max_radius * float(i + 1) / float(NUM_SAMPLES);
- float m = smoothstep(radius - 0.5, radius + 0.5, abs(coc));
- color += mix(color / tot, samp, m);
- tot += 1.0;
- }
-
- blurColor = color / tot;
+ /* Interlieved gradient noise by Jorge Jimenez
+ * http://www.iryoku.com/next-generation-post-processing-in-call-of-duty-advanced-warfare */
+ float ign = fract(offset + 52.9829189 * fract(0.06711056 * gl_FragCoord.x + 0.00583715 * gl_FragCoord.y));
+ float bn = texelFetch(noiseTex, ivec2(gl_FragCoord.xy) % 64, 0).a;
+ float ang = M_PI * 2.0 * fract(bn + offset);
+ return vec2(cos(ang), sin(ang)) * sqrt(ign);
+ // return noise.rg * sqrt(ign);
}
-#else
+
void main()
{
vec2 uv = gl_FragCoord.xy * invertedViewportSize * 2.0;
@@ -216,15 +238,18 @@ void main()
float coc = decode_coc(texelFetch(inputCocTex, texel, 0).rg);
float max_radius = coc;
+ vec2 noise = get_random_vector(noiseOffset) * 0.2 * clamp(max_radius * 0.2 - 4.0, 0.0, 1.0);
for (int i = 0; i < NUM_SAMPLES; ++i) {
- vec2 tc = uv + samples[i].xy * invertedViewportSize * max_radius;
+ vec2 tc = uv + (noise + samples[i].xy) * invertedViewportSize * max_radius;
- vec4 samp = texture(halfResColorTex, tc);
+ /* decode_signed_coc return biggest coc. */
+ coc = abs(decode_signed_coc(texture(inputCocTex, tc).rg));
- coc = decode_coc(texture(inputCocTex, tc).rg);
+ float lod = log2(clamp((coc + min(coc, max_radius)) * 0.5 - 21.0, 0.0, 16.0) * 0.25);
+ vec4 samp = textureLod(halfResColorTex, tc, lod);
float radius = samples[i].z * max_radius;
- float weight = coc * smoothstep(radius - 0.5, radius + 0.5, coc);
+ float weight = abs(coc) * smoothstep(radius - 0.5, radius + 0.5, abs(coc));
color += samp * weight;
tot += weight;
@@ -233,11 +258,38 @@ void main()
blurColor = color / tot;
}
#endif
-#endif
/**
* ----------------- STEP 3 ------------------
- * Additional 3x3 blur
+ * 3x3 Median Filter
+ * Morgan McGuire and Kyle Whitson
+ * http://graphics.cs.williams.edu
+ *
+ *
+ * Copyright (c) Morgan McGuire and Williams College, 2006
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**/
#ifdef BLUR2
out vec4 finalColor;
@@ -252,18 +304,42 @@ void main()
* since this filter is not weighted by CoC
* and can bleed a bit. */
float rad = clamp(coc - 9.0, 0.0, 1.0);
- rad *= 1.5; /* If not, it's a gaussian filter. */
- finalColor = texture(blurTex, uv + pixel_size * vec2(-1.0, -1.0) * rad);
- finalColor += texture(blurTex, uv + pixel_size * vec2(-1.0, 0.0) * rad);
- finalColor += texture(blurTex, uv + pixel_size * vec2(-1.0, 1.0) * rad);
- finalColor += texture(blurTex, uv + pixel_size * vec2( 0.0, -1.0) * rad);
- finalColor += texture(blurTex, uv + pixel_size * vec2( 0.0, 0.0) * rad);
- finalColor += texture(blurTex, uv + pixel_size * vec2( 0.0, 1.0) * rad);
- finalColor += texture(blurTex, uv + pixel_size * vec2( 1.0, -1.0) * rad);
- finalColor += texture(blurTex, uv + pixel_size * vec2( 1.0, 0.0) * rad);
- finalColor += texture(blurTex, uv + pixel_size * vec2( 1.0, 1.0) * rad);
- finalColor *= 1.0 / 9.0;
+
+#define vec vec4
+#define toVec(x) x.rgba
+
+#define s2(a, b) temp = a; a = min(a, b); b = max(temp, b);
+#define mn3(a, b, c) s2(a, b); s2(a, c);
+#define mx3(a, b, c) s2(b, c); s2(a, c);
+
+#define mnmx3(a, b, c) mx3(a, b, c); s2(a, b); // 3 exchanges
+#define mnmx4(a, b, c, d) s2(a, b); s2(c, d); s2(a, c); s2(b, d); // 4 exchanges
+#define mnmx5(a, b, c, d, e) s2(a, b); s2(c, d); mn3(a, c, e); mx3(b, d, e); // 6 exchanges
+#define mnmx6(a, b, c, d, e, f) s2(a, d); s2(b, e); s2(c, f); mn3(a, b, c); mx3(d, e, f); // 7 exchanges
+
+ vec v[9];
+
+ /* Add the pixels which make up our window to the pixel array. */
+ for(int dX = -1; dX <= 1; ++dX) {
+ for(int dY = -1; dY <= 1; ++dY) {
+ vec2 offset = vec2(float(dX), float(dY));
+ /* If a pixel in the window is located at (x+dX, y+dY), put it at index (dX + R)(2R + 1) + (dY + R) of the
+ * pixel array. This will fill the pixel array, with the top left pixel of the window at pixel[0] and the
+ * bottom right pixel of the window at pixel[N-1]. */
+ v[(dX + 1) * 3 + (dY + 1)] = toVec(texture(blurTex, uv + offset * pixel_size * rad));
+ }
+ }
+
+ vec temp;
+
+ /* Starting with a subset of size 6, remove the min and max each time */
+ mnmx6(v[0], v[1], v[2], v[3], v[4], v[5]);
+ mnmx5(v[1], v[2], v[3], v[4], v[6]);
+ mnmx4(v[2], v[3], v[4], v[7]);
+ mnmx3(v[3], v[4], v[8]);
+ toVec(finalColor) = v[4];
}
+
#endif
/**
diff --git a/source/blender/draw/engines/workbench/workbench_deferred.c b/source/blender/draw/engines/workbench/workbench_deferred.c
index 0e8981ed4a1..2e421595998 100644
--- a/source/blender/draw/engines/workbench/workbench_deferred.c
+++ b/source/blender/draw/engines/workbench/workbench_deferred.c
@@ -305,7 +305,7 @@ static float *create_disk_samples(int num_samples, int num_iterations)
static struct GPUTexture *create_jitter_texture(int num_samples)
{
- float jitter[64 * 64][3];
+ float jitter[64 * 64][4];
const float num_samples_inv = 1.0f / num_samples;
for (int i = 0; i < 64 * 64; i++) {
@@ -317,11 +317,12 @@ static struct GPUTexture *create_jitter_texture(int num_samples)
float bn = blue_noise[i][1] - 0.5f;
CLAMP(bn, -0.499f, 0.499f); /* fix fireflies */
jitter[i][2] = bn * num_samples_inv;
+ jitter[i][3] = blue_noise[i][1];
}
UNUSED_VARS(bsdf_split_sum_ggx, btdf_split_sum_ggx, ltc_mag_ggx, ltc_mat_ggx, ltc_disk_integral);
- return DRW_texture_create_2D(64, 64, GPU_RGB16F, DRW_TEX_FILTER | DRW_TEX_WRAP, &jitter[0][0]);
+ return DRW_texture_create_2D(64, 64, GPU_RGBA16F, DRW_TEX_FILTER | DRW_TEX_WRAP, &jitter[0][0]);
}
/* Functions */
@@ -524,7 +525,7 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata)
}
{
- workbench_dof_create_pass(vedata, &e_data.composite_buffer_tx);
+ workbench_dof_create_pass(vedata, &e_data.composite_buffer_tx, e_data.jitter_tx);
}
if (CAVITY_ENABLED(wpd)) {
diff --git a/source/blender/draw/engines/workbench/workbench_effect_dof.c b/source/blender/draw/engines/workbench/workbench_effect_dof.c
index ec8c184eac5..85bb5ba0522 100644
--- a/source/blender/draw/engines/workbench/workbench_effect_dof.c
+++ b/source/blender/draw/engines/workbench/workbench_effect_dof.c
@@ -33,6 +33,7 @@
/* *********** STATIC *********** */
static struct {
struct GPUShader *effect_dof_prepare_sh;
+ struct GPUShader *effect_dof_downsample_sh;
struct GPUShader *effect_dof_flatten_v_sh;
struct GPUShader *effect_dof_flatten_h_sh;
struct GPUShader *effect_dof_dilate_v_sh;
@@ -130,6 +131,7 @@ static void workbench_dof_setup_samples(
void workbench_dof_engine_init(WORKBENCH_Data *vedata, Object *camera)
{
+ WORKBENCH_TextureList *txl = vedata->txl;
WORKBENCH_StorageList *stl = vedata->stl;
WORKBENCH_PrivateData *wpd = stl->g_data;
WORKBENCH_FramebufferList *fbl = vedata->fbl;
@@ -146,6 +148,10 @@ void workbench_dof_engine_init(WORKBENCH_Data *vedata, Object *camera)
datatoc_workbench_effect_dof_frag_glsl,
"#define PREPARE\n");
+ e_data.effect_dof_downsample_sh = DRW_shader_create_fullscreen(
+ datatoc_workbench_effect_dof_frag_glsl,
+ "#define DOWNSAMPLE\n");
+
e_data.effect_dof_flatten_v_sh = DRW_shader_create_fullscreen(
datatoc_workbench_effect_dof_frag_glsl,
"#define FLATTEN_VERTICAL\n");
@@ -183,9 +189,9 @@ void workbench_dof_engine_init(WORKBENCH_Data *vedata, Object *camera)
int shrink_w_size[2] = {shrink_h_size[0], ceilf(size[1] / 8.0f)};
#endif
- wpd->half_res_col_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_R11F_G11F_B10F, &draw_engine_workbench_solid);
+ DRW_texture_ensure_2D(&txl->dof_source_tx, size[0], size[1], GPU_R11F_G11F_B10F, DRW_TEX_FILTER | DRW_TEX_MIPMAP);
+ DRW_texture_ensure_2D(&txl->coc_halfres_tx, size[0], size[1], GPU_RG8, DRW_TEX_FILTER | DRW_TEX_MIPMAP);
wpd->dof_blur_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_R11F_G11F_B10F, &draw_engine_workbench_solid);
- wpd->coc_halfres_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_RG8, &draw_engine_workbench_solid);
#if 0
wpd->coc_temp_tx = DRW_texture_pool_query_2D(shrink_h_size[0], shrink_h_size[1], GPU_RG8, &draw_engine_workbench_solid);
wpd->coc_tiles_tx[0] = DRW_texture_pool_query_2D(shrink_w_size[0], shrink_w_size[1], GPU_RG8, &draw_engine_workbench_solid);
@@ -194,8 +200,8 @@ void workbench_dof_engine_init(WORKBENCH_Data *vedata, Object *camera)
GPU_framebuffer_ensure_config(&fbl->dof_downsample_fb, {
GPU_ATTACHMENT_NONE,
- GPU_ATTACHMENT_TEXTURE(wpd->half_res_col_tx),
- GPU_ATTACHMENT_TEXTURE(wpd->coc_halfres_tx),
+ GPU_ATTACHMENT_TEXTURE(txl->dof_source_tx),
+ GPU_ATTACHMENT_TEXTURE(txl->coc_halfres_tx),
});
#if 0
GPU_framebuffer_ensure_config(&fbl->dof_coc_tile_h_fb, {
@@ -217,7 +223,7 @@ void workbench_dof_engine_init(WORKBENCH_Data *vedata, Object *camera)
});
GPU_framebuffer_ensure_config(&fbl->dof_blur2_fb, {
GPU_ATTACHMENT_NONE,
- GPU_ATTACHMENT_TEXTURE(wpd->half_res_col_tx),
+ GPU_ATTACHMENT_TEXTURE(txl->dof_source_tx),
});
{
@@ -276,9 +282,10 @@ void workbench_dof_engine_init(WORKBENCH_Data *vedata, Object *camera)
wpd->dof_enabled = true;
}
-void workbench_dof_create_pass(WORKBENCH_Data *vedata, GPUTexture **dof_input)
+void workbench_dof_create_pass(WORKBENCH_Data *vedata, GPUTexture **dof_input, GPUTexture *noise_tex)
{
WORKBENCH_PassList *psl = vedata->psl;
+ WORKBENCH_TextureList *txl = vedata->txl;
WORKBENCH_StorageList *stl = vedata->stl;
WORKBENCH_PrivateData *wpd = stl->g_data;
struct GPUBatch *quad = DRW_cache_fullscreen_quad_get();
@@ -290,6 +297,7 @@ void workbench_dof_create_pass(WORKBENCH_Data *vedata, GPUTexture **dof_input)
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
psl->dof_down_ps = DRW_pass_create("DoF DownSample", DRW_STATE_WRITE_COLOR);
+ psl->dof_down2_ps = DRW_pass_create("DoF DownSample", DRW_STATE_WRITE_COLOR);
psl->dof_flatten_h_ps = DRW_pass_create("DoF Flatten Coc H", DRW_STATE_WRITE_COLOR);
psl->dof_flatten_v_ps = DRW_pass_create("DoF Flatten Coc V", DRW_STATE_WRITE_COLOR);
psl->dof_dilate_h_ps = DRW_pass_create("DoF Dilate Coc H", DRW_STATE_WRITE_COLOR);
@@ -307,10 +315,17 @@ void workbench_dof_create_pass(WORKBENCH_Data *vedata, GPUTexture **dof_input)
DRW_shgroup_uniform_vec2(grp, "nearFar", wpd->dof_near_far, 1);
DRW_shgroup_call_add(grp, quad, NULL);
}
+
+ {
+ DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_dof_downsample_sh, psl->dof_down2_ps);
+ DRW_shgroup_uniform_texture(grp, "sceneColorTex", txl->dof_source_tx);
+ DRW_shgroup_uniform_texture(grp, "inputCocTex", txl->coc_halfres_tx);
+ DRW_shgroup_call_add(grp, quad, NULL);
+ }
#if 0
{
DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_dof_flatten_h_sh, psl->dof_flatten_h_ps);
- DRW_shgroup_uniform_texture(grp, "inputCocTex", wpd->coc_halfres_tx);
+ DRW_shgroup_uniform_texture(grp, "inputCocTex", txl->coc_halfres_tx);
DRW_shgroup_call_add(grp, quad, NULL);
}
{
@@ -330,23 +345,26 @@ void workbench_dof_create_pass(WORKBENCH_Data *vedata, GPUTexture **dof_input)
}
#endif
{
+ float offset = stl->effects->jitter_index / (float)workbench_taa_calculate_num_iterations(vedata);
DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_dof_blur1_sh, psl->dof_blur1_ps);
DRW_shgroup_uniform_block(grp, "dofSamplesBlock", wpd->dof_ubo);
- DRW_shgroup_uniform_texture(grp, "inputCocTex", wpd->coc_halfres_tx);
- DRW_shgroup_uniform_texture(grp, "halfResColorTex", wpd->half_res_col_tx);
+ DRW_shgroup_uniform_texture(grp, "noiseTex", noise_tex);
+ DRW_shgroup_uniform_texture(grp, "inputCocTex", txl->coc_halfres_tx);
+ DRW_shgroup_uniform_texture(grp, "halfResColorTex", txl->dof_source_tx);
DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
+ DRW_shgroup_uniform_float_copy(grp, "noiseOffset", offset);
DRW_shgroup_call_add(grp, quad, NULL);
}
{
DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_dof_blur2_sh, psl->dof_blur2_ps);
- DRW_shgroup_uniform_texture(grp, "inputCocTex", wpd->coc_halfres_tx);
+ DRW_shgroup_uniform_texture(grp, "inputCocTex", txl->coc_halfres_tx);
DRW_shgroup_uniform_texture(grp, "blurTex", wpd->dof_blur_tx);
DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
DRW_shgroup_call_add(grp, quad, NULL);
}
{
DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_dof_resolve_sh, psl->dof_resolve_ps);
- DRW_shgroup_uniform_texture(grp, "halfResColorTex", wpd->half_res_col_tx);
+ DRW_shgroup_uniform_texture(grp, "halfResColorTex", txl->dof_source_tx);
DRW_shgroup_uniform_texture(grp, "sceneDepthTex", dtxl->depth);
DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
DRW_shgroup_uniform_vec3(grp, "dofParams", &wpd->dof_aperturesize, 1);
@@ -358,6 +376,7 @@ void workbench_dof_create_pass(WORKBENCH_Data *vedata, GPUTexture **dof_input)
void workbench_dof_engine_free(void)
{
DRW_SHADER_FREE_SAFE(e_data.effect_dof_prepare_sh);
+ DRW_SHADER_FREE_SAFE(e_data.effect_dof_downsample_sh);
DRW_SHADER_FREE_SAFE(e_data.effect_dof_flatten_v_sh);
DRW_SHADER_FREE_SAFE(e_data.effect_dof_flatten_h_sh);
DRW_SHADER_FREE_SAFE(e_data.effect_dof_dilate_v_sh);
@@ -367,6 +386,12 @@ void workbench_dof_engine_free(void)
DRW_SHADER_FREE_SAFE(e_data.effect_dof_resolve_sh);
}
+static void workbench_dof_downsample_level(void *userData, int UNUSED(level))
+{
+ WORKBENCH_PassList *psl = (WORKBENCH_PassList *)userData;
+ DRW_draw_pass(psl->dof_down2_ps);
+}
+
void workbench_dof_draw_pass(WORKBENCH_Data *vedata)
{
WORKBENCH_FramebufferList *fbl = vedata->fbl;
@@ -383,6 +408,8 @@ void workbench_dof_draw_pass(WORKBENCH_Data *vedata)
GPU_framebuffer_bind(fbl->dof_downsample_fb);
DRW_draw_pass(psl->dof_down_ps);
+ GPU_framebuffer_recursive_downsample(fbl->dof_downsample_fb, 2, workbench_dof_downsample_level, psl);
+
#if 0
GPU_framebuffer_bind(fbl->dof_coc_tile_h_fb);
DRW_draw_pass(psl->dof_flatten_h_ps);
diff --git a/source/blender/draw/engines/workbench/workbench_private.h b/source/blender/draw/engines/workbench/workbench_private.h
index ef114370587..35cd9571711 100644
--- a/source/blender/draw/engines/workbench/workbench_private.h
+++ b/source/blender/draw/engines/workbench/workbench_private.h
@@ -108,6 +108,8 @@ typedef struct WORKBENCH_FramebufferList {
} WORKBENCH_FramebufferList;
typedef struct WORKBENCH_TextureList {
+ struct GPUTexture *dof_source_tx;
+ struct GPUTexture *coc_halfres_tx;
struct GPUTexture *history_buffer_tx;
struct GPUTexture *depth_buffer_tx;
} WORKBENCH_TextureList;
@@ -138,6 +140,7 @@ typedef struct WORKBENCH_PassList {
struct DRWPass *ghost_resolve_pass;
struct DRWPass *effect_aa_pass;
struct DRWPass *dof_down_ps;
+ struct DRWPass *dof_down2_ps;
struct DRWPass *dof_flatten_v_ps;
struct DRWPass *dof_flatten_h_ps;
struct DRWPass *dof_dilate_h_ps;
@@ -235,9 +238,7 @@ typedef struct WORKBENCH_PrivateData {
float ssao_settings[4];
/* Dof */
- struct GPUTexture *half_res_col_tx;
struct GPUTexture *dof_blur_tx;
- struct GPUTexture *coc_halfres_tx;
struct GPUTexture *coc_temp_tx;
struct GPUTexture *coc_tiles_tx[2];
struct GPUUniformBuffer *dof_ubo;
@@ -337,7 +338,7 @@ int workbench_taa_calculate_num_iterations(WORKBENCH_Data *vedata);
/* workbench_effect_dof.c */
void workbench_dof_engine_init(WORKBENCH_Data *vedata, Object *camera);
void workbench_dof_engine_free(void);
-void workbench_dof_create_pass(WORKBENCH_Data *vedata, GPUTexture **dof_input);
+void workbench_dof_create_pass(WORKBENCH_Data *vedata, GPUTexture **dof_input, GPUTexture *noise_tex);
void workbench_dof_draw_pass(WORKBENCH_Data *vedata);
/* workbench_materials.c */