[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