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:
authorClément Foucault <foucault.clem@gmail.com>2018-05-12 01:58:53 +0300
committerClément Foucault <foucault.clem@gmail.com>2018-05-13 00:28:55 +0300
commitf9cfb221d64a8f7b5bb89ee36d5ac594d6da34ff (patch)
treeadad1f71d8df8de99e58631a3cca088c64044a3a /source/blender
parent74a08cf12854308af166742f7dcaa5c7c227fcd4 (diff)
Eevee: Depth of field: Smooth out bokeh shape.
Due to the scatter operation being done at half resolution, undersampling is visible at bokeh shape edges (because of the hard cut). This commit adds a smoothing function to minimize the problem. Also optimize the bokeh shape parametrization by precomputing a lot of constants.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/draw/engines/eevee/eevee_depth_of_field.c15
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h1
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl39
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_dof_vert.glsl19
4 files changed, 51 insertions, 23 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 c17378a48e3..f4d534c4ccc 100644
--- a/source/blender/draw/engines/eevee/eevee_depth_of_field.c
+++ b/source/blender/draw/engines/eevee/eevee_depth_of_field.c
@@ -162,10 +162,15 @@ int EEVEE_depth_of_field_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *v
effects->dof_params[0] = aperture * fabsf(focal_len_scaled / (focus_dist - focal_len_scaled));
effects->dof_params[1] = -focus_dist;
effects->dof_params[2] = viewport_size[0] / sensor_scaled;
- effects->dof_bokeh[0] = blades;
- effects->dof_bokeh[1] = rotation;
- effects->dof_bokeh[2] = ratio;
- effects->dof_bokeh[3] = BKE_collection_engine_property_value_get_float(props, "bokeh_max_size");
+ effects->dof_bokeh[0] = rotation;
+ effects->dof_bokeh[1] = ratio;
+ effects->dof_bokeh[2] = BKE_collection_engine_property_value_get_float(props, "bokeh_max_size");
+
+ /* Precompute values to save instructions in fragment shader. */
+ effects->dof_bokeh_sides[0] = blades;
+ effects->dof_bokeh_sides[1] = 2.0f * M_PI / blades;
+ effects->dof_bokeh_sides[2] = blades / (2.0f * M_PI);
+ effects->dof_bokeh_sides[3] = cosf(M_PI / blades);
return EFFECT_DOF | EFFECT_POST_BUFFER;
}
@@ -219,7 +224,7 @@ void EEVEE_depth_of_field_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_
DRW_shgroup_uniform_texture_ref(grp, "colorBuffer", &effects->unf_source_buffer);
DRW_shgroup_uniform_texture_ref(grp, "cocBuffer", &effects->dof_coc);
DRW_shgroup_uniform_vec2(grp, "layerSelection", effects->dof_layer_select, 1);
- DRW_shgroup_uniform_vec4(grp, "bokehParams", effects->dof_bokeh, 1);
+ DRW_shgroup_uniform_vec4(grp, "bokehParams", effects->dof_bokeh, 2);
psl->dof_resolve = DRW_pass_create("DoF Resolve", DRW_STATE_WRITE_COLOR);
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index e8ad25527d7..d76ecea4e43 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -546,6 +546,7 @@ typedef struct EEVEE_EffectsInfo {
float dof_near_far[2];
float dof_params[3];
float dof_bokeh[4];
+ float dof_bokeh_sides[4];
float dof_layer_select[2];
int dof_target_size[2];
struct GPUTexture *dof_down_near; /* Textures from pool */
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 14ddf10f2d8..3ec36c95dfa 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl
@@ -10,12 +10,12 @@ uniform vec3 dofParams;
#define dof_distance dofParams.y
#define dof_invsensorsize dofParams.z
-uniform vec4 bokehParams;
+uniform vec4 bokehParams[2];
-#define bokeh_sides bokehParams.x /* Polygon Bokeh shape number of sides */
-#define bokeh_rotation bokehParams.y
-#define bokeh_ratio bokehParams.z
-#define bokeh_maxsize bokehParams.w
+#define bokeh_rotation bokehParams[0].x
+#define bokeh_ratio bokehParams[0].y
+#define bokeh_maxsize bokehParams[0].z
+#define bokeh_sides bokehParams[1] /* Polygon Bokeh shape number of sides (with precomputed vars) */
uniform vec2 nearFar; /* Near & far view depths values */
@@ -130,6 +130,7 @@ void main(void)
#elif defined(STEP_SCATTER)
flat in vec4 color;
+flat in float smoothFac;
/* coordinate used for calculating radius */
in vec2 particlecoord;
@@ -139,28 +140,42 @@ out vec4 fragColor;
void main(void)
{
/* Early out */
- float dist_sqrd = dot(particlecoord, particlecoord);
+ float dist_sqr = dot(particlecoord, particlecoord);
/* Circle Dof */
- if (dist_sqrd > 1.0) {
+ if (dist_sqr > 1.0) {
discard;
}
+ float dist = sqrt(dist_sqr);
+
/* Regular Polygon Dof */
- if (bokeh_sides > 0.0) {
+ if (bokeh_sides.x > 0.0) {
/* Circle parametrization */
float theta = atan(particlecoord.y, particlecoord.x) + bokeh_rotation;
- float r;
- r = cos(M_PI / bokeh_sides) /
- (cos(theta - (M_2PI / bokeh_sides) * floor((bokeh_sides * theta + M_PI) / M_2PI)));
+ /* Optimized version of :
+ * float denom = theta - (M_2PI / bokeh_sides) * floor((bokeh_sides * theta + M_PI) / M_2PI);
+ * float r = cos(M_PI / bokeh_sides) / cos(denom); */
+ float denom = theta - bokeh_sides.y * floor(bokeh_sides.z * theta + 0.5);
+ float r = bokeh_sides.w / max(1e-8, cos(denom));
+
+ /* Divide circle radial coord by the shape radius for angle theta.
+ * Giving us the new linear radius to the shape edge. */
+ dist /= r;
- if (dist_sqrd > r * r) {
+ if (dist > 1.0) {
discard;
}
}
fragColor = color;
+
+ /* 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);
+ }
}
#elif defined(STEP_RESOLVE)
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 dc34f2bd1fc..e28c957d58d 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_dof_vert.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_dof_vert.glsl
@@ -1,17 +1,17 @@
uniform vec2 layerSelection;
-uniform vec4 bokehParams;
+uniform vec4 bokehParams[2];
-#define bokeh_sides bokehParams.x /* Polygon Bokeh shape number of sides */
-#define bokeh_rotation bokehParams.y
-#define bokeh_ratio bokehParams.z
-#define bokeh_maxsize bokehParams.w
+#define bokeh_rotation bokehParams[0].x
+#define bokeh_ratio bokehParams[0].y
+#define bokeh_maxsize bokehParams[0].z
-uniform sampler2D colorBuffer;
uniform sampler2D cocBuffer;
+uniform sampler2D colorBuffer;
flat out vec4 color;
+flat out float smoothFac;
out vec2 particlecoord;
#define M_PI 3.1415926535897932384626433832795
@@ -78,4 +78,11 @@ void main()
gl_Position.xy -= 1.0 - 0.5 * texel_size; /* NDC Bottom left */
gl_Position.xy += (0.5 + vec2(texelco) * 2.0) * texel_size;
+ /* don't do smoothing for small sprites */
+ if (coc > 3.0) {
+ smoothFac = 1.0 - 1.5 / coc;
+ }
+ else {
+ smoothFac = 1.0;
+ }
}