Overte C++ Documentation
SurfaceGeometryPass.h
1 //
2 // SurfaceGeometryPass.h
3 // libraries/render-utils/src/
4 //
5 // Created by Sam Gateau 6/3/2016.
6 // Copyright 2016 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_SurfaceGeometryPass_h
13 #define hifi_SurfaceGeometryPass_h
14 
15 #include <DependencyManager.h>
16 
17 #include "render/DrawTask.h"
18 #include "render/BlurTask.h"
19 #include "DeferredFrameTransform.h"
20 #include "DeferredFramebuffer.h"
21 
22 
23 // SurfaceGeometryFramebuffer is a helper class gathering in one place theframebuffers and targets describing the surface geometry linear depth
24 // from a z buffer
25 class LinearDepthFramebuffer {
26 public:
27  LinearDepthFramebuffer();
28 
29  gpu::FramebufferPointer getLinearDepthFramebuffer();
30  gpu::TexturePointer getLinearDepthTexture();
31  gpu::TexturePointer getNormalTexture();
32 
33  gpu::FramebufferPointer getDownsampleFramebuffer();
34  gpu::TexturePointer getHalfLinearDepthTexture();
35  gpu::TexturePointer getHalfNormalTexture();
36 
37  // Update the depth buffer which will drive the allocation of all the other resources according to its size.
38  void update(const gpu::TexturePointer& depthBuffer, const gpu::TexturePointer& normalTexture, bool isStereo);
39  const glm::ivec2& getDepthFrameSize() const { return _frameSize; }
40 
41  void setResolutionLevel(int level) { _resolutionLevel = std::max(0, level); }
42  int getResolutionLevel() const { return _resolutionLevel; }
43 
44 protected:
45  void clear();
46  void allocate();
47 
48  gpu::TexturePointer _primaryDepthTexture;
49 
50  gpu::FramebufferPointer _linearDepthFramebuffer;
51  gpu::TexturePointer _linearDepthTexture;
52  gpu::TexturePointer _normalTexture;
53 
54  gpu::FramebufferPointer _downsampleFramebuffer;
55  gpu::TexturePointer _halfLinearDepthTexture;
56  gpu::TexturePointer _halfNormalTexture;
57 
58 
59  glm::ivec2 _frameSize;
60  glm::ivec2 _halfFrameSize;
61  int _resolutionLevel{ 0 };
62  bool _isStereo{ false };
63 };
64 
65 using LinearDepthFramebufferPointer = std::shared_ptr<LinearDepthFramebuffer>;
66 
67 using LinearDepthPassConfig = render::GPUJobConfig;
68 
69 class LinearDepthPass {
70 public:
71  using Inputs = render::VaryingSet2<DeferredFrameTransformPointer, DeferredFramebufferPointer>;
72  using Outputs = render::VaryingSet5<LinearDepthFramebufferPointer, gpu::FramebufferPointer, gpu::TexturePointer, gpu::TexturePointer, gpu::TexturePointer>;
73  using Config = LinearDepthPassConfig;
74  using JobModel = render::Job::ModelIO<LinearDepthPass, Inputs, Outputs, Config>;
75 
76  LinearDepthPass();
77 
78  void configure(const Config& config);
79  void run(const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& outputs);
80 
81 private:
82  typedef gpu::BufferView UniformBufferView;
83 
84  LinearDepthFramebufferPointer _linearDepthFramebuffer;
85 
86  const gpu::PipelinePointer& getLinearDepthPipeline(const render::RenderContextPointer& renderContext);
87  gpu::PipelinePointer _linearDepthPipeline;
88 
89  const gpu::PipelinePointer& getDownsamplePipeline(const render::RenderContextPointer& renderContext);
90  gpu::PipelinePointer _downsamplePipeline;
91 
92  gpu::RangeTimerPointer _gpuTimer;
93 };
94 
95 
96 // SurfaceGeometryFramebuffer is a helper class gathering in one place theframebuffers and targets describing the surface geometry linear depth and curvature generated
97 // from a z buffer and a normal buffer
98 class SurfaceGeometryFramebuffer {
99 public:
100  SurfaceGeometryFramebuffer();
101 
102  gpu::FramebufferPointer getCurvatureFramebuffer();
103  gpu::TexturePointer getCurvatureTexture();
104 
105  gpu::FramebufferPointer getLowCurvatureFramebuffer();
106  gpu::TexturePointer getLowCurvatureTexture();
107 
108  gpu::FramebufferPointer getBlurringFramebuffer();
109  gpu::TexturePointer getBlurringTexture();
110 
111  // Update the source framebuffer size which will drive the allocation of all the other resources.
112  void update(const gpu::TexturePointer& linearDepthBuffer);
113  gpu::TexturePointer getLinearDepthTexture();
114  const glm::ivec2& getSourceFrameSize() const { return _frameSize; }
115 
116  void setResolutionLevel(int level);
117  int getResolutionLevel() const { return _resolutionLevel; }
118 
119 protected:
120  void clear();
121  void allocate();
122 
123  gpu::TexturePointer _linearDepthTexture;
124 
125  gpu::FramebufferPointer _curvatureFramebuffer;
126  gpu::TexturePointer _curvatureTexture;
127 
128  gpu::FramebufferPointer _blurringFramebuffer;
129  gpu::TexturePointer _blurringTexture;
130 
131  gpu::FramebufferPointer _lowCurvatureFramebuffer;
132  gpu::TexturePointer _lowCurvatureTexture;
133 
134  glm::ivec2 _frameSize;
135  int _resolutionLevel{ 0 };
136 };
137 
138 using SurfaceGeometryFramebufferPointer = std::shared_ptr<SurfaceGeometryFramebuffer>;
139 
140 class SurfaceGeometryPassConfig : public render::GPUJobConfig {
141  Q_OBJECT
142  Q_PROPERTY(float depthThreshold MEMBER depthThreshold NOTIFY dirty)
143  Q_PROPERTY(float basisScale MEMBER basisScale NOTIFY dirty)
144  Q_PROPERTY(float curvatureScale MEMBER curvatureScale NOTIFY dirty)
145  Q_PROPERTY(int resolutionLevel MEMBER resolutionLevel NOTIFY dirty)
146 
147  Q_PROPERTY(float diffuseFilterScale MEMBER diffuseFilterScale NOTIFY dirty)
148  Q_PROPERTY(float diffuseDepthThreshold MEMBER diffuseDepthThreshold NOTIFY dirty)
149 
150 public:
151  SurfaceGeometryPassConfig() : render::GPUJobConfig(true) {}
152 
153  float depthThreshold{ 5.0f }; // centimeters
154  float basisScale{ 1.0f };
155  float curvatureScale{ 10.0f };
156  int resolutionLevel{ 1 };
157  float diffuseFilterScale{ 0.2f };
158  float diffuseDepthThreshold{ 1.0f };
159 
160 signals:
161  void dirty();
162 };
163 
164 class SurfaceGeometryPass {
165 public:
166  using Inputs = render::VaryingSet3<DeferredFrameTransformPointer, DeferredFramebufferPointer, LinearDepthFramebufferPointer>;
167  using Outputs = render::VaryingSet4<SurfaceGeometryFramebufferPointer, gpu::FramebufferPointer, gpu::FramebufferPointer, gpu::FramebufferPointer>;
168  using Config = SurfaceGeometryPassConfig;
169  using JobModel = render::Job::ModelIO<SurfaceGeometryPass, Inputs, Outputs, Config>;
170 
171  SurfaceGeometryPass();
172 
173  void configure(const Config& config);
174  void run(const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& outputs);
175 
176 
177  float getCurvatureDepthThreshold() const { return _parametersBuffer.get<Parameters>().curvatureInfo.x; }
178  float getCurvatureBasisScale() const { return _parametersBuffer.get<Parameters>().curvatureInfo.y; }
179  float getCurvatureScale() const { return _parametersBuffer.get<Parameters>().curvatureInfo.w; }
180  int getResolutionLevel() const { return (int)_parametersBuffer.get<Parameters>().resolutionInfo.w; }
181 
182 private:
183  typedef gpu::BufferView UniformBufferView;
184 
185  // Class describing the uniform buffer with all the parameters common to the AO shaders
186  class Parameters {
187  public:
188  // Resolution info
189  glm::vec4 resolutionInfo { 0.0f, 0.0f, 0.0f, 1.0f }; // Default Curvature & Diffusion is running half res
190  // Curvature algorithm
191  glm::vec4 curvatureInfo{ 0.0f };
192 
193  Parameters() {}
194  };
195  gpu::BufferView _parametersBuffer;
196 
197 
198  SurfaceGeometryFramebufferPointer _surfaceGeometryFramebuffer;
199 
200  const gpu::PipelinePointer& getCurvaturePipeline(const render::RenderContextPointer& renderContext);
201 
202  gpu::PipelinePointer _curvaturePipeline;
203 
204  render::BlurGaussianDepthAware _diffusePass;
205 
206 
207  gpu::RangeTimerPointer _gpuTimer;
208 };
209 
210 #endif // hifi_SurfaceGeometryPass_h