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: 11daa21629aaae6053cb06f2edfaee0cb8134f1f (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
/* 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. */
  constexpr static uint64_t dof_web_density_ = 6;
  /* High number of sample for viewport infinite rendering. */
  constexpr static uint64_t infinite_sample_count_ = 0xFFFFFFu;
  /* During interactive rendering, loop over the first few samples. */
  constexpr static uint64_t interactive_sample_max_ = 8;

  /** 0 based current sample. */
  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. */
  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;

  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_);
  }

  /* 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_ - 1);
  }

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

  /* 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