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

eevee_velocity.hh « eevee_next « engines « draw « blender « source - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: e2606c061e114ac0ff86e74875d2d0676a18a713 (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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
/* SPDX-License-Identifier: GPL-2.0-or-later
 * Copyright 2021 Blender Foundation.
 */

/** \file
 * \ingroup eevee
 *
 * The velocity pass outputs motion vectors to use for either
 * temporal re-projection or motion blur.
 *
 * It is the module that tracks the objects data between frames updates.
 */

#pragma once

#include "BLI_map.hh"

#include "eevee_shader_shared.hh"
#include "eevee_sync.hh"

namespace blender::eevee {

/* -------------------------------------------------------------------- */
/** \name VelocityModule
 *
 * \{ */

/** Container for scene velocity data. */
class VelocityModule {
  friend class VelocityView;

 public:
  struct VelocityObjectData : public VelocityIndex {
    /** ID to retrieve the corresponding #VelocityGeometryData after copy. */
    ID *id;
  };
  struct VelocityGeometryData {
    /** VertBuf not yet ready to be copied to the #VelocityGeometryBuf. */
    GPUVertBuf *pos_buf = nullptr;
    /* Offset in the #VelocityGeometryBuf to the start of the data. In vertex. */
    int ofs;
    /* Length of the vertex buffer. In vertex. */
    int len;
  };
  /**
   * The map contains indirection indices to the obmat and geometry in each step buffer.
   * Note that each object component gets its own resource id so one component correspond to one
   * geometry offset.
   */
  Map<ObjectKey, VelocityObjectData> velocity_map;
  /** Geometry to be copied to VelocityGeometryBuf. Indexed by evaluated ID *. Empty after */
  Map<ID *, VelocityGeometryData> geometry_map;
  /** Contains all objects matrices for each time step. */
  std::array<VelocityObjectBuf *, 3> object_steps;
  /** Contains all Geometry steps from deforming objects for each time step. */
  std::array<VelocityGeometryBuf *, 3> geometry_steps;
  /** Number of occupied slot in each `object_steps`. */
  int3 object_steps_usage = int3(0);
  /** Buffer of all #VelocityIndex used in this frame. Indexed by draw manager resource id. */
  VelocityIndexBuf indirection_buf;

  /**
   * Copies of camera data. One for previous and one for next time step.
   */
  std::array<CameraDataBuf *, 3> camera_steps;

 private:
  Instance &inst_;

  eVelocityStep step_ = STEP_CURRENT;

  DRWPass *resolve_ps_ = nullptr;

  /** Reference only. Not owned. */
  GPUTexture *input_depth_tx_;
  GPUTexture *velocity_view_tx_;
  GPUTexture *velocity_camera_tx_;

  int3 resolve_dispatch_size_ = int3(1, 1, 1);

 public:
  VelocityModule(Instance &inst) : inst_(inst)
  {
    for (VelocityObjectBuf *&step_buf : object_steps) {
      step_buf = new VelocityObjectBuf();
    }
    for (VelocityGeometryBuf *&step_buf : geometry_steps) {
      step_buf = new VelocityGeometryBuf();
    }
    for (CameraDataBuf *&step_buf : camera_steps) {
      step_buf = new CameraDataBuf();
    }
  };

  ~VelocityModule()
  {
    for (VelocityObjectBuf *step_buf : object_steps) {
      delete step_buf;
    }
    for (VelocityGeometryBuf *step_buf : geometry_steps) {
      delete step_buf;
    }
    for (CameraDataBuf *step_buf : camera_steps) {
      delete step_buf;
    }
  }

  void init();

  void step_camera_sync();
  void step_sync(eVelocityStep step, float time);

  /* Gather motion data. Returns true if the object **can** have motion. */
  bool step_object_sync(Object *ob, ObjectKey &object_key, int recalc = 0);

  /* Moves next frame data to previous frame data. Nullify next frame data. */
  void step_swap();

  void begin_sync();
  void end_sync();

  void bind_resources(DRWShadingGroup *grp);

 private:
  bool object_has_velocity(const Object *ob);
  bool object_is_deform(const Object *ob);

  void resolve_camera_motion(GPUTexture *depth_tx,
                             GPUTexture *velocity_view_tx,
                             GPUTexture *velocity_camera_tx);
};

/** \} */

/* -------------------------------------------------------------------- */
/** \name Velocity
 *
 * \{ */

/**
 * Per view module.
 */
class VelocityView {
 private:
  Instance &inst_;

  StringRefNull view_name_;

  TextureFromPool velocity_camera_tx_ = {"velocity_camera_tx_"};
  TextureFromPool velocity_view_tx_ = {"velocity_view_tx_"};

 public:
  VelocityView(Instance &inst, const char *name) : inst_(inst), view_name_(name){};
  ~VelocityView(){};

  void sync();

  void acquire(int2 extent);
  void release();

  void resolve(GPUTexture *depth_tx);

  /**
   * Getters
   **/
  GPUTexture *view_vectors_get() const
  {
    return velocity_view_tx_;
  }
  GPUTexture *camera_vectors_get() const
  {
    return (velocity_camera_tx_.is_valid()) ? velocity_camera_tx_ : velocity_view_tx_;
  }
};

/** \} */

}  // namespace blender::eevee