Welcome to mirror list, hosted at ThFree Co, Russian Federation.

eevee_motion_blur.hh « eevee_next « engines « draw « blender « source - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 310e94a702b912e6b2149b2d5325892dec1f10ac (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/* SPDX-License-Identifier: GPL-2.0-or-later
 * Copyright 2022 Blender Foundation.
 */

/** \file
 * \ingroup eevee
 *
 * Motion blur is done by accumulating scene samples over shutter time.
 * Since the number of step is discrete, quite low, and not per pixel randomized,
 * we couple this with a post processing motion blur.
 *
 * The post-fx motion blur is done in two directions, from the previous step and to the next.
 *
 * For a scene with 3 motion steps, a flat shutter curve and shutter time of 2 frame
 * centered on frame we have:
 *
 * |--------------------|--------------------|
 * -1                   0                    1  Frames
 *
 * |-------------|-------------|-------------|
 *        1             2             3         Motion steps
 *
 * |------|------|------|------|------|------|
 * 0      1      2      4      5      6      7  Time Steps
 *
 * |-------------| One motion step blurs this range.
 * -1     |     +1 Objects and geometry steps are recorded here.
 *        0 Scene is rendered here.
 *
 * Since motion step N and N+1 share one time step we reuse it to avoid an extra scene evaluation.
 *
 * Note that we have to evaluate -1 and +1 time steps before rendering so eval order is -1, +1, 0.
 * This is because all GPUBatches from the DRWCache are being free when changing a frame.
 *
 * For viewport, we only have the current and previous step data to work with. So we center the
 * blur on the current frame and extrapolate the motion.
 *
 * The Post-FX motion blur is based on:
 * "A Fast and Stable Feature-Aware Motion Blur Filter"
 * by Jean-Philippe Guertin, Morgan McGuire, Derek Nowrouzezahrai
 */

#pragma once

#include "BLI_map.hh"
#include "DEG_depsgraph_query.h"

#include "eevee_sampling.hh"
#include "eevee_shader_shared.hh"
#include "eevee_velocity.hh"

namespace blender::eevee {

/* -------------------------------------------------------------------- */
/** \name MotionBlur
 *
 * \{ */

/**
 * Manages time-steps evaluations and accumulation Motion blur.
 * Also handles Post process motion blur.
 */
class MotionBlurModule {
 private:
  Instance &inst_;

  /**
   * Array containing all steps (in scene time) we need to evaluate (not render).
   * Only odd steps are rendered. The even ones are evaluated for fx motion blur.
   */
  Vector<float> time_steps_;

  /** Copy of input frame and sub-frame to restore after render. */
  int initial_frame_;
  float initial_subframe_;
  /** Time of the frame we are rendering. */
  float frame_time_;
  /** Enum controlling when the shutter opens. See SceneEEVEE.motion_blur_position. */
  int shutter_position_;
  /** Time in scene frame the shutter is open. Controls the amount of blur. */
  float shutter_time_;

  /** True if motion blur is enabled as a module. */
  bool enabled_ = false;
  /** True if motion blur post-fx is enabled. */
  float motion_blur_fx_enabled_ = false;
  /** True if last viewport redraw state was already in navigation state. */
  bool was_navigating_ = false;

  int step_id_ = 0;

  /** Velocity tiles used to guide and speedup the gather pass. */
  TextureFromPool tiles_tx_;

  GPUTexture *input_color_tx_ = nullptr;
  GPUTexture *output_color_tx_ = nullptr;

  DRWPass *tiles_flatten_ps_ = nullptr;
  DRWPass *tiles_dilate_ps_ = nullptr;
  DRWPass *gather_ps_ = nullptr;

  MotionBlurTileIndirectionBuf tile_indirection_buf_;
  MotionBlurDataBuf data_;
  /** Dispatch size for full-screen passes. */
  int3 dispatch_flatten_size_ = int3(0);
  int3 dispatch_dilate_size_ = int3(0);
  int3 dispatch_gather_size_ = int3(0);

 public:
  MotionBlurModule(Instance &inst) : inst_(inst){};
  ~MotionBlurModule(){};

  void init();

  void step();

  void sync();

  bool postfx_enabled() const
  {
    return motion_blur_fx_enabled_;
  }

  void render(GPUTexture **input_tx, GPUTexture **output_tx);

 private:
  float shutter_time_to_scene_time(float time);
};

/** \} */

}  // namespace blender::eevee