Overte C++ Documentation
AmbientOcclusionEffect.h
1 //
2 // AmbientOcclusionEffect.h
3 // libraries/render-utils/src/
4 //
5 // Created by Niraj Venkat on 7/15/15.
6 // Copyright 2015 High Fidelity, Inc.
7 //
8 // Distributed under the Apache License, Version 2.0.
9 // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
10 //
11 
12 #ifndef hifi_AmbientOcclusionEffect_h
13 #define hifi_AmbientOcclusionEffect_h
14 
15 #include <string>
16 #include <DependencyManager.h>
17 
18 #include "render/DrawTask.h"
19 
20 #include "LightingModel.h"
21 #include "DeferredFrameTransform.h"
22 #include "DeferredFramebuffer.h"
23 #include "SurfaceGeometryPass.h"
24 
25 #include "ssao_shared.h"
26 
27 class AmbientOcclusionFramebuffer {
28 public:
29  AmbientOcclusionFramebuffer();
30 
31  gpu::FramebufferPointer getOcclusionFramebuffer();
32  gpu::TexturePointer getOcclusionTexture();
33 
34  gpu::FramebufferPointer getOcclusionBlurredFramebuffer();
35  gpu::TexturePointer getOcclusionBlurredTexture();
36 
37  gpu::FramebufferPointer getNormalFramebuffer();
38  gpu::TexturePointer getNormalTexture();
39 
40 #if SSAO_USE_QUAD_SPLIT
41  gpu::FramebufferPointer getOcclusionSplitFramebuffer(int index);
42  gpu::TexturePointer getOcclusionSplitTexture();
43 #endif
44 
45  // Update the source framebuffer size which will drive the allocation of all the other resources.
46  bool update(const gpu::TexturePointer& linearDepthBuffer, int resolutionLevel, int depthResolutionLevel, bool isStereo);
47  gpu::TexturePointer getLinearDepthTexture();
48  const glm::ivec2& getSourceFrameSize() const { return _frameSize; }
49  bool isStereo() const { return _isStereo; }
50 
51 protected:
52 
53  void clear();
54  void allocate();
55 
56  gpu::TexturePointer _linearDepthTexture;
57 
58  gpu::FramebufferPointer _occlusionFramebuffer;
59  gpu::TexturePointer _occlusionTexture;
60 
61  gpu::FramebufferPointer _occlusionBlurredFramebuffer;
62  gpu::TexturePointer _occlusionBlurredTexture;
63 
64  gpu::FramebufferPointer _normalFramebuffer;
65  gpu::TexturePointer _normalTexture;
66 
67 #if SSAO_USE_QUAD_SPLIT
68  gpu::FramebufferPointer _occlusionSplitFramebuffers[SSAO_SPLIT_COUNT*SSAO_SPLIT_COUNT];
69  gpu::TexturePointer _occlusionSplitTexture;
70 #endif
71 
72  glm::ivec2 _frameSize;
73  int _resolutionLevel{ 0 };
74  int _depthResolutionLevel{ 0 };
75  bool _isStereo{ false };
76 };
77 
78 using AmbientOcclusionFramebufferPointer = std::shared_ptr<AmbientOcclusionFramebuffer>;
79 
80 class AmbientOcclusionEffectConfig : public render::GPUJobConfig::Persistent {
81  Q_OBJECT
82  Q_PROPERTY(bool horizonBased MEMBER horizonBased NOTIFY dirty)
83  Q_PROPERTY(bool ditheringEnabled MEMBER ditheringEnabled NOTIFY dirty)
84  Q_PROPERTY(bool borderingEnabled MEMBER borderingEnabled NOTIFY dirty)
85  Q_PROPERTY(bool fetchMipsEnabled MEMBER fetchMipsEnabled NOTIFY dirty)
86  Q_PROPERTY(bool jitterEnabled MEMBER jitterEnabled NOTIFY dirty)
87 
88  Q_PROPERTY(int resolutionLevel MEMBER resolutionLevel WRITE setResolutionLevel)
89  Q_PROPERTY(float edgeSharpness MEMBER edgeSharpness WRITE setEdgeSharpness)
90  Q_PROPERTY(int blurRadius MEMBER blurRadius WRITE setBlurRadius)
91 
92  // SSAO
93  Q_PROPERTY(float ssaoRadius MEMBER ssaoRadius WRITE setSSAORadius)
94  Q_PROPERTY(float ssaoObscuranceLevel MEMBER ssaoObscuranceLevel WRITE setSSAOObscuranceLevel)
95  Q_PROPERTY(float ssaoFalloffAngle MEMBER ssaoFalloffAngle WRITE setSSAOFalloffAngle)
96  Q_PROPERTY(float ssaoNumSpiralTurns MEMBER ssaoNumSpiralTurns WRITE setSSAONumSpiralTurns)
97  Q_PROPERTY(int ssaoNumSamples MEMBER ssaoNumSamples WRITE setSSAONumSamples)
98 
99  // HBAO
100  Q_PROPERTY(float hbaoRadius MEMBER hbaoRadius WRITE setHBAORadius)
101  Q_PROPERTY(float hbaoObscuranceLevel MEMBER hbaoObscuranceLevel WRITE setHBAOObscuranceLevel)
102  Q_PROPERTY(float hbaoFalloffAngle MEMBER hbaoFalloffAngle WRITE setHBAOFalloffAngle)
103  Q_PROPERTY(int hbaoNumSamples MEMBER hbaoNumSamples WRITE setHBAONumSamples)
104 
105 public:
106  AmbientOcclusionEffectConfig();
107 
108  const int MAX_RESOLUTION_LEVEL = 4;
109  const int MAX_BLUR_RADIUS = 15;
110 
111  void setEdgeSharpness(float sharpness);
112  void setResolutionLevel(int level);
113  void setBlurRadius(int radius);
114 
115  void setSSAORadius(float newRadius);
116  void setSSAOObscuranceLevel(float level);
117  void setSSAOFalloffAngle(float bias);
118  void setSSAONumSpiralTurns(float turns);
119  void setSSAONumSamples(int samples);
120 
121  void setHBAORadius(float newRadius);
122  void setHBAOObscuranceLevel(float level);
123  void setHBAOFalloffAngle(float bias);
124  void setHBAONumSamples(int samples);
125 
126  float perspectiveScale;
127  float edgeSharpness;
128  int blurRadius; // 0 means no blurring
129  int resolutionLevel;
130 
131  float ssaoRadius;
132  float ssaoObscuranceLevel; // intensify or dim down the obscurance effect
133  float ssaoFalloffAngle;
134  float ssaoNumSpiralTurns; // defining an angle span to distribute the samples ray directions
135  int ssaoNumSamples;
136 
137  float hbaoRadius;
138  float hbaoObscuranceLevel; // intensify or dim down the obscurance effect
139  float hbaoFalloffAngle;
140  int hbaoNumSamples;
141 
142  bool horizonBased; // Use horizon based AO
143  bool ditheringEnabled; // randomize the distribution of taps per pixel, should always be true
144  bool borderingEnabled; // avoid evaluating information from non existing pixels out of the frame, should always be true
145  bool fetchMipsEnabled; // fetch taps in sub mips to otpimize cache, should always be true
146  bool jitterEnabled; // Add small jittering to AO samples at each frame
147 
148 signals:
149  void dirty();
150 };
151 
152 #define SSAO_RANDOM_SAMPLE_COUNT 16
153 
154 class AmbientOcclusionEffect {
155 public:
156  using Input = render::VaryingSet4<LightingModelPointer, DeferredFrameTransformPointer, DeferredFramebufferPointer, LinearDepthFramebufferPointer>;
157  using Output = render::VaryingSet2<AmbientOcclusionFramebufferPointer, gpu::BufferView>;
158  using Config = AmbientOcclusionEffectConfig;
159  using JobModel = render::Job::ModelIO<AmbientOcclusionEffect, Input, Output, Config>;
160 
161  AmbientOcclusionEffect();
162 
163  void configure(const Config& config);
164  void run(const render::RenderContextPointer& renderContext, const Input& input, Output& output);
165 
166  // Class describing the uniform buffer with all the parameters common to the AO shaders
167  class AOParameters : public AmbientOcclusionParams {
168  public:
169 
170  AOParameters();
171 
172  int getResolutionLevel() const { return _resolutionInfo.x; }
173  float getRadius() const { return _radiusInfo.x; }
174  float getPerspectiveScale() const { return _resolutionInfo.z; }
175  float getObscuranceLevel() const { return _radiusInfo.w; }
176  float getFalloffAngle() const { return (float)_falloffInfo.x; }
177 
178  float getNumSpiralTurns() const { return _sampleInfo.z; }
179  int getNumSamples() const { return (int)_sampleInfo.x; }
180  bool isFetchMipsEnabled() const { return _sampleInfo.w; }
181 
182  bool isDitheringEnabled() const { return _ditheringInfo.x != 0.0f; }
183  bool isBorderingEnabled() const { return _ditheringInfo.w != 0.0f; }
184  bool isHorizonBased() const { return _resolutionInfo.y != 0.0f; }
185 
186  };
187  using AOParametersBuffer = gpu::StructBuffer<AOParameters>;
188 
189 private:
190 
191  // Class describing the uniform buffer with all the parameters common to the bilateral blur shaders
192  class BlurParameters : public AmbientOcclusionBlurParams {
193  public:
194 
195  BlurParameters();
196 
197  float getEdgeSharpness() const { return (float)_blurInfo.x; }
198  int getBlurRadius() const { return (int)_blurInfo.w; }
199 
200  };
201  using BlurParametersBuffer = gpu::StructBuffer<BlurParameters>;
202 
203  using FrameParametersBuffer = gpu::StructBuffer< AmbientOcclusionFrameParams>;
204 
205  void updateBlurParameters();
206  void updateFramebufferSizes();
207  void updateRandomSamples();
208  void updateJitterSamples();
209 
210  int getDepthResolutionLevel() const;
211 
212  AOParametersBuffer _aoParametersBuffer;
213  FrameParametersBuffer _aoFrameParametersBuffer[SSAO_SPLIT_COUNT*SSAO_SPLIT_COUNT];
214  BlurParametersBuffer _vblurParametersBuffer;
215  BlurParametersBuffer _hblurParametersBuffer;
216  float _blurEdgeSharpness{ 0.0f };
217 
218  static const gpu::PipelinePointer& getOcclusionPipeline();
219  static const gpu::PipelinePointer& getBilateralBlurPipeline();
220  static const gpu::PipelinePointer& getMipCreationPipeline();
221  static const gpu::PipelinePointer& getGatherPipeline();
222  static const gpu::PipelinePointer& getBuildNormalsPipeline();
223 
224  static gpu::PipelinePointer _occlusionPipeline;
225  static gpu::PipelinePointer _bilateralBlurPipeline;
226  static gpu::PipelinePointer _mipCreationPipeline;
227  static gpu::PipelinePointer _gatherPipeline;
228  static gpu::PipelinePointer _buildNormalsPipeline;
229 
230  AmbientOcclusionFramebufferPointer _framebuffer;
231  std::array<float, SSAO_RANDOM_SAMPLE_COUNT * SSAO_SPLIT_COUNT*SSAO_SPLIT_COUNT> _randomSamples;
232  int _frameId{ 0 };
233  bool _isJitterEnabled{ true };
234 
235  gpu::RangeTimerPointer _gpuTimer;
236 
237  friend class DebugAmbientOcclusion;
238 };
239 
240 
241 class DebugAmbientOcclusionConfig : public render::Job::Config {
242  Q_OBJECT
243 
244  Q_PROPERTY(bool showCursorPixel MEMBER showCursorPixel NOTIFY dirty)
245  Q_PROPERTY(glm::vec2 debugCursorTexcoord MEMBER debugCursorTexcoord NOTIFY dirty)
246 public:
247  DebugAmbientOcclusionConfig() : render::Job::Config(false) {}
248 
249  bool showCursorPixel{ false };
250  glm::vec2 debugCursorTexcoord{ 0.5f, 0.5f };
251 
252 signals:
253  void dirty();
254 };
255 
256 
257 class DebugAmbientOcclusion {
258 public:
259  using Inputs = render::VaryingSet4<DeferredFrameTransformPointer, DeferredFramebufferPointer, LinearDepthFramebufferPointer, AmbientOcclusionEffect::AOParametersBuffer>;
260  using Config = DebugAmbientOcclusionConfig;
261  using JobModel = render::Job::ModelI<DebugAmbientOcclusion, Inputs, Config>;
262 
263  DebugAmbientOcclusion();
264 
265  void configure(const Config& config);
266  void run(const render::RenderContextPointer& renderContext, const Inputs& inputs);
267 
268 private:
269 
270  // Class describing the uniform buffer with all the parameters common to the debug AO shaders
271  class Parameters {
272  public:
273  // Pixel info
274  glm::vec4 pixelInfo { 0.0f, 0.0f, 0.0f, 0.0f };
275 
276  Parameters() {}
277  };
278  gpu::StructBuffer<Parameters> _parametersBuffer;
279 
280  const gpu::PipelinePointer& getDebugPipeline();
281 
282  gpu::PipelinePointer _debugPipeline;
283 
284  bool _showCursorPixel{ false };
285 };
286 
287 #endif // hifi_AmbientOcclusionEffect_h