[Bf-blender-cvs] [f9cfb221d64] blender2.8: Eevee: Depth of field: Smooth out bokeh shape.

Clément Foucault noreply at git.blender.org
Sat May 12 23:24:59 CEST 2018


Commit: f9cfb221d64a8f7b5bb89ee36d5ac594d6da34ff
Author: Clément Foucault
Date:   Sat May 12 00:58:53 2018 +0200
Branches: blender2.8
https://developer.blender.org/rBf9cfb221d64a8f7b5bb89ee36d5ac594d6da34ff

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.

===================================================================

M	source/blender/draw/engines/eevee/eevee_depth_of_field.c
M	source/blender/draw/engines/eevee/eevee_private.h
M	source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl
M	source/blender/draw/engines/eevee/shaders/effect_dof_vert.glsl

===================================================================

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;
+	}
 }



More information about the Bf-blender-cvs mailing list