Blender  V3.3
eevee_bloom.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2016 Blender Foundation. */
3 
10 #include "DRW_render.h"
11 
12 #include "GPU_texture.h"
13 
14 #include "DEG_depsgraph_query.h"
15 
16 #include "eevee_private.h"
17 
18 static const bool use_highres = true;
19 
21 {
22  EEVEE_StorageList *stl = vedata->stl;
23  EEVEE_FramebufferList *fbl = vedata->fbl;
24  EEVEE_EffectsInfo *effects = stl->effects;
25 
26  const DRWContextState *draw_ctx = DRW_context_state_get();
27  const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
28 
29  if (scene_eval->eevee.flag & SCE_EEVEE_BLOOM_ENABLED) {
30  const float *viewport_size = DRW_viewport_size_get();
31 
32  /* Bloom */
33  int blitsize[2], texsize[2];
34 
35  /* Blit Buffer */
36  effects->source_texel_size[0] = 1.0f / viewport_size[0];
37  effects->source_texel_size[1] = 1.0f / viewport_size[1];
38 
39  blitsize[0] = (int)viewport_size[0];
40  blitsize[1] = (int)viewport_size[1];
41 
42  effects->blit_texel_size[0] = 1.0f / (float)blitsize[0];
43  effects->blit_texel_size[1] = 1.0f / (float)blitsize[1];
44 
46  blitsize[0], blitsize[1], GPU_R11F_G11F_B10F, &draw_engine_eevee_type);
47 
48  GPU_framebuffer_ensure_config(
49  &fbl->bloom_blit_fb, {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(effects->bloom_blit)});
50 
51  /* Parameters */
52  const float threshold = scene_eval->eevee.bloom_threshold;
53  const float knee = scene_eval->eevee.bloom_knee;
54  const float intensity = scene_eval->eevee.bloom_intensity;
55  const float *color = scene_eval->eevee.bloom_color;
56  const float radius = scene_eval->eevee.bloom_radius;
57  effects->bloom_clamp = scene_eval->eevee.bloom_clamp;
58 
59  /* determine the iteration count */
60  const float minDim = (float)MIN2(blitsize[0], blitsize[1]);
61  const float maxIter = (radius - 8.0f) + log(minDim) / log(2);
62  const int maxIterInt = effects->bloom_iteration_len = (int)maxIter;
63 
65 
66  effects->bloom_sample_scale = 0.5f + maxIter - (float)maxIterInt;
67  effects->bloom_curve_threshold[0] = threshold - knee;
68  effects->bloom_curve_threshold[1] = knee * 2.0f;
69  effects->bloom_curve_threshold[2] = 0.25f / max_ff(1e-5f, knee);
70  effects->bloom_curve_threshold[3] = threshold;
71 
72  mul_v3_v3fl(effects->bloom_color, color, intensity);
73 
74  /* Downsample buffers */
75  copy_v2_v2_int(texsize, blitsize);
76  for (int i = 0; i < effects->bloom_iteration_len; i++) {
77  texsize[0] /= 2;
78  texsize[1] /= 2;
79 
80  texsize[0] = MAX2(texsize[0], 2);
81  texsize[1] = MAX2(texsize[1], 2);
82 
83  effects->downsamp_texel_size[i][0] = 1.0f / (float)texsize[0];
84  effects->downsamp_texel_size[i][1] = 1.0f / (float)texsize[1];
85 
87  texsize[0], texsize[1], GPU_R11F_G11F_B10F, &draw_engine_eevee_type);
88  GPU_framebuffer_ensure_config(
89  &fbl->bloom_down_fb[i],
90  {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(effects->bloom_downsample[i])});
91  }
92 
93  /* Upsample buffers */
94  copy_v2_v2_int(texsize, blitsize);
95  for (int i = 0; i < effects->bloom_iteration_len - 1; i++) {
96  texsize[0] /= 2;
97  texsize[1] /= 2;
98 
99  texsize[0] = MAX2(texsize[0], 2);
100  texsize[1] = MAX2(texsize[1], 2);
101 
103  texsize[0], texsize[1], GPU_R11F_G11F_B10F, &draw_engine_eevee_type);
104  GPU_framebuffer_ensure_config(
105  &fbl->bloom_accum_fb[i],
106  {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(effects->bloom_upsample[i])});
107  }
108 
110  }
111 
112  /* Cleanup to release memory */
113  GPU_FRAMEBUFFER_FREE_SAFE(fbl->bloom_blit_fb);
114 
115  for (int i = 0; i < MAX_BLOOM_STEP - 1; i++) {
116  GPU_FRAMEBUFFER_FREE_SAFE(fbl->bloom_down_fb[i]);
117  GPU_FRAMEBUFFER_FREE_SAFE(fbl->bloom_accum_fb[i]);
118  }
119 
120  return 0;
121 }
122 
123 static DRWShadingGroup *eevee_create_bloom_pass(const char *name,
124  EEVEE_EffectsInfo *effects,
125  struct GPUShader *sh,
126  DRWPass **pass,
127  bool upsample,
128  bool resolve,
129  bool resolve_add_base)
130 {
132 
133  *pass = DRW_pass_create(name, DRW_STATE_WRITE_COLOR);
134 
135  DRWShadingGroup *grp = DRW_shgroup_create(sh, *pass);
136  DRW_shgroup_call(grp, quad, NULL);
137  DRW_shgroup_uniform_texture_ref(grp, "sourceBuffer", &effects->unf_source_buffer);
138  DRW_shgroup_uniform_vec2(grp, "sourceBufferTexelSize", effects->unf_source_texel_size, 1);
139  if (upsample) {
140  DRW_shgroup_uniform_texture_ref(grp, "baseBuffer", &effects->unf_base_buffer);
141  DRW_shgroup_uniform_float(grp, "sampleScale", &effects->bloom_sample_scale, 1);
142  }
143  if (resolve) {
144  DRW_shgroup_uniform_vec3(grp, "bloomColor", effects->bloom_color, 1);
145  DRW_shgroup_uniform_bool_copy(grp, "bloomAddBase", resolve_add_base);
146  }
147 
148  return grp;
149 }
150 
152 {
153  EEVEE_PassList *psl = vedata->psl;
154  EEVEE_StorageList *stl = vedata->stl;
155  EEVEE_EffectsInfo *effects = stl->effects;
156 
157  psl->bloom_accum_ps = NULL;
158 
159  if ((effects->enabled_effects & EFFECT_BLOOM) != 0) {
190  DRWShadingGroup *grp;
191  const bool use_antiflicker = true;
192  eevee_create_bloom_pass("Bloom Downsample First",
193  effects,
194  EEVEE_shaders_bloom_downsample_get(use_antiflicker),
196  false,
197  false,
198  false);
199  eevee_create_bloom_pass("Bloom Downsample",
200  effects,
202  &psl->bloom_downsample,
203  false,
204  false,
205  false);
206  eevee_create_bloom_pass("Bloom Upsample",
207  effects,
209  &psl->bloom_upsample,
210  true,
211  false,
212  false);
213 
214  grp = eevee_create_bloom_pass("Bloom Blit",
215  effects,
216  EEVEE_shaders_bloom_blit_get(use_antiflicker),
217  &psl->bloom_blit,
218  false,
219  false,
220  false);
221  DRW_shgroup_uniform_vec4(grp, "curveThreshold", effects->bloom_curve_threshold, 1);
222  DRW_shgroup_uniform_float(grp, "clampIntensity", &effects->bloom_clamp, 1);
223 
224  grp = eevee_create_bloom_pass("Bloom Resolve",
225  effects,
227  &psl->bloom_resolve,
228  true,
229  true,
230  true);
231  }
232 }
233 
235 {
236  EEVEE_PassList *psl = vedata->psl;
237  EEVEE_TextureList *txl = vedata->txl;
238  EEVEE_FramebufferList *fbl = vedata->fbl;
239  EEVEE_StorageList *stl = vedata->stl;
240  EEVEE_EffectsInfo *effects = stl->effects;
241 
242  /* Bloom */
243  if ((effects->enabled_effects & EFFECT_BLOOM) != 0) {
244  struct GPUTexture *last;
245 
246  /* Extract bright pixels */
248  effects->unf_source_buffer = effects->source_buffer;
249 
252 
253  /* Downsample */
255  effects->unf_source_buffer = effects->bloom_blit;
256 
259 
260  last = effects->bloom_downsample[0];
261 
262  for (int i = 1; i < effects->bloom_iteration_len; i++) {
263  copy_v2_v2(effects->unf_source_texel_size, effects->downsamp_texel_size[i - 1]);
264  effects->unf_source_buffer = last;
265 
268 
269  /* Used in next loop */
270  last = effects->bloom_downsample[i];
271  }
272 
273  /* Upsample and accumulate */
274  for (int i = effects->bloom_iteration_len - 2; i >= 0; i--) {
276  effects->unf_source_buffer = last;
277  effects->unf_base_buffer = effects->bloom_downsample[i];
278 
281 
282  last = effects->bloom_upsample[i];
283  }
284 
285  /* Resolve */
287  effects->unf_source_buffer = last;
288  effects->unf_base_buffer = effects->source_buffer;
289 
292  SWAP_BUFFERS();
293  }
294 }
295 
297  EEVEE_Data *vedata,
298  uint UNUSED(tot_samples))
299 {
300  EEVEE_FramebufferList *fbl = vedata->fbl;
301  EEVEE_TextureList *txl = vedata->txl;
302  EEVEE_PassList *psl = vedata->psl;
303  EEVEE_StorageList *stl = vedata->stl;
304  EEVEE_EffectsInfo *effects = stl->effects;
305 
306  /* Create FrameBuffer. */
308 
309  GPU_framebuffer_ensure_config(&fbl->bloom_pass_accum_fb,
310  {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(txl->bloom_accum)});
311 
312  /* Create Pass and shgroup. */
313  eevee_create_bloom_pass("Bloom Accumulate",
314  effects,
316  &psl->bloom_accum_ps,
317  true,
318  true,
319  false);
320 }
321 
323 {
324  EEVEE_FramebufferList *fbl = vedata->fbl;
325  EEVEE_PassList *psl = vedata->psl;
326  EEVEE_StorageList *stl = vedata->stl;
327 
331 
332  /* Restore */
334  }
335 }
typedef float(TangentPoint)[2]
MINLINE float max_ff(float a, float b)
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void copy_v2_v2_int(int r[2], const int a[2])
MINLINE void mul_v3_v3fl(float r[3], const float a[3], float f)
unsigned int uint
Definition: BLI_sys_types.h:67
#define UNUSED(x)
#define MAX2(a, b)
#define MIN2(a, b)
struct Scene * DEG_get_evaluated_scene(const struct Depsgraph *graph)
@ EEVEE_RENDER_PASS_BLOOM
@ SCE_EEVEE_BLOOM_ENABLED
@ DRW_STATE_WRITE_COLOR
Definition: DRW_render.h:303
#define DRW_shgroup_call(shgroup, geom, ob)
Definition: DRW_render.h:414
GPUBatch
Definition: GPU_batch.h:78
void GPU_framebuffer_bind(GPUFrameBuffer *fb)
struct GPUShader GPUShader
Definition: GPU_shader.h:20
struct GPUTexture GPUTexture
Definition: GPU_texture.h:17
@ GPU_R11F_G11F_B10F
Definition: GPU_texture.h:118
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position CLAMP
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert a color
GPUBatch * DRW_cache_fullscreen_quad_get(void)
Definition: draw_cache.c:356
const DRWContextState * DRW_context_state_get(void)
const float * DRW_viewport_size_get(void)
Definition: draw_manager.c:288
void DRW_shgroup_uniform_vec4(DRWShadingGroup *shgroup, const char *name, const float *value, int arraysize)
void DRW_shgroup_uniform_vec3(DRWShadingGroup *shgroup, const char *name, const float *value, int arraysize)
DRWShadingGroup * DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass)
void DRW_shgroup_uniform_texture_ref(DRWShadingGroup *shgroup, const char *name, GPUTexture **tex)
DRWPass * DRW_pass_create(const char *name, DRWState state)
void DRW_shgroup_uniform_bool_copy(DRWShadingGroup *shgroup, const char *name, const bool value)
void DRW_shgroup_uniform_float(DRWShadingGroup *shgroup, const char *name, const float *value, int arraysize)
void DRW_shgroup_uniform_vec2(DRWShadingGroup *shgroup, const char *name, const float *value, int arraysize)
void DRW_draw_pass(DRWPass *pass)
void DRW_texture_ensure_fullscreen_2d(GPUTexture **tex, eGPUTextureFormat format, DRWTextureFlag flags)
GPUTexture * DRW_texture_pool_query_2d(int w, int h, eGPUTextureFormat format, DrawEngineType *engine_type)
void EEVEE_bloom_output_accumulate(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
Definition: eevee_bloom.c:322
void EEVEE_bloom_output_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata, uint UNUSED(tot_samples))
Definition: eevee_bloom.c:296
void EEVEE_bloom_draw(EEVEE_Data *vedata)
Definition: eevee_bloom.c:234
int EEVEE_bloom_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
Definition: eevee_bloom.c:20
static const bool use_highres
Definition: eevee_bloom.c:18
static DRWShadingGroup * eevee_create_bloom_pass(const char *name, EEVEE_EffectsInfo *effects, struct GPUShader *sh, DRWPass **pass, bool upsample, bool resolve, bool resolve_add_base)
Definition: eevee_bloom.c:123
void EEVEE_bloom_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
Definition: eevee_bloom.c:151
DrawEngineType draw_engine_eevee_type
Definition: eevee_engine.c:618
#define SWAP_BUFFERS()
Definition: eevee_private.h:88
#define MAX_BLOOM_STEP
Definition: eevee_private.h:40
struct GPUShader * EEVEE_shaders_bloom_blit_get(bool high_quality)
@ EFFECT_BLOOM
@ EFFECT_POST_BUFFER
struct GPUShader * EEVEE_shaders_bloom_upsample_get(bool high_quality)
struct GPUShader * EEVEE_shaders_bloom_resolve_get(bool high_quality)
struct GPUShader * EEVEE_shaders_bloom_downsample_get(bool high_quality)
GPUBatch * quad
ccl_gpu_kernel_postfix ccl_global float int int int int float threshold
ccl_gpu_kernel_postfix ccl_global float int int int int sh
ccl_device_inline float3 log(float3 v)
Definition: math_float3.h:397
struct Depsgraph * depsgraph
Definition: DRW_render.h:987
EEVEE_TextureList * txl
EEVEE_StorageList * stl
EEVEE_PassList * psl
EEVEE_FramebufferList * fbl
float blit_texel_size[2]
float downsamp_texel_size[MAX_BLOOM_STEP][2]
struct GPUTexture * source_buffer
float bloom_curve_threshold[4]
float unf_source_texel_size[2]
struct GPUTexture * bloom_blit
struct GPUFrameBuffer * target_buffer
struct GPUTexture * bloom_upsample[MAX_BLOOM_STEP - 1]
struct GPUTexture * bloom_downsample[MAX_BLOOM_STEP]
float source_texel_size[2]
EEVEE_EffectsFlag enabled_effects
struct GPUTexture * unf_base_buffer
struct GPUTexture * unf_source_buffer
struct GPUFrameBuffer * main_fb
struct GPUFrameBuffer * bloom_blit_fb
struct GPUFrameBuffer * bloom_pass_accum_fb
struct GPUFrameBuffer * bloom_accum_fb[MAX_BLOOM_STEP - 1]
struct GPUFrameBuffer * bloom_down_fb[MAX_BLOOM_STEP]
struct DRWPass * bloom_resolve
struct DRWPass * bloom_upsample
struct DRWPass * bloom_downsample_first
struct DRWPass * bloom_blit
struct DRWPass * bloom_accum_ps
struct DRWPass * bloom_downsample
eViewLayerEEVEEPassType render_passes
struct EEVEE_PrivateData * g_data
struct EEVEE_EffectsInfo * effects
struct GPUTexture * bloom_accum
float bloom_intensity
float bloom_color[3]
float bloom_threshold
struct SceneEEVEE eevee