Overte C++ Documentation
AntialiasingEffect.h
1 //
2 // AntialiasingEffect.h
3 // libraries/render-utils/src/
4 //
5 // Created by Raffi Bedikian on 8/30/15
6 // Copyright 2015 High Fidelity, Inc.
7 // Copyright 2022-2023 Overte e.V.
8 //
9 // Distributed under the Apache License, Version 2.0.
10 // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
11 // SPDX-License-Identifier: Apache-2.0
12 //
13 
14 #ifndef hifi_AntialiasingEffect_h
15 #define hifi_AntialiasingEffect_h
16 
17 #include <DependencyManager.h>
18 
19 #include "render/DrawTask.h"
20 #include "DeferredFrameTransform.h"
21 #include "VelocityBufferPass.h"
22 
23 
24 class JitterSampleConfig : public render::Job::Config {
25  Q_OBJECT
26  Q_PROPERTY(float scale MEMBER scale NOTIFY dirty)
27  Q_PROPERTY(bool freeze MEMBER freeze NOTIFY dirty)
28  Q_PROPERTY(bool stop MEMBER stop NOTIFY dirty)
29  Q_PROPERTY(int index READ getIndex NOTIFY dirty)
30  Q_PROPERTY(int state READ getState WRITE setState NOTIFY dirty)
31 public:
32  JitterSampleConfig() : render::Job::Config(true) {}
33 
34  float scale{ 0.5f };
35  bool stop{ false };
36  bool freeze{ false };
37 
38  void setIndex(int current);
39  void setState(int state);
40 
41 public slots:
42  int cycleStopPauseRun();
43  int prev();
44  int next();
45  int none();
46  int pause();
47  int play();
48 
49  int getIndex() const { return _index; }
50  int getState() const { return _state; }
51 signals:
52  void dirty();
53 
54 private:
55  int _state{ 0 };
56  int _index{ 0 };
57 
58 };
59 
60 
61 class JitterSample {
62 public:
63 
64  enum {
65  SEQUENCE_LENGTH = 64
66  };
67 
68  using Config = JitterSampleConfig;
69  using Output = glm::vec2;
70  using JobModel = render::Job::ModelO<JitterSample, Output, Config>;
71 
72  void configure(const Config& config);
73  void run(const render::RenderContextPointer& renderContext, Output& jitter);
74 
75 private:
76 
77  struct SampleSequence {
78  SampleSequence();
79 
80  glm::vec2 offsets[SEQUENCE_LENGTH + 1];
81  int sequenceLength{ SEQUENCE_LENGTH };
82  int currentIndex{ 0 };
83  };
84 
85  SampleSequence _sampleSequence;
86  float _scale{ 1.0 };
87  bool _freeze{ false };
88 };
89 
90 
91 class AntialiasingConfig : public render::Job::Config {
92  Q_OBJECT
93  Q_PROPERTY(int mode READ getAAMode WRITE setAAMode NOTIFY dirty)
94  Q_PROPERTY(float blend MEMBER blend NOTIFY dirty)
95  Q_PROPERTY(float sharpen MEMBER sharpen NOTIFY dirty)
96  Q_PROPERTY(float covarianceGamma MEMBER covarianceGamma NOTIFY dirty)
97 
98  Q_PROPERTY(bool constrainColor MEMBER constrainColor NOTIFY dirty)
99  Q_PROPERTY(bool feedbackColor MEMBER feedbackColor NOTIFY dirty)
100 
101  Q_PROPERTY(bool debug MEMBER debug NOTIFY dirty)
102  Q_PROPERTY(float debugX MEMBER debugX NOTIFY dirty)
103  Q_PROPERTY(bool fxaaOnOff READ debugFXAA WRITE setDebugFXAA NOTIFY dirty)
104  Q_PROPERTY(float debugShowVelocityThreshold MEMBER debugShowVelocityThreshold NOTIFY dirty)
105  Q_PROPERTY(bool showCursorPixel MEMBER showCursorPixel NOTIFY dirty)
106  Q_PROPERTY(glm::vec2 debugCursorTexcoord MEMBER debugCursorTexcoord NOTIFY dirty)
107  Q_PROPERTY(float debugOrbZoom MEMBER debugOrbZoom NOTIFY dirty)
108 
109  Q_PROPERTY(bool showClosestFragment MEMBER showClosestFragment NOTIFY dirty)
110 
111 public:
112  AntialiasingConfig() : render::Job::Config(true) {}
113 
114  /*@jsdoc
115  *Antialiasing modes. <table>
116  * <thead>
117  * <tr><th>Value</th><th>Name</th><th>Description</th>
118  * </thead>
119  * <tbody>
120  * <tr><td><code>0</code></td><td>NONE</td><td>Antialiasing is disabled.</td></tr>
121  * <tr><td><code>1</code></td><td>TAA</td><td>Temporal Antialiasing.</td></tr>
122  * <tr><td><code>2</code></td><td>FXAA</td><td>FXAA.</td></tr>
123  * <tr><td><code>3</code></td><td>MODE_COUNT</td><td>Inducates number of antialiasing modes</td></tr>
124  * </tbody>
125  * </table>
126  * @typedef {number} AntialiasingMode
127  */
128  enum Mode {
129  NONE = 0,
130  TAA,
131  FXAA,
132  MODE_COUNT
133  };
134  Q_ENUM(Mode) // Stored as signed int.
135 
136  void setAAMode(int mode);
137  int getAAMode() const { return _mode; }
138 
139  void setDebugFXAA(bool debug) { debugFXAAX = (debug ? 0.0f : 1.0f); emit dirty();}
140  bool debugFXAA() const { return (debugFXAAX == 0.0f ? true : false); }
141 
142  int _mode{ TAA }; // '_' prefix but not private?
143 
144  float blend{ 0.25f };
145  float sharpen{ 0.05f };
146 
147  bool constrainColor{ true };
148  float covarianceGamma{ 0.65f };
149  bool feedbackColor{ false };
150 
151  float debugX{ 0.0f };
152  float debugFXAAX{ 1.0f };
153  float debugShowVelocityThreshold{ 1.0f };
154  glm::vec2 debugCursorTexcoord{ 0.5f, 0.5f };
155  float debugOrbZoom{ 2.0f };
156 
157  bool debug { false };
158  bool showCursorPixel { false };
159  bool showClosestFragment{ false };
160 
161 signals:
162  void dirty();
163 };
164 
165 #define SET_BIT(bitfield, bitIndex, value) bitfield = ((bitfield) & ~(1 << (bitIndex))) | ((value) << (bitIndex))
166 #define GET_BIT(bitfield, bitIndex) ((bitfield) & (1 << (bitIndex)))
167 
168 #define ANTIALIASING_USE_TAA 1
169 
170 #if ANTIALIASING_USE_TAA
171 
172 struct TAAParams {
173  float nope{ 0.0f };
174  float blend{ 0.15f };
175  float covarianceGamma{ 1.0f };
176  float debugShowVelocityThreshold{ 1.0f };
177 
178  glm::ivec4 flags{ 0 };
179  glm::vec4 pixelInfo{ 0.5f, 0.5f, 2.0f, 0.0f };
180  glm::vec4 regionInfo{ 0.0f, 0.0f, 1.0f, 0.0f };
181 
182  void setConstrainColor(bool enabled) { SET_BIT(flags.y, 1, enabled); }
183  bool isConstrainColor() const { return (bool)GET_BIT(flags.y, 1); }
184 
185  void setFeedbackColor(bool enabled) { SET_BIT(flags.y, 4, enabled); }
186  bool isFeedbackColor() const { return (bool)GET_BIT(flags.y, 4); }
187 
188  void setDebug(bool enabled) { SET_BIT(flags.x, 0, enabled); }
189  bool isDebug() const { return (bool) GET_BIT(flags.x, 0); }
190 
191  void setShowDebugCursor(bool enabled) { SET_BIT(flags.x, 1, enabled); }
192  bool showDebugCursor() const { return (bool)GET_BIT(flags.x, 1); }
193 
194  void setDebugCursor(glm::vec2 debugCursor) { pixelInfo.x = debugCursor.x; pixelInfo.y = debugCursor.y; }
195  glm::vec2 getDebugCursor() const { return glm::vec2(pixelInfo.x, pixelInfo.y); }
196 
197  void setDebugOrbZoom(float orbZoom) { pixelInfo.z = orbZoom; }
198  float getDebugOrbZoom() const { return pixelInfo.z; }
199 
200  void setShowClosestFragment(bool enabled) { SET_BIT(flags.x, 3, enabled); }
201 
202 };
203 using TAAParamsBuffer = gpu::StructBuffer<TAAParams>;
204 
205 class Antialiasing {
206 public:
207  using Inputs = render::VaryingSet4 < DeferredFrameTransformPointer, gpu::FramebufferPointer, LinearDepthFramebufferPointer, VelocityFramebufferPointer > ;
208  using Config = AntialiasingConfig;
209  using JobModel = render::Job::ModelI<Antialiasing, Inputs, Config>;
210 
211  Antialiasing(bool isSharpenEnabled = true);
212  ~Antialiasing();
213  void configure(const Config& config);
214  void run(const render::RenderContextPointer& renderContext, const Inputs& inputs);
215 
216  const gpu::PipelinePointer& getAntialiasingPipeline(const render::RenderContextPointer& renderContext);
217  const gpu::PipelinePointer& getBlendPipeline();
218  const gpu::PipelinePointer& getDebugBlendPipeline();
219 
220 private:
221 
222  gpu::FramebufferSwapChainPointer _antialiasingBuffers;
223  gpu::TexturePointer _antialiasingTextures[2];
224  gpu::BufferPointer _blendParamsBuffer;
225  gpu::PipelinePointer _antialiasingPipeline;
226  gpu::PipelinePointer _blendPipeline;
227  gpu::PipelinePointer _debugBlendPipeline;
228 
229  TAAParamsBuffer _params;
230  AntialiasingConfig::Mode _mode{ AntialiasingConfig::TAA };
231  float _sharpen{ 0.15f };
232  bool _isSharpenEnabled{ true };
233 };
234 
235 
236 #else // User setting for antialias mode will probably be broken.
237 class AntiAliasingConfig : public render::Job::Config { // Not to be confused with AntialiasingConfig...
238  Q_OBJECT
239  Q_PROPERTY(bool enabled MEMBER enabled)
240 public:
241  AntiAliasingConfig() : render::Job::Config(true) {}
242 };
243 
244 class Antialiasing {
245 public:
246  using Config = AntiAliasingConfig;
247  using JobModel = render::Job::ModelI<Antialiasing, gpu::FramebufferPointer, Config>;
248 
249  Antialiasing();
250  ~Antialiasing();
251  void configure(const Config& config) {}
252  void run(const render::RenderContextPointer& renderContext, const gpu::FramebufferPointer& sourceBuffer);
253 
254  const gpu::PipelinePointer& getAntialiasingPipeline();
255  const gpu::PipelinePointer& getBlendPipeline();
256 
257 private:
258  gpu::FramebufferPointer _antialiasingBuffer;
259 
260  gpu::TexturePointer _antialiasingTexture;
261  gpu::BufferPointer _paramsBuffer;
262 
263  gpu::PipelinePointer _antialiasingPipeline;
264  gpu::PipelinePointer _blendPipeline;
265  int _geometryId { 0 };
266 };
267 #endif
268 
269 #endif // hifi_AntialiasingEffect_h