[Bf-blender-cvs] [0aa2a662b91] blender2.8: Eevee: Add Bloom post process.

Clément Foucault noreply at git.blender.org
Sun May 7 15:52:03 CEST 2017


Commit: 0aa2a662b91a33c6457408a02f92cfdb82bcaaee
Author: Clément Foucault
Date:   Sun May 7 14:27:43 2017 +0200
Branches: blender2.8
https://developer.blender.org/rB0aa2a662b91a33c6457408a02f92cfdb82bcaaee

Eevee: Add Bloom post process.

Based on Kino/Bloom v2 - Bloom filter for Unity
MIT license.

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

M	source/blender/draw/CMakeLists.txt
M	source/blender/draw/engines/eevee/eevee_effects.c
M	source/blender/draw/engines/eevee/eevee_private.h
A	source/blender/draw/engines/eevee/shaders/effect_bloom_frag.glsl
M	source/blender/draw/intern/draw_manager.c

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

diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 64371d74960..0b229ecee8d 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -114,6 +114,7 @@ data_to_c_simple(engines/eevee/shaders/default_world_frag.glsl SRC)
 data_to_c_simple(engines/eevee/shaders/background_vert.glsl SRC)
 data_to_c_simple(engines/eevee/shaders/lit_surface_frag.glsl SRC)
 data_to_c_simple(engines/eevee/shaders/lit_surface_vert.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/effect_bloom_frag.glsl SRC)
 data_to_c_simple(engines/eevee/shaders/effect_motion_blur_frag.glsl SRC)
 data_to_c_simple(engines/eevee/shaders/probe_filter_frag.glsl SRC)
 data_to_c_simple(engines/eevee/shaders/probe_sh_frag.glsl SRC)
diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c
index dfae27b9cec..2279f0a6b44 100644
--- a/source/blender/draw/engines/eevee/eevee_effects.c
+++ b/source/blender/draw/engines/eevee/eevee_effects.c
@@ -43,13 +43,22 @@ typedef struct EEVEE_ProbeData {
 
 /* TODO Option */
 #define ENABLE_EFFECT_MOTION_BLUR 1
+#define ENABLE_EFFECT_BLOOM 1
 
 static struct {
 	struct GPUShader *motion_blur_sh;
+
+	/* Bloom */
+	struct GPUShader *bloom_blit_sh[2];
+	struct GPUShader *bloom_downsample_sh[2];
+	struct GPUShader *bloom_upsample_sh[2];
+	struct GPUShader *bloom_resolve_sh[2];
+
 	struct GPUShader *tonemap_sh;
 } e_data = {NULL}; /* Engine data */
 
 extern char datatoc_effect_motion_blur_frag_glsl[];
+extern char datatoc_effect_bloom_frag_glsl[];
 extern char datatoc_tonemap_frag_glsl[];
 
 void EEVEE_effects_init(EEVEE_Data *vedata)
@@ -70,18 +79,37 @@ void EEVEE_effects_init(EEVEE_Data *vedata)
 		e_data.motion_blur_sh = DRW_shader_create_fullscreen(datatoc_effect_motion_blur_frag_glsl, NULL);
 	}
 
+	if (!e_data.bloom_blit_sh[0]) {
+		e_data.bloom_blit_sh[0] = DRW_shader_create_fullscreen(datatoc_effect_bloom_frag_glsl, "#define STEP_BLIT\n");
+		e_data.bloom_blit_sh[1] = DRW_shader_create_fullscreen(datatoc_effect_bloom_frag_glsl, "#define STEP_BLIT\n"
+		                                                                                       "#define HIGH_QUALITY\n");
+
+		e_data.bloom_downsample_sh[0] = DRW_shader_create_fullscreen(datatoc_effect_bloom_frag_glsl, "#define STEP_DOWNSAMPLE\n");
+		e_data.bloom_downsample_sh[1] = DRW_shader_create_fullscreen(datatoc_effect_bloom_frag_glsl, "#define STEP_DOWNSAMPLE\n"
+		                                                                                             "#define HIGH_QUALITY\n");
+
+		e_data.bloom_upsample_sh[0] = DRW_shader_create_fullscreen(datatoc_effect_bloom_frag_glsl, "#define STEP_UPSAMPLE\n");
+		e_data.bloom_upsample_sh[1] = DRW_shader_create_fullscreen(datatoc_effect_bloom_frag_glsl, "#define STEP_UPSAMPLE\n"
+		                                                                                           "#define HIGH_QUALITY\n");
+
+		e_data.bloom_resolve_sh[0] = DRW_shader_create_fullscreen(datatoc_effect_bloom_frag_glsl, "#define STEP_RESOLVE\n");
+		e_data.bloom_resolve_sh[1] = DRW_shader_create_fullscreen(datatoc_effect_bloom_frag_glsl, "#define STEP_RESOLVE\n"
+		                                                                                          "#define HIGH_QUALITY\n");
+	}
+
 	if (!e_data.tonemap_sh) {
 		e_data.tonemap_sh = DRW_shader_create_fullscreen(datatoc_tonemap_frag_glsl, NULL);
 	}
 
 	if (!stl->effects) {
 		stl->effects = MEM_callocN(sizeof(EEVEE_EffectsInfo), "EEVEE_EffectsInfo");
+		stl->effects->enabled_effects = 0;
 	}
 
+#if ENABLE_EFFECT_MOTION_BLUR
 	{
 		/* Update Motion Blur Matrices */
 		EEVEE_EffectsInfo *effects = stl->effects;
-#if ENABLE_EFFECT_MOTION_BLUR
 		const DRWContextState *draw_ctx = DRW_context_state_get();
 		Scene *scene = draw_ctx->scene;
 		View3D *v3d = draw_ctx->v3d;
@@ -124,18 +152,101 @@ void EEVEE_effects_init(EEVEE_Data *vedata)
 			DRW_viewport_matrix_get(effects->current_ndc_to_world, DRW_MAT_PERSINV);
 
 			effects->blur_amount = 0.5f;
-			effects->final_color = txl->color_post;
 			effects->enabled_effects |= EFFECT_MOTION_BLUR;
 		}
-		else {
+	}
 #endif /* ENABLE_EFFECT_MOTION_BLUR */
-			effects->blur_amount = 0.0f;
-			effects->final_color = txl->color;
-			effects->enabled_effects &= ~EFFECT_MOTION_BLUR;
-#if ENABLE_EFFECT_MOTION_BLUR
+
+	{
+		/* Bloom */
+		EEVEE_EffectsInfo *effects = stl->effects;
+		int blitsize[2], texsize[2];
+
+		/* Blit Buffer */
+		effects->source_texel_size[0] = 1.0f / viewport_size[0];
+		effects->source_texel_size[1] = 1.0f / viewport_size[1];
+
+		blitsize[0] = (int)viewport_size[0];
+		blitsize[1] = (int)viewport_size[1];
+
+		effects->blit_texel_size[0] = 1.0f / (float)blitsize[0];
+		effects->blit_texel_size[1] = 1.0f / (float)blitsize[1];
+
+		DRWFboTexture tex_blit = {&txl->bloom_blit, DRW_BUF_RGBA_16, DRW_TEX_FILTER};
+		DRW_framebuffer_init(&fbl->bloom_blit_fb,
+		                    (int)blitsize[0], (int)blitsize[1],
+		                    &tex_blit, 1);
+
+		/* Parameters */
+		/* TODO UI Options */
+		float threshold = 0.8f;
+		float knee = 0.5f;
+		float intensity = 0.8f;
+		float radius = 8.5f;
+
+		/* determine the iteration count */
+		const float minDim = (float)MIN2(blitsize[0], blitsize[1]);
+		const float maxIter = (radius - 8.0f) + log(minDim) / log(2);
+		const int maxIterInt = effects->bloom_iteration_ct = (int)maxIter;
+
+		CLAMP(effects->bloom_iteration_ct, 1, MAX_BLOOM_STEP);
+
+		effects->bloom_sample_scale = 0.5f + maxIter - (float)maxIterInt;
+		effects->bloom_curve_threshold[0] = threshold - knee;
+		effects->bloom_curve_threshold[1] = knee * 2.0f;
+		effects->bloom_curve_threshold[2] = 0.25f / knee;
+		effects->bloom_curve_threshold[3] = threshold;
+		effects->bloom_intensity = intensity;
+
+		/* Downsample buffers */
+		copy_v2_v2_int(texsize, blitsize);
+		for (int i = 0; i < effects->bloom_iteration_ct; ++i) {
+			texsize[0] /= 2; texsize[1] /= 2;
+			texsize[0] = MAX2(texsize[0], 2);
+			texsize[1] = MAX2(texsize[1], 2);
+
+			effects->downsamp_texel_size[i][0] = 1.0f / (float)texsize[0];
+			effects->downsamp_texel_size[i][1] = 1.0f / (float)texsize[1];
+
+			DRWFboTexture tex_bloom = {&txl->bloom_downsample[i], DRW_BUF_RGBA_16, DRW_TEX_FILTER};
+			DRW_framebuffer_init(&fbl->bloom_down_fb[i],
+			                    (int)texsize[0], (int)texsize[1],
+			                    &tex_bloom, 1);
 		}
-#endif
+
+		/* Upsample buffers */
+		copy_v2_v2_int(texsize, blitsize);
+		for (int i = 0; i < effects->bloom_iteration_ct - 1; ++i) {
+			texsize[0] /= 2; texsize[1] /= 2;
+			texsize[0] = MAX2(texsize[0], 2);
+			texsize[1] = MAX2(texsize[1], 2);
+
+			DRWFboTexture tex_bloom = {&txl->bloom_upsample[i], DRW_BUF_RGBA_16, DRW_TEX_FILTER};
+			DRW_framebuffer_init(&fbl->bloom_accum_fb[i],
+			                    (int)texsize[0], (int)texsize[1],
+			                    &tex_bloom, 1);
+		}
+
+		effects->enabled_effects |= EFFECT_BLOOM;
+	}
+}
+
+static DRWShadingGroup *eevee_create_bloom_pass(const char *name, EEVEE_EffectsInfo *effects, struct GPUShader *sh, DRWPass **pass, bool upsample)
+{
+	struct Batch *quad = DRW_cache_fullscreen_quad_get();
+
+	*pass = DRW_pass_create(name, DRW_STATE_WRITE_COLOR);
+
+	DRWShadingGroup *grp = DRW_shgroup_create(sh, *pass);
+	DRW_shgroup_call_add(grp, quad, NULL);
+	DRW_shgroup_uniform_buffer(grp, "sourceBuffer", &effects->unf_source_buffer, 0);
+	DRW_shgroup_uniform_vec2(grp, "sourceBufferTexelSize", effects->unf_source_texel_size, 1);
+	if (upsample) {
+		DRW_shgroup_uniform_buffer(grp, "baseBuffer", &effects->unf_base_buffer, 1);
+		DRW_shgroup_uniform_float(grp, "sampleScale", &effects->bloom_sample_scale, 1);
 	}
+
+	return grp;
 }
 
 void EEVEE_effects_cache_init(EEVEE_Data *vedata)
@@ -161,19 +272,80 @@ void EEVEE_effects_cache_init(EEVEE_Data *vedata)
 	}
 
 	{
+		/**  Bloom algorithm
+		 *
+		 * Overview :
+		 * - Downsample the color buffer doing a small blur during each step.
+		 * - Accumulate bloom color using previously downsampled color buffers
+		 *   and do an upsample blur for each new accumulated layer.
+		 * - Finally add accumulation buffer onto the source color buffer.
+		 *
+		 *  [1/1] is original copy resolution (can be half or quater res for performance)
+		 *
+		 *                                [DOWNSAMPLE CHAIN]                      [UPSAMPLE CHAIN]
+		 *
+		 *  Source Color ── [Blit] ──>  Bright Color Extract [1/1]                  Final Color
+		 *                                        |                                      Λ
+		 *                                [Downsample First]       Source Color ─> + [Resolve]
+		 *                                        v                                      |
+		 *                              Color Downsampled [1/2] ────────────> + Accumulation Buffer [1/2]
+		 *                                        |                                      Λ
+		 *                                       ───                                    ───
+		 *                                      Repeat                                 Repeat
+		 *                                       ───                                    ───
+		 *                                        v                                      |
+		 *                              Color Downsampled [1/N-1] ──────────> + Accumulation Buffer [1/N-1]
+		 *                                        |                                      Λ
+		 *                                   [Downsample]                            [Upsample]
+		 *                                        v                                      |
+		 *                              Color Downsampled [1/N] ─────────────────────────┘
+		 **/
+		DRWShadingGroup *grp;
+		const bool use_highres = true;
+		const bool use_antiflicker = true;
+		eevee_create_bloom_pass("Bloom Downsample First", effects, e_data.bloom_downsample_sh[use_antiflicker], &psl->bloom_downsample_first, false);
+		eevee_create_bloom_pass("Bloom Downsample", effects, e_data.bloom_downsample_sh[0], &psl->bloom_downsample, false);
+		eevee_create_

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list