12 #ifndef hifi_AmbientOcclusionEffect_h
13 #define hifi_AmbientOcclusionEffect_h
16 #include <DependencyManager.h>
18 #include "render/DrawTask.h"
20 #include "LightingModel.h"
21 #include "DeferredFrameTransform.h"
22 #include "DeferredFramebuffer.h"
23 #include "SurfaceGeometryPass.h"
24 #include "AmbientOcclusionStage.h"
26 #include "ssao_shared.h"
28 class AmbientOcclusionFramebuffer {
30 AmbientOcclusionFramebuffer();
32 gpu::FramebufferPointer getOcclusionFramebuffer();
33 gpu::TexturePointer getOcclusionTexture();
35 gpu::FramebufferPointer getOcclusionBlurredFramebuffer();
36 gpu::TexturePointer getOcclusionBlurredTexture();
38 gpu::FramebufferPointer getNormalFramebuffer();
39 gpu::TexturePointer getNormalTexture();
41 #if SSAO_USE_QUAD_SPLIT
42 gpu::FramebufferPointer getOcclusionSplitFramebuffer(
int index);
43 gpu::TexturePointer getOcclusionSplitTexture();
47 bool update(
const gpu::TexturePointer& linearDepthBuffer,
int resolutionLevel,
int depthResolutionLevel,
bool isStereo);
48 gpu::TexturePointer getLinearDepthTexture();
49 const glm::ivec2& getSourceFrameSize()
const {
return _frameSize; }
50 bool isStereo()
const {
return _isStereo; }
57 gpu::TexturePointer _linearDepthTexture;
59 gpu::FramebufferPointer _occlusionFramebuffer;
60 gpu::TexturePointer _occlusionTexture;
62 gpu::FramebufferPointer _occlusionBlurredFramebuffer;
63 gpu::TexturePointer _occlusionBlurredTexture;
65 gpu::FramebufferPointer _normalFramebuffer;
66 gpu::TexturePointer _normalTexture;
68 #if SSAO_USE_QUAD_SPLIT
69 gpu::FramebufferPointer _occlusionSplitFramebuffers[SSAO_SPLIT_COUNT*SSAO_SPLIT_COUNT];
70 gpu::TexturePointer _occlusionSplitTexture;
73 glm::ivec2 _frameSize;
74 int _resolutionLevel { 0 };
75 int _depthResolutionLevel { 0 };
76 bool _isStereo {
false };
79 using AmbientOcclusionFramebufferPointer = std::shared_ptr<AmbientOcclusionFramebuffer>;
81 class AmbientOcclusionEffectConfig :
public render::GPUJobConfig::Persistent {
83 Q_PROPERTY(
bool debug MEMBER debug NOTIFY dirty)
84 Q_PROPERTY(
bool horizonBased MEMBER horizonBased NOTIFY dirty)
85 Q_PROPERTY(
bool ditheringEnabled MEMBER ditheringEnabled NOTIFY dirty)
86 Q_PROPERTY(
bool borderingEnabled MEMBER borderingEnabled NOTIFY dirty)
87 Q_PROPERTY(
bool fetchMipsEnabled MEMBER fetchMipsEnabled NOTIFY dirty)
88 Q_PROPERTY(
bool jitterEnabled MEMBER jitterEnabled NOTIFY dirty)
90 Q_PROPERTY(
int resolutionLevel MEMBER resolutionLevel WRITE setResolutionLevel)
91 Q_PROPERTY(
float edgeSharpness MEMBER edgeSharpness WRITE setEdgeSharpness)
92 Q_PROPERTY(
int blurRadius MEMBER blurRadius WRITE setBlurRadius)
95 Q_PROPERTY(
float ssaoRadius MEMBER ssaoRadius WRITE setSSAORadius)
96 Q_PROPERTY(
float ssaoObscuranceLevel MEMBER ssaoObscuranceLevel WRITE setSSAOObscuranceLevel)
97 Q_PROPERTY(
float ssaoFalloffAngle MEMBER ssaoFalloffAngle WRITE setSSAOFalloffAngle)
98 Q_PROPERTY(
float ssaoNumSpiralTurns MEMBER ssaoNumSpiralTurns WRITE setSSAONumSpiralTurns)
99 Q_PROPERTY(
int ssaoNumSamples MEMBER ssaoNumSamples WRITE setSSAONumSamples)
102 Q_PROPERTY(
float hbaoRadius MEMBER hbaoRadius WRITE setHBAORadius)
103 Q_PROPERTY(
float hbaoObscuranceLevel MEMBER hbaoObscuranceLevel WRITE setHBAOObscuranceLevel)
104 Q_PROPERTY(
float hbaoFalloffAngle MEMBER hbaoFalloffAngle WRITE setHBAOFalloffAngle)
105 Q_PROPERTY(
int hbaoNumSamples MEMBER hbaoNumSamples WRITE setHBAONumSamples)
108 AmbientOcclusionEffectConfig();
110 const int MAX_RESOLUTION_LEVEL = 4;
111 const int MAX_BLUR_RADIUS = 15;
113 void setResolutionLevel(
int level);
114 void setEdgeSharpness(
float sharpness);
115 void setBlurRadius(
int radius);
117 void setSSAORadius(
float newRadius);
118 void setSSAOObscuranceLevel(
float level);
119 void setSSAOFalloffAngle(
float bias);
120 void setSSAONumSamples(
int samples);
121 void setSSAONumSpiralTurns(
float turns);
123 void setHBAORadius(
float newRadius);
124 void setHBAOObscuranceLevel(
float level);
125 void setHBAOFalloffAngle(
float bias);
126 void setHBAONumSamples(
int samples);
128 bool debug {
false };
130 bool jitterEnabled {
false };
131 bool horizonBased {
false };
132 int resolutionLevel { 2 };
133 float edgeSharpness { 1.0f };
134 int blurRadius { 4 };
136 float ssaoRadius { 1.0f };
137 float ssaoObscuranceLevel { 0.4f };
138 float ssaoFalloffAngle { 0.15f };
139 int ssaoNumSamples { 32 };
140 float ssaoNumSpiralTurns { 7.0f };
142 float hbaoRadius { 0.7f };
143 float hbaoObscuranceLevel { 0.75f };
144 float hbaoFalloffAngle { 0.3f };
145 int hbaoNumSamples { 1 };
147 float perspectiveScale { 1.0f };
148 bool ditheringEnabled {
true };
149 bool borderingEnabled {
true };
150 bool fetchMipsEnabled {
true };
156 #define SSAO_RANDOM_SAMPLE_COUNT 16
158 class AmbientOcclusionEffect {
160 using Input = render::VaryingSet5<LightingModelPointer, DeferredFrameTransformPointer, DeferredFramebufferPointer,
161 LinearDepthFramebufferPointer, AmbientOcclusionStage::FramePointer>;
162 using Output = render::VaryingSet2<AmbientOcclusionFramebufferPointer, gpu::BufferView>;
163 using Config = AmbientOcclusionEffectConfig;
164 using JobModel = render::Job::ModelIO<AmbientOcclusionEffect, Input, Output, Config>;
166 AmbientOcclusionEffect() {}
168 void configure(
const Config& config);
169 void run(
const render::RenderContextPointer& renderContext,
const Input& input, Output& output);
172 class AOParameters :
public AmbientOcclusionParams {
176 int getResolutionLevel()
const {
return _resolutionInfo.x; }
177 float getRadius()
const {
return _radiusInfo.x; }
178 float getPerspectiveScale()
const {
return _resolutionInfo.z; }
179 float getObscuranceLevel()
const {
return _radiusInfo.w; }
180 float getFalloffAngle()
const {
return (
float)_falloffInfo.x; }
182 float getNumSpiralTurns()
const {
return _sampleInfo.z; }
183 int getNumSamples()
const {
return (
int)_sampleInfo.x; }
184 bool isFetchMipsEnabled()
const {
return _sampleInfo.w; }
186 bool isDitheringEnabled()
const {
return _ditheringInfo.x != 0.0f; }
187 bool isBorderingEnabled()
const {
return _ditheringInfo.w != 0.0f; }
188 bool isHorizonBased()
const {
return _resolutionInfo.y != 0.0f; }
190 using AOParametersBuffer = gpu::StructBuffer<AOParameters>;
195 class BlurParameters :
public AmbientOcclusionBlurParams {
199 float getEdgeSharpness()
const {
return (
float)_blurInfo.x; }
200 int getBlurRadius()
const {
return (
int)_blurInfo.w; }
202 using BlurParametersBuffer = gpu::StructBuffer<BlurParameters>;
203 using FrameParametersBuffer = gpu::StructBuffer< AmbientOcclusionFrameParams>;
205 void updateParameters(
const graphics::AmbientOcclusionPointer ambientOcclusion);
206 void updateBlurParameters();
207 void updateFramebufferSizes();
208 void updateRandomSamples();
209 void updateJitterSamples();
211 int getDepthResolutionLevel()
const;
213 AOParametersBuffer _aoParametersBuffer;
214 FrameParametersBuffer _aoFrameParametersBuffer[SSAO_SPLIT_COUNT*SSAO_SPLIT_COUNT];
215 BlurParametersBuffer _vblurParametersBuffer;
216 BlurParametersBuffer _hblurParametersBuffer;
217 float _blurEdgeSharpness { 0.0f };
219 static const gpu::PipelinePointer& getOcclusionPipeline();
220 static const gpu::PipelinePointer& getBilateralBlurPipeline();
221 static const gpu::PipelinePointer& getMipCreationPipeline();
222 static const gpu::PipelinePointer& getGatherPipeline();
223 static const gpu::PipelinePointer& getBuildNormalsPipeline();
225 static gpu::PipelinePointer _occlusionPipeline;
226 static gpu::PipelinePointer _bilateralBlurPipeline;
227 static gpu::PipelinePointer _mipCreationPipeline;
228 static gpu::PipelinePointer _gatherPipeline;
229 static gpu::PipelinePointer _buildNormalsPipeline;
231 AmbientOcclusionFramebufferPointer _framebuffer;
232 std::array<float, SSAO_RANDOM_SAMPLE_COUNT * SSAO_SPLIT_COUNT*SSAO_SPLIT_COUNT> _randomSamples;
234 bool _debug {
false };
235 float _perspectiveScale { 1.0f };
236 bool _ditheringEnabled {
true };
237 bool _borderingEnabled {
true };
238 bool _fetchMipsEnabled {
true };
239 graphics::AmbientOcclusionPointer _debugAmbientOcclusion { std::make_shared<graphics::AmbientOcclusion>() };
241 gpu::RangeTimerPointer _gpuTimer;
243 friend class DebugAmbientOcclusion;
247 class DebugAmbientOcclusionConfig :
public render::Job::Config {
250 Q_PROPERTY(
bool showCursorPixel MEMBER showCursorPixel NOTIFY dirty)
251 Q_PROPERTY(glm::vec2 debugCursorTexcoord MEMBER debugCursorTexcoord NOTIFY dirty)
253 DebugAmbientOcclusionConfig() : render::Job::Config(false) {}
255 bool showCursorPixel {
false };
256 glm::vec2 debugCursorTexcoord { 0.5f, 0.5f };
263 class DebugAmbientOcclusion {
265 using Inputs = render::VaryingSet4<DeferredFrameTransformPointer, DeferredFramebufferPointer, LinearDepthFramebufferPointer, AmbientOcclusionEffect::AOParametersBuffer>;
266 using Config = DebugAmbientOcclusionConfig;
267 using JobModel = render::Job::ModelI<DebugAmbientOcclusion, Inputs, Config>;
269 DebugAmbientOcclusion() {}
271 void configure(
const Config& config);
272 void run(
const render::RenderContextPointer& renderContext,
const Inputs& inputs);
280 glm::vec4 pixelInfo { 0.0f, 0.0f, 0.0f, 0.0f };
284 gpu::StructBuffer<Parameters> _parametersBuffer;
286 static gpu::PipelinePointer& getDebugPipeline();
288 static gpu::PipelinePointer _debugPipeline;
290 bool _showCursorPixel {
false };