Blender  V3.3
eevee_motion_blur.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 "BLI_rand.h"
13 #include "BLI_string_utils.h"
14 
15 #include "BKE_animsys.h"
16 #include "BKE_camera.h"
17 #include "BKE_duplilist.h"
18 #include "BKE_object.h"
19 #include "BKE_screen.h"
20 
21 #include "DNA_anim_types.h"
22 #include "DNA_camera_types.h"
23 #include "DNA_mesh_types.h"
24 #include "DNA_modifier_types.h"
25 #include "DNA_particle_types.h"
26 #include "DNA_rigidbody_types.h"
27 #include "DNA_screen_types.h"
28 
29 #include "ED_screen.h"
30 
31 #include "DEG_depsgraph.h"
32 #include "DEG_depsgraph_query.h"
33 
34 #include "GPU_batch.h"
35 #include "GPU_texture.h"
36 #include "eevee_private.h"
37 
39 {
40  EEVEE_StorageList *stl = vedata->stl;
41  EEVEE_FramebufferList *fbl = vedata->fbl;
42  EEVEE_EffectsInfo *effects = stl->effects;
43 
44  const DRWContextState *draw_ctx = DRW_context_state_get();
45  Scene *scene = draw_ctx->scene;
46 
47  /* Viewport not supported for now. */
49  return 0;
50  }
51 
53 
54  if ((effects->motion_blur_max > 0) && (scene->eevee.flag & SCE_EEVEE_MOTION_BLUR_ENABLED)) {
56  int mb_step = effects->motion_blur_step;
57  DRW_view_viewmat_get(NULL, effects->motion_blur.camera[mb_step].viewmat, false);
58  DRW_view_persmat_get(NULL, effects->motion_blur.camera[mb_step].persmat, false);
59  DRW_view_persmat_get(NULL, effects->motion_blur.camera[mb_step].persinv, true);
60  }
61 
62  const float *fs_size = DRW_viewport_size_get();
63  const int tx_size[2] = {
64  1 + ((int)fs_size[0] / EEVEE_VELOCITY_TILE_SIZE),
65  1 + ((int)fs_size[1] / EEVEE_VELOCITY_TILE_SIZE),
66  };
67 
69  tx_size[0], fs_size[1], GPU_RGBA16, &draw_engine_eevee_type);
70  GPU_framebuffer_ensure_config(&fbl->velocity_tiles_fb[0],
71  {
72  GPU_ATTACHMENT_NONE,
73  GPU_ATTACHMENT_TEXTURE(effects->velocity_tiles_x_tx),
74  });
75 
77  tx_size[0], tx_size[1], GPU_RGBA16, &draw_engine_eevee_type);
78  GPU_framebuffer_ensure_config(&fbl->velocity_tiles_fb[1],
79  {
80  GPU_ATTACHMENT_NONE,
81  GPU_ATTACHMENT_TEXTURE(effects->velocity_tiles_tx),
82  });
83 
85  }
86  return 0;
87 }
88 
89 void EEVEE_motion_blur_step_set(EEVEE_Data *vedata, int step)
90 {
91  BLI_assert(step < 3);
92  vedata->stl->effects->motion_blur_step = step;
93 }
94 
96 {
97  EEVEE_EffectsInfo *effects = vedata->stl->effects;
99  int mb_step = effects->motion_blur_step;
100  DRW_view_viewmat_get(NULL, effects->motion_blur.camera[mb_step].viewmat, false);
101  DRW_view_persmat_get(NULL, effects->motion_blur.camera[mb_step].persmat, false);
102  DRW_view_persmat_get(NULL, effects->motion_blur.camera[mb_step].persinv, true);
103  }
104 
107 }
108 
110 {
111  EEVEE_PassList *psl = vedata->psl;
112  EEVEE_StorageList *stl = vedata->stl;
113  EEVEE_EffectsInfo *effects = stl->effects;
114  EEVEE_MotionBlurData *mb_data = &effects->motion_blur;
116  const DRWContextState *draw_ctx = DRW_context_state_get();
117  Scene *scene = draw_ctx->scene;
118 
119  if ((effects->enabled_effects & EFFECT_MOTION_BLUR) != 0) {
120  const float *fs_size = DRW_viewport_size_get();
121  const int tx_size[2] = {
124  };
125 
127 
128  DRWShadingGroup *grp;
129  {
132 
133  /* Create max velocity tiles in 2 passes. One for X and one for Y */
136  DRW_shgroup_uniform_texture(grp, "velocityBuffer", effects->velocity_tx);
137  DRW_shgroup_uniform_ivec2_copy(grp, "velocityBufferSize", (int[2]){fs_size[0], fs_size[1]});
138  DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1);
139  DRW_shgroup_uniform_vec2(grp, "viewportSizeInv", DRW_viewport_invert_size_get(), 1);
140  DRW_shgroup_uniform_ivec2_copy(grp, "gatherStep", (int[2]){1, 0});
142 
143  grp = DRW_shgroup_create(sh, psl->velocity_tiles);
144  DRW_shgroup_uniform_texture(grp, "velocityBuffer", effects->velocity_tiles_x_tx);
145  DRW_shgroup_uniform_ivec2_copy(grp, "velocityBufferSize", (int[2]){tx_size[0], fs_size[1]});
146  DRW_shgroup_uniform_ivec2_copy(grp, "gatherStep", (int[2]){0, 1});
148 
149  /* Expand max tiles by keeping the max tile in each tile neighborhood. */
152  for (int i = 0; i < 2; i++) {
153  GPUTexture *tile_tx = (i == 0) ? effects->velocity_tiles_tx : effects->velocity_tiles_x_tx;
155  grp = DRW_shgroup_create(sh_expand, psl->velocity_tiles_expand[i]);
156  DRW_shgroup_uniform_ivec2_copy(grp, "velocityBufferSize", tx_size);
157  DRW_shgroup_uniform_texture(grp, "velocityBuffer", tile_tx);
158  DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1);
159  DRW_shgroup_uniform_vec2(grp, "viewportSizeInv", DRW_viewport_invert_size_get(), 1);
161  }
162  }
163  {
166  int expand_steps = 1 + (max_ii(0, effects->motion_blur_max - 1) / EEVEE_VELOCITY_TILE_SIZE);
167  GPUTexture *tile_tx = (expand_steps & 1) ? effects->velocity_tiles_x_tx :
168  effects->velocity_tiles_tx;
169 
172  DRW_shgroup_uniform_texture_ref_ex(grp, "colorBuffer", &effects->source_buffer, state);
173  DRW_shgroup_uniform_texture_ref_ex(grp, "depthBuffer", &dtxl->depth, state);
174  DRW_shgroup_uniform_texture_ref_ex(grp, "velocityBuffer", &effects->velocity_tx, state);
175  DRW_shgroup_uniform_texture(grp, "tileMaxBuffer", tile_tx);
177  DRW_shgroup_uniform_vec2(grp, "nearFar", effects->motion_blur_near_far, 1);
179  DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1);
180  DRW_shgroup_uniform_vec2(grp, "viewportSizeInv", DRW_viewport_invert_size_get(), 1);
181  DRW_shgroup_uniform_ivec2_copy(grp, "tileBufferSize", tx_size);
183  }
184  {
186 
188  psl->velocity_object);
189  DRW_shgroup_uniform_mat4(grp, "prevViewProjMatrix", mb_data->camera[MB_PREV].persmat);
190  DRW_shgroup_uniform_mat4(grp, "currViewProjMatrix", mb_data->camera[MB_CURR].persmat);
191  DRW_shgroup_uniform_mat4(grp, "nextViewProjMatrix", mb_data->camera[MB_NEXT].persmat);
192 
194 
196  psl->velocity_hair);
197  DRW_shgroup_uniform_mat4(grp, "prevViewProjMatrix", mb_data->camera[MB_PREV].persmat);
198  DRW_shgroup_uniform_mat4(grp, "currViewProjMatrix", mb_data->camera[MB_CURR].persmat);
199  DRW_shgroup_uniform_mat4(grp, "nextViewProjMatrix", mb_data->camera[MB_NEXT].persmat);
200 
202  }
203 
205  }
206  else {
207  psl->motion_blur = NULL;
208  psl->velocity_object = NULL;
209  psl->velocity_hair = NULL;
210  }
211 }
212 
214  EEVEE_Data *vedata,
215  Object *ob,
216  ParticleSystem *psys,
217  ModifierData *md)
218 {
219  EEVEE_PassList *psl = vedata->psl;
220  EEVEE_StorageList *stl = vedata->stl;
221  EEVEE_EffectsInfo *effects = stl->effects;
222  DRWShadingGroup *grp = NULL;
223 
224  if (!DRW_state_is_scene_render() || psl->velocity_hair == NULL) {
225  return;
226  }
227 
228  /* For now we assume hair objects are always moving. */
230  &effects->motion_blur, ob, true);
231 
232  if (mb_data) {
233  int mb_step = effects->motion_blur_step;
234  /* Store transform. */
235  DRW_hair_duplimat_get(ob, psys, md, mb_data->obmat[mb_step]);
236 
238  int psys_id = (md != NULL) ? BLI_findindex(&ob->modifiers, md) : 0;
239 
240  if (psys_id >= mb_hair->psys_len) {
241  /* This should never happen. It means the modifier list was changed by frame evaluation. */
242  BLI_assert(0);
243  return;
244  }
245 
246  if (mb_step == MB_CURR) {
247  /* Fill missing matrices if the object was hidden in previous or next frame. */
248  if (is_zero_m4(mb_data->obmat[MB_PREV])) {
249  copy_m4_m4(mb_data->obmat[MB_PREV], mb_data->obmat[MB_CURR]);
250  }
251  if (is_zero_m4(mb_data->obmat[MB_NEXT])) {
252  copy_m4_m4(mb_data->obmat[MB_NEXT], mb_data->obmat[MB_CURR]);
253  }
254 
255  GPUTexture *tex_prev = mb_hair->psys[psys_id].step_data[MB_PREV].hair_pos_tx;
256  GPUTexture *tex_next = mb_hair->psys[psys_id].step_data[MB_NEXT].hair_pos_tx;
257 
258  grp = DRW_shgroup_hair_create_sub(ob, psys, md, effects->motion_blur.hair_grp, NULL);
259  DRW_shgroup_uniform_mat4(grp, "prevModelMatrix", mb_data->obmat[MB_PREV]);
260  DRW_shgroup_uniform_mat4(grp, "currModelMatrix", mb_data->obmat[MB_CURR]);
261  DRW_shgroup_uniform_mat4(grp, "nextModelMatrix", mb_data->obmat[MB_NEXT]);
262  DRW_shgroup_uniform_texture(grp, "prvBuffer", tex_prev);
263  DRW_shgroup_uniform_texture(grp, "nxtBuffer", tex_next);
264  DRW_shgroup_uniform_bool(grp, "useDeform", &mb_hair->use_deform, 1);
265  }
266  else {
267  /* Store vertex position buffer. */
268  mb_hair->psys[psys_id].step_data[mb_step].hair_pos = DRW_hair_pos_buffer_get(ob, psys, md);
269  mb_hair->use_deform = true;
270  }
271  }
272 }
273 
275  EEVEE_Data *vedata,
276  Object *ob)
277 {
278  EEVEE_PassList *psl = vedata->psl;
279  EEVEE_StorageList *stl = vedata->stl;
280  EEVEE_EffectsInfo *effects = stl->effects;
281 
282  if (!DRW_state_is_scene_render() || psl->velocity_hair == NULL) {
283  return;
284  }
285 
286  /* For now we assume curves objects are always moving. */
288  &effects->motion_blur, ob, false);
289  if (mb_data == NULL) {
290  return;
291  }
292 
293  int mb_step = effects->motion_blur_step;
294  /* Store transform. */
295  copy_m4_m4(mb_data->obmat[mb_step], ob->obmat);
296 
298 
299  if (mb_step == MB_CURR) {
300  /* Fill missing matrices if the object was hidden in previous or next frame. */
301  if (is_zero_m4(mb_data->obmat[MB_PREV])) {
302  copy_m4_m4(mb_data->obmat[MB_PREV], mb_data->obmat[MB_CURR]);
303  }
304  if (is_zero_m4(mb_data->obmat[MB_NEXT])) {
305  copy_m4_m4(mb_data->obmat[MB_NEXT], mb_data->obmat[MB_CURR]);
306  }
307 
308  GPUTexture *tex_prev = mb_curves->psys[0].step_data[MB_PREV].hair_pos_tx;
309  GPUTexture *tex_next = mb_curves->psys[0].step_data[MB_NEXT].hair_pos_tx;
310 
312  DRW_shgroup_uniform_mat4(grp, "prevModelMatrix", mb_data->obmat[MB_PREV]);
313  DRW_shgroup_uniform_mat4(grp, "currModelMatrix", mb_data->obmat[MB_CURR]);
314  DRW_shgroup_uniform_mat4(grp, "nextModelMatrix", mb_data->obmat[MB_NEXT]);
315  DRW_shgroup_uniform_texture(grp, "prvBuffer", tex_prev);
316  DRW_shgroup_uniform_texture(grp, "nxtBuffer", tex_next);
317  DRW_shgroup_uniform_bool(grp, "useDeform", &mb_curves->use_deform, 1);
318  }
319  else {
320  /* Store vertex position buffer. */
321  mb_curves->psys[0].step_data[mb_step].hair_pos = DRW_curves_pos_buffer_get(ob);
322  mb_curves->use_deform = true;
323  }
324 }
325 
327  EEVEE_Data *vedata,
328  Object *ob)
329 {
330  EEVEE_PassList *psl = vedata->psl;
331  EEVEE_StorageList *stl = vedata->stl;
332  EEVEE_EffectsInfo *effects = stl->effects;
333  DRWShadingGroup *grp = NULL;
334 
335  if (!DRW_state_is_scene_render() || psl->velocity_object == NULL) {
336  return;
337  }
338 
339  RigidBodyOb *rbo = ob->rigidbody_object;
340 
341  /* active rigidbody objects only, as only those are affected by sim. */
342  const bool has_rigidbody = (rbo && (rbo->type == RBO_TYPE_ACTIVE));
343 #if 0
344  /* For now we assume dupli objects are moving. */
345  const bool is_dupli = (ob->base_flag & BASE_FROM_DUPLI) != 0;
346  const bool object_moves = is_dupli || has_rigidbody || BKE_object_moves_in_time(ob, true);
347 #else
348  /* BKE_object_moves_in_time does not work in some cases.
349  * Better detect non moving object after evaluation. */
350  const bool object_moves = true;
351 #endif
352  const bool is_deform = BKE_object_is_deform_modified(DRW_context_state_get()->scene, ob) ||
353  (has_rigidbody && (rbo->flag & RBO_FLAG_USE_DEFORM) != 0);
354 
355  if (!(object_moves || is_deform)) {
356  return;
357  }
358 
360  &effects->motion_blur, ob, false);
361 
362  if (mb_data) {
363  int mb_step = effects->motion_blur_step;
364  /* Store transform. */
365  copy_m4_m4(mb_data->obmat[mb_step], ob->obmat);
366 
368 
369  if (mb_step == MB_CURR) {
371  if (batch == NULL) {
372  return;
373  }
374 
375  /* Fill missing matrices if the object was hidden in previous or next frame. */
376  if (is_zero_m4(mb_data->obmat[MB_PREV])) {
377  copy_m4_m4(mb_data->obmat[MB_PREV], mb_data->obmat[MB_CURR]);
378  }
379  if (is_zero_m4(mb_data->obmat[MB_NEXT])) {
380  copy_m4_m4(mb_data->obmat[MB_NEXT], mb_data->obmat[MB_CURR]);
381  }
382 
383  if (mb_geom->use_deform) {
384  /* Keep to modify later (after init). */
385  mb_geom->batch = batch;
386  }
387 
388  /* Avoid drawing object that has no motions since object_moves is always true. */
389  if (!mb_geom->use_deform && /* Object deformation can happen without transform. */
390  equals_m4m4(mb_data->obmat[MB_PREV], mb_data->obmat[MB_CURR]) &&
391  equals_m4m4(mb_data->obmat[MB_NEXT], mb_data->obmat[MB_CURR])) {
392  return;
393  }
394 
396  psl->velocity_object);
397  DRW_shgroup_uniform_mat4(grp, "prevModelMatrix", mb_data->obmat[MB_PREV]);
398  DRW_shgroup_uniform_mat4(grp, "currModelMatrix", mb_data->obmat[MB_CURR]);
399  DRW_shgroup_uniform_mat4(grp, "nextModelMatrix", mb_data->obmat[MB_NEXT]);
400  DRW_shgroup_uniform_bool(grp, "useDeform", &mb_geom->use_deform, 1);
401 
402  DRW_shgroup_call(grp, batch, ob);
403  }
404  else if (is_deform) {
405  /* Store vertex position buffer. */
406  mb_geom->vbo[mb_step] = DRW_cache_object_pos_vertbuf_get(ob);
407  mb_geom->use_deform = (mb_geom->vbo[mb_step] != NULL);
408  }
409  else {
410  mb_geom->vbo[mb_step] = NULL;
411  mb_geom->use_deform = false;
412  }
413  }
414 }
415 
417  GPUVertBuf *vbo1,
418  GPUVertBuf *vbo2)
419 {
420 
421  for (int i = 0; i < GPU_BATCH_VBO_MAX_LEN; i++) {
422  if (ELEM(batch->verts[i], vbo1, vbo2)) {
423  /* Avoid double reference of the VBOs. */
424  batch->verts[i] = NULL;
425  }
426  }
427 }
428 
430 {
431  EEVEE_StorageList *stl = vedata->stl;
432  EEVEE_EffectsInfo *effects = stl->effects;
433  GHashIterator ghi;
434 
435  if ((effects->enabled_effects & EFFECT_MOTION_BLUR) == 0) {
436  return;
437  }
438 
439  int mb_step = effects->motion_blur_step;
440 
441  if (mb_step != MB_CURR) {
442  /* Push instances attributes to the GPU. */
444 
445  /* Need to be called after #DRW_render_instance_buffer_finish() */
446  /* Also we weed to have a correct FBO bound for #DRW_curves_update. */
447  GPU_framebuffer_bind(vedata->fbl->main_fb);
449 
451  }
452 
453  for (BLI_ghashIterator_init(&ghi, effects->motion_blur.object);
454  BLI_ghashIterator_done(&ghi) == false;
455  BLI_ghashIterator_step(&ghi)) {
457  EEVEE_HairMotionData *mb_hair = mb_data->hair_data;
458  EEVEE_GeometryMotionData *mb_geom = mb_data->geometry_data;
459  if (mb_hair != NULL && mb_hair->use_deform) {
460  if (mb_step == MB_CURR) {
461  /* TODO(fclem): Check if vertex count mismatch. */
462  mb_hair->use_deform = true;
463  }
464  else {
465  for (int i = 0; i < mb_hair->psys_len; i++) {
466  GPUVertBuf *vbo = mb_hair->psys[i].step_data[mb_step].hair_pos;
467  if (vbo == NULL) {
468  continue;
469  }
470  EEVEE_HairMotionStepData **step_data_cache_ptr;
472  vbo,
473  (void ***)&step_data_cache_ptr)) {
475  __func__);
476  /* Duplicate the vbo, otherwise it would be lost when evaluating another frame. */
477  new_step_data->hair_pos = GPU_vertbuf_duplicate(vbo);
478  /* Create vbo immediately to bind to texture buffer. */
479  GPU_vertbuf_use(new_step_data->hair_pos);
480  new_step_data->hair_pos_tx = GPU_texture_create_from_vertbuf("hair_pos_motion_blur",
481  new_step_data->hair_pos);
482  *step_data_cache_ptr = new_step_data;
483  }
484  mb_hair->psys[i].step_data[mb_step] = **step_data_cache_ptr;
485  }
486  }
487  }
488  if (mb_geom != NULL && mb_geom->use_deform) {
489  if (mb_step == MB_CURR) {
490  /* Modify batch to have data from adjacent frames. */
491  GPUBatch *batch = mb_geom->batch;
492  for (int i = 0; i < MB_CURR; i++) {
493  GPUVertBuf *vbo = mb_geom->vbo[i];
494  if (vbo && batch) {
496  /* Vertex count mismatch, disable deform motion blur. */
497  mb_geom->use_deform = false;
498  }
499 
500  if (mb_geom->use_deform == false) {
502  batch, mb_geom->vbo[MB_PREV], mb_geom->vbo[MB_NEXT]);
503  break;
504  }
505  /* Avoid adding the same vbo more than once when the batch is used by multiple
506  * instances. */
507  if (!GPU_batch_vertbuf_has(batch, vbo)) {
508  /* Currently, the code assumes that all objects that share the same mesh in the
509  * current frame also share the same mesh on other frames. */
510  GPU_batch_vertbuf_add_ex(batch, vbo, false);
511  }
512  }
513  }
514  }
515  else {
516  GPUVertBuf *vbo = mb_geom->vbo[mb_step];
517  if (vbo) {
518  /* Use the vbo to perform the copy on the GPU. */
519  GPU_vertbuf_use(vbo);
520  /* Perform a copy to avoid losing it after RE_engine_frame_set(). */
521  GPUVertBuf **vbo_cache_ptr;
522  if (!BLI_ghash_ensure_p(effects->motion_blur.position_vbo_cache[mb_step],
523  vbo,
524  (void ***)&vbo_cache_ptr)) {
525  /* Duplicate the vbo, otherwise it would be lost when evaluating another frame. */
526  GPUVertBuf *duplicated_vbo = GPU_vertbuf_duplicate(vbo);
527  *vbo_cache_ptr = duplicated_vbo;
528  /* Find and replace "pos" attrib name. */
530  int attrib_id = GPU_vertformat_attr_id_get(format, "pos");
531  GPU_vertformat_attr_rename(format, attrib_id, (mb_step == MB_PREV) ? "prv" : "nxt");
532  }
533  mb_geom->vbo[mb_step] = vbo = *vbo_cache_ptr;
534  }
535  else {
536  /* This might happen if the object visibility has been animated. */
537  mb_geom->use_deform = false;
538  }
539  }
540  }
541  }
542 }
543 
545 {
546  EEVEE_StorageList *stl = vedata->stl;
547  EEVEE_EffectsInfo *effects = stl->effects;
548 
549  GHashIterator ghi;
550 
551  BLI_assert((effects->enabled_effects & EFFECT_MOTION_BLUR) != 0);
552 
553  /* Camera Data. */
554  effects->motion_blur.camera[MB_PREV] = effects->motion_blur.camera[MB_NEXT];
555 
556  /* Swap #position_vbo_cache pointers. */
557  if (effects->motion_blur.position_vbo_cache[MB_PREV]) {
559  NULL,
561  }
565 
566  /* Swap #hair_motion_step_cache pointers. */
569  NULL,
571  }
575 
576  /* Rename attributes in #position_vbo_cache. */
578  !BLI_ghashIterator_done(&ghi);
579  BLI_ghashIterator_step(&ghi)) {
582  int attrib_id = GPU_vertformat_attr_id_get(format, "nxt");
583  GPU_vertformat_attr_rename(format, attrib_id, "prv");
584  }
585 
586  /* Object Data. */
588  BLI_ghashIterator_step(&ghi)) {
590  EEVEE_GeometryMotionData *mb_geom = mb_data->geometry_data;
591  EEVEE_HairMotionData *mb_hair = mb_data->hair_data;
592 
593  copy_m4_m4(mb_data->obmat[MB_PREV], mb_data->obmat[MB_NEXT]);
594 
595  if (mb_hair != NULL) {
596  for (int i = 0; i < mb_hair->psys_len; i++) {
597  mb_hair->psys[i].step_data[MB_PREV].hair_pos =
598  mb_hair->psys[i].step_data[MB_NEXT].hair_pos;
599  mb_hair->psys[i].step_data[MB_PREV].hair_pos_tx =
600  mb_hair->psys[i].step_data[MB_NEXT].hair_pos_tx;
601  mb_hair->psys[i].step_data[MB_NEXT].hair_pos = NULL;
602  mb_hair->psys[i].step_data[MB_NEXT].hair_pos_tx = NULL;
603  }
604  }
605  if (mb_geom != NULL) {
606  if (mb_geom->batch != NULL) {
608  mb_geom->batch, mb_geom->vbo[MB_PREV], mb_geom->vbo[MB_NEXT]);
609  }
610  mb_geom->vbo[MB_PREV] = mb_geom->vbo[MB_NEXT];
611  mb_geom->vbo[MB_NEXT] = NULL;
612  }
613  }
614 }
615 
617 {
618  EEVEE_PassList *psl = vedata->psl;
619  EEVEE_TextureList *txl = vedata->txl;
620  EEVEE_FramebufferList *fbl = vedata->fbl;
621  EEVEE_StorageList *stl = vedata->stl;
622  EEVEE_EffectsInfo *effects = stl->effects;
623 
624  /* Motion Blur */
625  if ((effects->enabled_effects & EFFECT_MOTION_BLUR) != 0) {
626  /* Create velocity max tiles in 2 passes. One for each dimension. */
629 
632 
633  /* Expand the tiles by reading the neighborhood. Do as many passes as required. */
634  int buf = 0;
635  for (int i = effects->motion_blur_max; i > 0; i -= EEVEE_VELOCITY_TILE_SIZE) {
637 
638  /* Change viewport to avoid invoking more pixel shaders than necessary since in one of the
639  * buffer the texture is way bigger in height. This avoid creating another texture and
640  * reduce VRAM usage. */
641  int w = GPU_texture_width(effects->velocity_tiles_tx);
642  int h = GPU_texture_height(effects->velocity_tiles_tx);
643  GPU_framebuffer_viewport_set(fbl->velocity_tiles_fb[buf], 0, 0, w, h);
644 
646 
648 
649  buf = buf ? 0 : 1;
650  }
651 
654  SWAP_BUFFERS();
655  }
656 }
Camera data-block and utility functions.
General operations, lookup, etc. for blender objects.
int BKE_object_is_deform_modified(struct Scene *scene, struct Object *ob)
Definition: object.cc:4982
bool BKE_object_moves_in_time(const struct Object *object, bool recurse_parent)
#define BLI_assert(a)
Definition: BLI_assert.h:46
void BLI_ghashIterator_step(GHashIterator *ghi)
Definition: BLI_ghash.c:914
BLI_INLINE void * BLI_ghashIterator_getValue(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.h:302
void(* GHashValFreeFP)(void *val)
Definition: BLI_ghash.h:38
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:863
void BLI_ghashIterator_init(GHashIterator *ghi, GHash *gh)
Definition: BLI_ghash.c:898
bool BLI_ghash_ensure_p(GHash *gh, void *key, void ***r_val) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:755
BLI_INLINE bool BLI_ghashIterator_done(const GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.h:310
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE int max_ii(int a, int b)
bool equals_m4m4(const float mat1[4][4], const float mat2[4][4])
Definition: math_matrix.c:2531
void copy_m4_m4(float m1[4][4], const float m2[4][4])
Definition: math_matrix.c:77
bool is_zero_m4(const float mat[4][4])
Definition: math_matrix.c:2520
Random number functions.
#define UNUSED(x)
#define ELEM(...)
@ BASE_FROM_DUPLI
Types and defines for representing Rigid Body entities.
@ RBO_TYPE_ACTIVE
@ RBO_FLAG_USE_DEFORM
@ SCE_EEVEE_MOTION_BLUR_ENABLED
@ DRW_STATE_DEPTH_EQUAL
Definition: DRW_render.h:312
@ DRW_STATE_WRITE_COLOR
Definition: DRW_render.h:303
#define DRW_PASS_CREATE(pass, state)
Definition: DRW_render.h:690
#define DRW_shgroup_call(shgroup, geom, ob)
Definition: DRW_render.h:414
GPUBatch
Definition: GPU_batch.h:78
int GPU_batch_vertbuf_add_ex(GPUBatch *, GPUVertBuf *, bool own_vbo)
Definition: gpu_batch.cc:171
#define GPU_BATCH_VBO_MAX_LEN
Definition: GPU_batch.h:20
bool GPU_batch_vertbuf_has(GPUBatch *, GPUVertBuf *)
Definition: gpu_batch.cc:193
void GPU_framebuffer_bind(GPUFrameBuffer *fb)
struct GPUShader GPUShader
Definition: GPU_shader.h:20
eGPUSamplerState
Definition: GPU_texture.h:25
int GPU_texture_height(const GPUTexture *tex)
Definition: gpu_texture.cc:607
struct GPUTexture GPUTexture
Definition: GPU_texture.h:17
GPUTexture * GPU_texture_create_from_vertbuf(const char *name, struct GPUVertBuf *vert)
Definition: gpu_texture.cc:361
int GPU_texture_width(const GPUTexture *tex)
Definition: gpu_texture.cc:602
@ GPU_RGBA16
Definition: GPU_texture.h:94
const GPUVertFormat * GPU_vertbuf_get_format(const GPUVertBuf *verts)
uint GPU_vertbuf_get_vertex_len(const GPUVertBuf *verts)
void GPU_vertbuf_discard(GPUVertBuf *)
struct GPUVertBuf GPUVertBuf
GPUVertBuf * GPU_vertbuf_duplicate(GPUVertBuf *verts)
void GPU_vertbuf_use(GPUVertBuf *)
void GPU_vertformat_attr_rename(GPUVertFormat *format, int attr, const char *new_name)
int GPU_vertformat_attr_id_get(const GPUVertFormat *, const char *name)
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
Scene scene
GPUVertBuf * DRW_cache_object_pos_vertbuf_get(Object *ob)
Definition: draw_cache.c:911
GPUBatch * DRW_cache_object_surface_get(Object *ob)
Definition: draw_cache.c:887
void DRW_hair_duplimat_get(struct Object *object, struct ParticleSystem *psys, struct ModifierData *md, float(*dupli_mat)[4])
struct DRWShadingGroup * DRW_shgroup_curves_create_sub(struct Object *object, struct DRWShadingGroup *shgrp, struct GPUMaterial *gpu_material)
Definition: draw_curves.cc:303
void DRW_curves_update(void)
Definition: draw_curves.cc:414
struct GPUVertBuf * DRW_curves_pos_buffer_get(struct Object *object)
Definition: draw_curves.cc:269
struct GPUVertBuf * DRW_hair_pos_buffer_get(struct Object *object, struct ParticleSystem *psys, struct ModifierData *md)
Definition: draw_hair.cc:193
struct DRWShadingGroup * DRW_shgroup_hair_create_sub(struct Object *object, struct ParticleSystem *psys, struct ModifierData *md, struct DRWShadingGroup *shgrp, struct GPUMaterial *gpu_material)
Definition: draw_hair.cc:235
void DRW_render_instance_buffer_finish(void)
const DRWContextState * DRW_context_state_get(void)
void DRW_cache_restart(void)
const float * DRW_viewport_size_get(void)
Definition: draw_manager.c:288
const float * DRW_viewport_invert_size_get(void)
Definition: draw_manager.c:293
bool DRW_state_is_scene_render(void)
DefaultTextureList * DRW_viewport_texture_list_get(void)
Definition: draw_manager.c:638
float DRW_view_near_distance_get(const DRWView *view)
void DRW_shgroup_uniform_float_copy(DRWShadingGroup *shgroup, const char *name, const float value)
void DRW_view_persmat_get(const DRWView *view, float mat[4][4], bool inverse)
void DRW_shgroup_uniform_texture(DRWShadingGroup *shgroup, const char *name, const GPUTexture *tex)
void DRW_shgroup_uniform_ivec2_copy(DRWShadingGroup *shgroup, const char *name, const int *value)
void DRW_pass_link(DRWPass *first, DRWPass *second)
bool DRW_view_is_persp_get(const DRWView *view)
void DRW_shgroup_uniform_texture_ref_ex(DRWShadingGroup *shgroup, const char *name, GPUTexture **tex, eGPUSamplerState sampler_state)
void DRW_shgroup_call_procedural_triangles(DRWShadingGroup *shgroup, Object *ob, uint tri_count)
void DRW_shgroup_uniform_bool(DRWShadingGroup *shgroup, const char *name, const int *value, int arraysize)
DRWShadingGroup * DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass)
float DRW_view_far_distance_get(const DRWView *view)
void DRW_shgroup_uniform_bool_copy(DRWShadingGroup *shgroup, const char *name, const bool value)
void DRW_shgroup_uniform_mat4(DRWShadingGroup *shgroup, const char *name, const float(*value)[4])
void DRW_shgroup_uniform_vec2(DRWShadingGroup *shgroup, const char *name, const float *value, int arraysize)
void DRW_view_viewmat_get(const DRWView *view, float mat[4][4], bool inverse)
void DRW_draw_pass(DRWPass *pass)
GPUTexture * DRW_texture_pool_query_2d(int w, int h, eGPUTextureFormat format, DrawEngineType *engine_type)
void EEVEE_motion_blur_data_init(EEVEE_MotionBlurData *mb)
Definition: eevee_data.c:81
EEVEE_GeometryMotionData * EEVEE_motion_blur_geometry_data_get(EEVEE_ObjectMotionData *mb_data)
Definition: eevee_data.c:153
void EEVEE_motion_hair_step_free(EEVEE_HairMotionStepData *step_data)
Definition: eevee_data.c:74
EEVEE_HairMotionData * EEVEE_motion_blur_curves_data_get(EEVEE_ObjectMotionData *mb_data)
Definition: eevee_data.c:177
EEVEE_HairMotionData * EEVEE_motion_blur_hair_data_get(EEVEE_ObjectMotionData *mb_data, Object *ob)
Definition: eevee_data.c:163
EEVEE_ObjectMotionData * EEVEE_motion_blur_object_data_get(EEVEE_MotionBlurData *mb, Object *ob, bool is_psys)
Definition: eevee_data.c:117
DrawEngineType draw_engine_eevee_type
Definition: eevee_engine.c:618
struct GPUTexture * EEVEE_materials_get_util_tex(void)
void EEVEE_motion_blur_cache_finish(EEVEE_Data *vedata)
static void eevee_motion_blur_sync_camera(EEVEE_Data *vedata)
void EEVEE_motion_blur_swap_data(EEVEE_Data *vedata)
void EEVEE_motion_blur_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
static void motion_blur_remove_vbo_reference_from_batch(GPUBatch *batch, GPUVertBuf *vbo1, GPUVertBuf *vbo2)
void EEVEE_motion_blur_step_set(EEVEE_Data *vedata, int step)
void EEVEE_motion_blur_cache_populate(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata, Object *ob)
void EEVEE_motion_blur_draw(EEVEE_Data *vedata)
int EEVEE_motion_blur_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
void EEVEE_motion_blur_curves_cache_populate(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata, Object *ob)
void EEVEE_motion_blur_hair_cache_populate(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata, Object *ob, ParticleSystem *psys, ModifierData *md)
struct GPUShader * EEVEE_shaders_effect_motion_blur_sh_get(void)
#define SWAP_BUFFERS()
Definition: eevee_private.h:88
#define EEVEE_VELOCITY_TILE_SIZE
Definition: eevee_private.h:74
struct GPUShader * EEVEE_shaders_effect_motion_blur_velocity_tiles_sh_get(void)
struct GPUShader * EEVEE_shaders_effect_motion_blur_hair_sh_get(void)
#define MB_PREV
@ EFFECT_MOTION_BLUR
@ EFFECT_VELOCITY_BUFFER
@ EFFECT_POST_BUFFER
#define MB_NEXT
struct GPUShader * EEVEE_shaders_effect_motion_blur_velocity_tiles_expand_sh_get(void)
#define MB_CURR
struct GPUShader * EEVEE_shaders_effect_motion_blur_object_sh_get(void)
struct @653::@655 batch
void GPU_framebuffer_viewport_reset(GPUFrameBuffer *gpu_fb)
void GPU_framebuffer_viewport_set(GPUFrameBuffer *gpu_fb, int x, int y, int width, int height)
const int state
ccl_gpu_kernel_postfix ccl_global float int int int int sh
format
Definition: logImageCore.h:38
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
#define fabsf(x)
Definition: metal/compat.h:219
struct Scene * scene
Definition: DRW_render.h:979
struct GPUTexture * depth
EEVEE_TextureList * txl
EEVEE_StorageList * stl
EEVEE_PassList * psl
EEVEE_FramebufferList * fbl
struct GPUTexture * source_buffer
float motion_blur_near_far[2]
struct GPUTexture * velocity_tiles_x_tx
struct GPUFrameBuffer * target_buffer
struct GPUTexture * velocity_tiles_tx
EEVEE_EffectsFlag enabled_effects
struct GPUTexture * velocity_tx
struct EEVEE_MotionBlurData motion_blur
struct GPUFrameBuffer * main_fb
struct GPUFrameBuffer * velocity_tiles_fb[2]
struct GPUVertBuf * vbo[2]
struct GPUBatch * batch
EEVEE_HairMotionStepData step_data[2]
struct EEVEE_HairMotionData::@209 psys[0]
struct GPUTexture * hair_pos_tx
struct GPUVertBuf * hair_pos
struct GHash * hair_motion_step_cache[2]
struct EEVEE_MotionBlurData::@208 camera[3]
struct GHash * position_vbo_cache[2]
struct GHash * object
DRWShadingGroup * hair_grp
float obmat[3][4][4]
EEVEE_GeometryMotionData * geometry_data
EEVEE_HairMotionData * hair_data
struct DRWPass * velocity_object
struct DRWPass * velocity_tiles
struct DRWPass * motion_blur
struct DRWPass * velocity_tiles_expand[2]
struct DRWPass * velocity_tiles_x
struct DRWPass * velocity_hair
struct EEVEE_EffectsInfo * effects
short base_flag
ListBase modifiers
struct RigidBodyOb * rigidbody_object
float obmat[4][4]
float motion_blur_depth_scale
struct SceneEEVEE eevee