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

eevee_sampling.hh « eevee_next « engines « draw « blender « source - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 72a906d5988f08700aa7c73211e8c1f6d833d18f (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
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
/* SPDX-License-Identifier: GPL-2.0-or-later
 * Copyright 2021 Blender Foundation.
 */

/** \file
 * \ingroup eevee
 *
 * Random number generator, contains persistent state and sample count logic.
 */

#pragma once

#include "BKE_colortools.h"
#include "BLI_system.h"
#include "BLI_vector.hh"
#include "DNA_scene_types.h"
#include "DRW_render.h"

#include "eevee_shader_shared.hh"

namespace blender::eevee {

class Instance;

class Sampling {
 private:
  Instance &inst_;

  /* Number of samples in the first ring of jittered depth of field. */
  static constexpr uint64_t dof_web_density_ = 6;
  /* High number of sample for viewport infinite rendering. */
  static constexpr uint64_t infinite_sample_count_ = 0xFFFFFFu;
  /* During interactive rendering, loop over the first few samples. */
  static constexpr uint64_t interactive_sample_max_ = 8;

  /** 0 based current sample. Might not increase sequentially in viewport. */
  uint64_t sample_ = 0;
  /** Target sample count. */
  uint64_t sample_count_ = 64;
  /** Number of ring in the web pattern of the jittered Depth of Field. */
  uint64_t dof_ring_count_ = 0;
  /** Number of samples in the web pattern of the jittered Depth of Field. */
  uint64_t dof_sample_count_ = 1;
  /** Motion blur steps. */
  uint64_t motion_blur_steps_ = 1;
  /** Increases if the view and the scene is static. Does increase sequentially. */
  int64_t viewport_sample_ = 0;
  /** Tag to reset sampling for the next sample. */
  bool reset_ = false;
  /**
   * Switch between interactive and static accumulation.
   * In interactive mode, image stability is prioritized over quality.
   */
  bool interactive_mode_ = false;
  /**
   * Sample count after which we use the static accumulation.
   * Interactive sampling from sample 0 to (interactive_mode_threshold - 1).
   * Accumulation sampling from sample interactive_mode_threshold to sample_count_.
   */
  static constexpr int interactive_mode_threshold = 3;

  SamplingDataBuf data_;

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

  void init(const Scene *scene);
  void end_sync();
  void step();

  /* Viewport Only: Function to call to notify something in the scene changed.
   * This will reset accumulation. Do not call after end_sync() or during sample rendering. */
  void reset()
  {
    reset_ = true;
  }

  /* Viewport Only: true if an update happened in the scene and accumulation needs reset. */
  bool is_reset() const
  {
    return reset_;
  }

  void bind_resources(DRWShadingGroup *grp)
  {
    DRW_shgroup_storage_block_ref(grp, "sampling_buf", &data_);
  }

  template<typename T> void bind_resources(draw::detail::PassBase<T> *pass)
  {
    /* Storage Buf. */
    pass->bind(SAMPLING_BUF_SLOT, &data_);
  }

  /* Returns a pseudo random number in [0..1] range. Each dimension are de-correlated. */
  float rng_get(eSamplingDimension dimension) const
  {
    return data_.dimensions[dimension];
  }

  /* Returns a pseudo random number in [0..1] range. Each dimension are de-correlated. */
  float2 rng_2d_get(eSamplingDimension starting_dimension) const
  {
    return *reinterpret_cast<const float2 *>(&data_.dimensions[starting_dimension]);
  }

  /* Returns a pseudo random number in [0..1] range. Each dimension are de-correlated. */
  float3 rng_3d_get(eSamplingDimension starting_dimension) const
  {
    return *reinterpret_cast<const float3 *>(&data_.dimensions[starting_dimension]);
  }

  /* Returns true if rendering has finished. */
  bool finished() const
  {
    return (sample_ >= sample_count_);
  }

  /* Returns true if viewport smoothing and sampling has finished. */
  bool finished_viewport() const
  {
    return (viewport_sample_ >= sample_count_) && !interactive_mode_;
  }

  /* Returns true if viewport renderer is in interactive mode and should use TAA. */
  bool interactive_mode() const
  {
    return interactive_mode_;
  }

  uint64_t sample_count() const
  {
    return sample_count_;
  }

  /* Return true if we are starting a new motion blur step. We need to run sync again since
   * depsgraph was updated by MotionBlur::step(). */
  bool do_render_sync() const
  {
    return ((sample_ % (sample_count_ / motion_blur_steps_)) == 0);
  }

  /**
   * Special ball distribution:
   * Point are distributed in a way that when they are orthogonally
   * projected into any plane, the resulting distribution is (close to)
   * a uniform disc distribution.
   * \a rand is 3 random float in the [0..1] range.
   * Returns point in a ball of radius 1 and centered on the origin.
   */
  static float3 sample_ball(const float3 &rand);

  /**
   * Uniform disc distribution.
   * \a rand is 2 random float in the [0..1] range.
   * Returns point in a disk of radius 1 and centered on the origin.
   */
  static float2 sample_disk(const float2 &rand);

  /**
   * Uniform disc distribution using Fibonacci spiral sampling.
   * \a rand is 2 random float in the [0..1] range.
   * Returns point in a disk of radius 1 and centered on the origin.
   */
  static float2 sample_spiral(const float2 &rand);

  /**
   * Special RNG for depth of field.
   * Returns \a radius and \a theta angle offset to apply to the web sampling pattern.
   */
  void dof_disk_sample_get(float *r_radius, float *r_theta) const;

  /**
   * Returns sample count inside the jittered depth of field web pattern.
   */
  uint64_t dof_ring_count_get() const
  {
    return dof_ring_count_;
  }

  /**
   * Returns sample count inside the jittered depth of field web pattern.
   */
  uint64_t dof_sample_count_get() const
  {
    return dof_sample_count_;
  }

  /* Cumulative Distribution Function Utils. */
  static void cdf_from_curvemapping(const CurveMapping &curve, Vector<float> &cdf);
  static void cdf_invert(Vector<float> &cdf, Vector<float> &inverted_cdf);
};

}  // namespace blender::eevee