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/eevee/eevee_depth_of_field.c67
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h1
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl40
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_dof_vert.glsl5
4 files changed, 85 insertions, 28 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_depth_of_field.c b/source/blender/draw/engines/eevee/eevee_depth_of_field.c
index e51fb2fd1d7..c36e8601d25 100644
--- a/source/blender/draw/engines/eevee/eevee_depth_of_field.c
+++ b/source/blender/draw/engines/eevee/eevee_depth_of_field.c
@@ -56,23 +56,32 @@
static struct {
/* Depth Of Field */
- struct GPUShader *dof_downsample_sh;
- struct GPUShader *dof_scatter_sh;
- struct GPUShader *dof_resolve_sh;
+ struct GPUShader *dof_downsample_sh[2];
+ struct GPUShader *dof_scatter_sh[2];
+ struct GPUShader *dof_resolve_sh[2];
} e_data = {NULL}; /* Engine data */
extern char datatoc_effect_dof_vert_glsl[];
extern char datatoc_effect_dof_frag_glsl[];
-static void eevee_create_shader_depth_of_field(void)
+static void eevee_create_shader_depth_of_field(const bool use_alpha)
{
- e_data.dof_downsample_sh = DRW_shader_create_fullscreen(
- datatoc_effect_dof_frag_glsl, "#define STEP_DOWNSAMPLE\n");
- e_data.dof_scatter_sh = DRW_shader_create(
+ e_data.dof_downsample_sh[use_alpha] = DRW_shader_create_fullscreen(
+ datatoc_effect_dof_frag_glsl, use_alpha ?
+ "#define USE_ALPHA_DOF\n"
+ "#define STEP_DOWNSAMPLE\n" :
+ "#define STEP_DOWNSAMPLE\n");
+ e_data.dof_scatter_sh[use_alpha] = DRW_shader_create(
datatoc_effect_dof_vert_glsl, NULL,
- datatoc_effect_dof_frag_glsl, "#define STEP_SCATTER\n");
- e_data.dof_resolve_sh = DRW_shader_create_fullscreen(
- datatoc_effect_dof_frag_glsl, "#define STEP_RESOLVE\n");
+ datatoc_effect_dof_frag_glsl, use_alpha ?
+ "#define USE_ALPHA_DOF\n"
+ "#define STEP_SCATTER\n" :
+ "#define STEP_SCATTER\n");
+ e_data.dof_resolve_sh[use_alpha] = DRW_shader_create_fullscreen(
+ datatoc_effect_dof_frag_glsl, use_alpha ?
+ "#define USE_ALPHA_DOF\n"
+ "#define STEP_RESOLVE\n" :
+ "#define STEP_RESOLVE\n");
}
int EEVEE_depth_of_field_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata, Object *camera)
@@ -86,9 +95,10 @@ int EEVEE_depth_of_field_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *v
if (scene_eval->eevee.flag & SCE_EEVEE_DOF_ENABLED) {
RegionView3D *rv3d = draw_ctx->rv3d;
+ const bool use_alpha = !DRW_state_draw_background();
- if (!e_data.dof_downsample_sh) {
- eevee_create_shader_depth_of_field();
+ if (!e_data.dof_downsample_sh[use_alpha]) {
+ eevee_create_shader_depth_of_field(use_alpha);
}
if (camera) {
@@ -101,9 +111,11 @@ int EEVEE_depth_of_field_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *v
int buffer_size[2] = {(int)viewport_size[0] / 2, (int)viewport_size[1] / 2};
- effects->dof_down_near = DRW_texture_pool_query_2D(buffer_size[0], buffer_size[1], GPU_R11F_G11F_B10F,
+ GPUTextureFormat down_format = DRW_state_draw_background() ? GPU_R11F_G11F_B10F : GPU_RGBA16F;
+
+ effects->dof_down_near = DRW_texture_pool_query_2D(buffer_size[0], buffer_size[1], down_format,
&draw_engine_eevee_type);
- effects->dof_down_far = DRW_texture_pool_query_2D(buffer_size[0], buffer_size[1], GPU_R11F_G11F_B10F,
+ effects->dof_down_far = DRW_texture_pool_query_2D(buffer_size[0], buffer_size[1], down_format,
&draw_engine_eevee_type);
effects->dof_coc = DRW_texture_pool_query_2D(buffer_size[0], buffer_size[1], GPU_RG16F,
&draw_engine_eevee_type);
@@ -120,11 +132,18 @@ int EEVEE_depth_of_field_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *v
effects->dof_blur = DRW_texture_pool_query_2D(buffer_size[0] * 2, buffer_size[1], fb_format,
&draw_engine_eevee_type);
+
GPU_framebuffer_ensure_config(&fbl->dof_scatter_fb, {
GPU_ATTACHMENT_NONE,
GPU_ATTACHMENT_TEXTURE(effects->dof_blur),
});
+ if (!DRW_state_draw_background()) {
+ effects->dof_blur_alpha = DRW_texture_pool_query_2D(buffer_size[0] * 2, buffer_size[1], GPU_R32F,
+ &draw_engine_eevee_type);
+ GPU_framebuffer_texture_attach(fbl->dof_scatter_fb, effects->dof_blur_alpha, 1, 0);
+ }
+
/* Parameters */
/* TODO UI Options */
float fstop = cam->gpu_dof.fstop;
@@ -193,10 +212,11 @@ void EEVEE_depth_of_field_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_
**/
DRWShadingGroup *grp;
struct GPUBatch *quad = DRW_cache_fullscreen_quad_get();
+ const bool use_alpha = !DRW_state_draw_background();
psl->dof_down = DRW_pass_create("DoF Downsample", DRW_STATE_WRITE_COLOR);
- grp = DRW_shgroup_create(e_data.dof_downsample_sh, psl->dof_down);
+ grp = DRW_shgroup_create(e_data.dof_downsample_sh[use_alpha], psl->dof_down);
DRW_shgroup_uniform_texture_ref(grp, "colorBuffer", &effects->source_buffer);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
DRW_shgroup_uniform_vec2(grp, "nearFar", effects->dof_near_far, 1);
@@ -209,8 +229,7 @@ void EEVEE_depth_of_field_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_
* by the vertex shader 0.4ms against 6ms with instancing */
const float *viewport_size = DRW_viewport_size_get();
const int sprite_len = ((int)viewport_size[0] / 2) * ((int)viewport_size[1] / 2); /* brackets matters */
- grp = DRW_shgroup_empty_tri_batch_create(e_data.dof_scatter_sh, psl->dof_scatter, sprite_len);
-
+ grp = DRW_shgroup_empty_tri_batch_create(e_data.dof_scatter_sh[use_alpha], psl->dof_scatter, sprite_len);
DRW_shgroup_uniform_texture_ref(grp, "nearBuffer", &effects->dof_down_near);
DRW_shgroup_uniform_texture_ref(grp, "farBuffer", &effects->dof_down_far);
DRW_shgroup_uniform_texture_ref(grp, "cocBuffer", &effects->dof_coc);
@@ -218,13 +237,17 @@ void EEVEE_depth_of_field_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_
psl->dof_resolve = DRW_pass_create("DoF Resolve", DRW_STATE_WRITE_COLOR);
- grp = DRW_shgroup_create(e_data.dof_resolve_sh, psl->dof_resolve);
+ grp = DRW_shgroup_create(e_data.dof_resolve_sh[use_alpha], psl->dof_resolve);
DRW_shgroup_uniform_texture_ref(grp, "scatterBuffer", &effects->dof_blur);
DRW_shgroup_uniform_texture_ref(grp, "colorBuffer", &effects->source_buffer);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
DRW_shgroup_uniform_vec2(grp, "nearFar", effects->dof_near_far, 1);
DRW_shgroup_uniform_vec3(grp, "dofParams", effects->dof_params, 1);
DRW_shgroup_call_add(grp, quad, NULL);
+
+ if (use_alpha) {
+ DRW_shgroup_uniform_texture_ref(grp, "scatterAlphaBuffer", &effects->dof_blur_alpha);
+ }
}
}
@@ -258,7 +281,9 @@ void EEVEE_depth_of_field_draw(EEVEE_Data *vedata)
void EEVEE_depth_of_field_free(void)
{
- DRW_SHADER_FREE_SAFE(e_data.dof_downsample_sh);
- DRW_SHADER_FREE_SAFE(e_data.dof_scatter_sh);
- DRW_SHADER_FREE_SAFE(e_data.dof_resolve_sh);
+ for (int i = 0; i < 2; ++i) {
+ DRW_SHADER_FREE_SAFE(e_data.dof_downsample_sh[i]);
+ DRW_SHADER_FREE_SAFE(e_data.dof_scatter_sh[i]);
+ DRW_SHADER_FREE_SAFE(e_data.dof_resolve_sh[i]);
+ }
}
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index 35a1211ba4a..c5d184e1a84 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -578,6 +578,7 @@ typedef struct EEVEE_EffectsInfo {
struct GPUTexture *dof_down_far;
struct GPUTexture *dof_coc;
struct GPUTexture *dof_blur;
+ struct GPUTexture *dof_blur_alpha;
/* Other */
float prev_persmat[4][4];
/* Bloom */
diff --git a/source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl
index d816d72c1e3..27517ebd86e 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl
@@ -77,6 +77,14 @@ void main(void)
vec4 near_weights = step(THRESHOLD, coc_near) * clamp(1.0 - abs(cocData.x - coc_near), 0.0, 1.0);
vec4 far_weights = step(THRESHOLD, coc_far) * clamp(1.0 - abs(cocData.y - coc_far), 0.0, 1.0);
+# ifdef USE_ALPHA_DOF
+ /* Premult */
+ color1.rgb *= color1.a;
+ color2.rgb *= color2.a;
+ color3.rgb *= color3.a;
+ color4.rgb *= color4.a;
+# endif
+
/* now write output to weighted buffers. */
nearColor = weighted_sum(color1, color2, color3, color4, near_weights);
farColor = weighted_sum(color1, color2, color3, color4, far_weights);
@@ -85,12 +93,16 @@ void main(void)
#elif defined(STEP_SCATTER)
flat in vec4 color;
+flat in float weight;
flat in float smoothFac;
flat in ivec2 edge;
/* coordinate used for calculating radius */
in vec2 particlecoord;
-out vec4 fragColor;
+layout(location = 0) out vec4 fragColor;
+# ifdef USE_ALPHA_DOF
+layout(location = 1) out float fragAlpha;
+# endif
/* accumulate color in the near/far blur buffers */
void main(void)
@@ -130,9 +142,14 @@ void main(void)
/* Smooth the edges a bit. This effectively reduce the bokeh shape
* but does fade out the undersampling artifacts. */
- if (smoothFac < 1.0) {
- fragColor *= smoothstep(1.0, smoothFac, dist);
- }
+ float shape = smoothstep(1.0, min(0.999, smoothFac), dist);
+
+ fragColor *= shape;
+
+# ifdef USE_ALPHA_DOF
+ fragAlpha = fragColor.a;
+ fragColor.a = weight * shape;
+# endif
}
#elif defined(STEP_RESOLVE)
@@ -140,6 +157,7 @@ void main(void)
#define MERGE_THRESHOLD 4.0
uniform sampler2D scatterBuffer;
+uniform sampler2D scatterAlphaBuffer;
in vec4 uvcoordsvar;
out vec4 fragColor;
@@ -203,9 +221,21 @@ void main(void)
float far_w = far_col.a;
float near_w = near_col.a;
float focus_w = 1.0 - smoothstep(1.0, MERGE_THRESHOLD, abs(coc_signed));
+ float inv_weight_sum = 1.0 / (near_w + focus_w + far_w);
+
focus_col *= focus_w; /* Premul */
- fragColor = (far_col + near_col + focus_col) / (near_w + focus_w + far_w);
+# ifdef USE_ALPHA_DOF
+ near_col.a = upsample_filter(scatterAlphaBuffer, near_uv, texelSize).r;
+ far_col.a = upsample_filter(scatterAlphaBuffer, far_uv, texelSize).r;
+# endif
+
+ fragColor = (far_col + near_col + focus_col) * inv_weight_sum;
+
+# ifdef USE_ALPHA_DOF
+ /* Unpremult */
+ fragColor.rgb /= (fragColor.a > 0.0) ? fragColor.a : 1.0;
+# endif
}
#endif
diff --git a/source/blender/draw/engines/eevee/shaders/effect_dof_vert.glsl b/source/blender/draw/engines/eevee/shaders/effect_dof_vert.glsl
index ec8b474b431..92fd36f684a 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_dof_vert.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_dof_vert.glsl
@@ -10,6 +10,7 @@ uniform sampler2D farBuffer;
uniform sampler2D cocBuffer;
flat out vec4 color;
+flat out float weight;
flat out float smoothFac;
flat out ivec2 edge;
out vec2 particlecoord;
@@ -49,8 +50,8 @@ void main()
/* find the area the pixel will cover and divide the color by it */
/* HACK: 4.0 out of nowhere (I suppose it's 4 pixels footprint for coc 0?)
* Makes near in focus more closer to 1.0 alpha. */
- color.a = 4.0 / (coc * coc * M_PI);
- color.rgb *= color.a;
+ weight = 4.0 / (coc * coc * M_PI);
+ color *= weight;
/* Compute edge to discard fragment that does not belong to the other layer. */
edge.x = (is_near) ? 1 : -1;