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

eevee_depth_of_field.hh « eevee « engines « draw « blender « source - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 81e796a1fbf4450a0f7586c4bd88f1e100717c44 (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
/*
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 * Copyright 2021, Blender Foundation.
 */

/** \file
 * \ingroup eevee
 *
 * Depth of field post process effect.
 *
 * There are 2 methods to achieve this effect.
 * - The first uses projection matrix offsetting and sample accumulation to give
 * reference quality depth of field. But this needs many samples to hide the
 * under-sampling.
 * - The second one is a post-processing based one. It follows the
 * implementation described in the presentation "Life of a Bokeh - Siggraph
 * 2018" from Guillaume Abadie. There are some difference with our actual
 * implementation that prioritize quality.
 */

#pragma once

#include "eevee_shader_shared.hh"

namespace blender::eevee {

class Instance;

/* -------------------------------------------------------------------- */
/** \name Depth of field
 * \{ */

class DepthOfField {
 private:
  class Instance &inst_;

  DepthOfFieldDataBuf data_;

  /** Textures from pool. Not owned. */
  GPUTexture *bokeh_gather_lut_tx_ = nullptr;
  GPUTexture *bokeh_resolve_lut_tx_ = nullptr;
  GPUTexture *bokeh_scatter_lut_tx_ = nullptr;
  GPUTexture *color_bg_tx_ = nullptr;
  GPUTexture *color_fg_tx_ = nullptr;
  GPUTexture *color_holefill_tx_ = nullptr;
  GPUTexture *occlusion_tx_ = nullptr;
  GPUTexture *reduce_downsample_tx_ = nullptr;
  GPUTexture *scatter_src_tx_ = nullptr;
  GPUTexture *setup_coc_tx_ = nullptr;
  GPUTexture *setup_color_tx_ = nullptr;
  GPUTexture *tiles_bg_tx_ = nullptr;
  GPUTexture *tiles_fg_tx_ = nullptr;
  GPUTexture *tiles_dilated_bg_tx_ = nullptr;
  GPUTexture *tiles_dilated_fg_tx_ = nullptr;
  GPUTexture *weight_bg_tx_ = nullptr;
  GPUTexture *weight_fg_tx_ = nullptr;
  GPUTexture *weight_holefill_tx_ = nullptr;
  /** Allocated textures. Owned. */
  Texture reduced_coc_tx_ = {"dof_reduced_coc"};
  Texture reduced_color_tx_ = {"dof_reduced_color"};
  /** Input texture. Not owned. */
  GPUTexture *input_color_tx_;
  GPUTexture *input_depth_tx_;
  /** Passes. Not owned. */
  DRWPass *bokeh_lut_ps_ = nullptr;
  DRWPass *gather_bg_ps_ = nullptr;
  DRWPass *gather_fg_ps_ = nullptr;
  DRWPass *filter_ps_ = nullptr;
  DRWPass *gather_holefill_ps_ = nullptr;
  DRWPass *reduce_copy_ps_ = nullptr;
  DRWPass *reduce_downsample_ps_ = nullptr;
  DRWPass *reduce_recursive_ps_ = nullptr;
  DRWPass *resolve_ps_ = nullptr;
  DRWPass *scatter_bg_ps_ = nullptr;
  DRWPass *scatter_fg_ps_ = nullptr;
  DRWPass *setup_ps_ = nullptr;
  DRWPass *tiles_dilate_minabs_ps_ = nullptr;
  DRWPass *tiles_dilate_minmax_ps_ = nullptr;
  DRWPass *tiles_flatten_ps_ = nullptr;
  /** Framebuffers. Owned.  */
  Framebuffer bokeh_lut_fb_ = {"bokeh_lut_fb_"};
  Framebuffer filter_bg_fb_ = {"filter_bg_fb_"};
  Framebuffer filter_fg_fb_ = {"filter_fg_fb_"};
  Framebuffer gather_fb_ = {"gather_fb_"};
  Framebuffer gather_filter_bg_fb_ = {"gather_filter_bg_fb_"};
  Framebuffer gather_holefill_fb_ = {"gather_holefill_fb_"};
  Framebuffer reduce_copy_fb_ = {"reduce_copy_fb_"};
  Framebuffer reduce_downsample_fb_ = {"reduce_downsample_fb_"};
  Framebuffer reduce_fb_ = {"reduce_fb_"};
  Framebuffer resolve_fb_ = {"resolve_fb_"};
  Framebuffer scatter_bg_fb_ = {"scatter_bg_fb_"};
  Framebuffer scatter_fg_fb_ = {"scatter_fg_fb_"};
  Framebuffer setup_fb_ = {"setup_fb_"};
  Framebuffer tiles_dilate_fb_ = {"tiles_dilate_fb_"};
  Framebuffer tiles_flatten_fb_ = {"tiles_flatten_fb_"};

  /** Scene settings that are immutable. */
  float user_overblur_;
  float fx_max_coc_;
  /** Use Hiqh Quality (expensive) in-focus gather pass. */
  bool do_hq_slight_focus_;
  /** Use jittered depth of field where we randomize camera location. */
  bool do_jitter_;

  /** Circle of Confusion radius for FX DoF passes. Is in view X direction in [0..1] range. */
  float fx_radius_;
  /** Circle of Confusion radius for jittered DoF. Is in view X direction in [0..1] range. */
  float jitter_radius_;
  /** Focus distance in view space. */
  float focus_distance_;
  /** Extent of the input buffer. */
  int2 extent_;

  /** Tile dilation uniforms. */
  int tiles_dilate_slight_focus_;
  int tiles_dilate_ring_count_;
  int tiles_dilate_ring_width_multiplier_;

  /** Reduce pass info. */
  int reduce_steps_;

  /** Static string pointer. Used as debug name and as UUID for texture pool. */
  StringRefNull view_name_;

 public:
  DepthOfField(Instance &inst, StringRefNull view_name) : inst_(inst), view_name_(view_name){};
  ~DepthOfField(){};

  void init();

  void sync(const float4x4 &winmat, int2 input_extent);

  /** Apply Depth Of Field jittering to the view and projection matrices.. */
  void jitter_apply(float4x4 &winmat, float4x4 &viewmat);

  /** Will swap input and output texture if rendering happens. The actual output of this function
   * is in intput_tx. */
  void render(GPUTexture *depth_tx, GPUTexture **input_tx, GPUTexture **output_tx);

 private:
  void bokeh_lut_pass_sync(void);
  void bokeh_lut_pass_render(void);

  void setup_pass_sync(void);
  void setup_pass_render(void);

  void tiles_prepare_pass_sync(void);
  void tiles_prepare_pass_render(void);

  static void reduce_recusive(void *thunk, int level);
  void reduce_pass_sync(void);
  void reduce_pass_render(void);

  void convolve_pass_sync(void);
  void convolve_pass_render(void);

  void resolve_pass_sync(void);
  void resolve_pass_render(GPUTexture *output_tx);
};

/** \} */

}  // namespace blender::eevee