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"
25 #include "ssao_shared.h"
27 class AmbientOcclusionFramebuffer {
29 AmbientOcclusionFramebuffer();
31 gpu::FramebufferPointer getOcclusionFramebuffer();
32 gpu::TexturePointer getOcclusionTexture();
34 gpu::FramebufferPointer getOcclusionBlurredFramebuffer();
35 gpu::TexturePointer getOcclusionBlurredTexture();
37 gpu::FramebufferPointer getNormalFramebuffer();
38 gpu::TexturePointer getNormalTexture();
40 #if SSAO_USE_QUAD_SPLIT
41 gpu::FramebufferPointer getOcclusionSplitFramebuffer(
int index);
42 gpu::TexturePointer getOcclusionSplitTexture();
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; }
56 gpu::TexturePointer _linearDepthTexture;
58 gpu::FramebufferPointer _occlusionFramebuffer;
59 gpu::TexturePointer _occlusionTexture;
61 gpu::FramebufferPointer _occlusionBlurredFramebuffer;
62 gpu::TexturePointer _occlusionBlurredTexture;
64 gpu::FramebufferPointer _normalFramebuffer;
65 gpu::TexturePointer _normalTexture;
67 #if SSAO_USE_QUAD_SPLIT
68 gpu::FramebufferPointer _occlusionSplitFramebuffers[SSAO_SPLIT_COUNT*SSAO_SPLIT_COUNT];
69 gpu::TexturePointer _occlusionSplitTexture;
72 glm::ivec2 _frameSize;
73 int _resolutionLevel{ 0 };
74 int _depthResolutionLevel{ 0 };
75 bool _isStereo{
false };
78 using AmbientOcclusionFramebufferPointer = std::shared_ptr<AmbientOcclusionFramebuffer>;
80 class AmbientOcclusionEffectConfig :
public render::GPUJobConfig::Persistent {
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)
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)
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)
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)
106 AmbientOcclusionEffectConfig();
108 const int MAX_RESOLUTION_LEVEL = 4;
109 const int MAX_BLUR_RADIUS = 15;
111 void setEdgeSharpness(
float sharpness);
112 void setResolutionLevel(
int level);
113 void setBlurRadius(
int radius);
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);
121 void setHBAORadius(
float newRadius);
122 void setHBAOObscuranceLevel(
float level);
123 void setHBAOFalloffAngle(
float bias);
124 void setHBAONumSamples(
int samples);
126 float perspectiveScale;
132 float ssaoObscuranceLevel;
133 float ssaoFalloffAngle;
134 float ssaoNumSpiralTurns;
138 float hbaoObscuranceLevel;
139 float hbaoFalloffAngle;
143 bool ditheringEnabled;
144 bool borderingEnabled;
145 bool fetchMipsEnabled;
152 #define SSAO_RANDOM_SAMPLE_COUNT 16
154 class AmbientOcclusionEffect {
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>;
161 AmbientOcclusionEffect();
163 void configure(
const Config& config);
164 void run(
const render::RenderContextPointer& renderContext,
const Input& input, Output& output);
167 class AOParameters :
public AmbientOcclusionParams {
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; }
178 float getNumSpiralTurns()
const {
return _sampleInfo.z; }
179 int getNumSamples()
const {
return (
int)_sampleInfo.x; }
180 bool isFetchMipsEnabled()
const {
return _sampleInfo.w; }
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; }
187 using AOParametersBuffer = gpu::StructBuffer<AOParameters>;
192 class BlurParameters :
public AmbientOcclusionBlurParams {
197 float getEdgeSharpness()
const {
return (
float)_blurInfo.x; }
198 int getBlurRadius()
const {
return (
int)_blurInfo.w; }
201 using BlurParametersBuffer = gpu::StructBuffer<BlurParameters>;
203 using FrameParametersBuffer = gpu::StructBuffer< AmbientOcclusionFrameParams>;
205 void updateBlurParameters();
206 void updateFramebufferSizes();
207 void updateRandomSamples();
208 void updateJitterSamples();
210 int getDepthResolutionLevel()
const;
212 AOParametersBuffer _aoParametersBuffer;
213 FrameParametersBuffer _aoFrameParametersBuffer[SSAO_SPLIT_COUNT*SSAO_SPLIT_COUNT];
214 BlurParametersBuffer _vblurParametersBuffer;
215 BlurParametersBuffer _hblurParametersBuffer;
216 float _blurEdgeSharpness{ 0.0f };
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();
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;
230 AmbientOcclusionFramebufferPointer _framebuffer;
231 std::array<float, SSAO_RANDOM_SAMPLE_COUNT * SSAO_SPLIT_COUNT*SSAO_SPLIT_COUNT> _randomSamples;
233 bool _isJitterEnabled{
true };
235 gpu::RangeTimerPointer _gpuTimer;
237 friend class DebugAmbientOcclusion;
241 class DebugAmbientOcclusionConfig :
public render::Job::Config {
244 Q_PROPERTY(
bool showCursorPixel MEMBER showCursorPixel NOTIFY dirty)
245 Q_PROPERTY(glm::vec2 debugCursorTexcoord MEMBER debugCursorTexcoord NOTIFY dirty)
247 DebugAmbientOcclusionConfig() : render::Job::Config(false) {}
249 bool showCursorPixel{
false };
250 glm::vec2 debugCursorTexcoord{ 0.5f, 0.5f };
257 class DebugAmbientOcclusion {
259 using Inputs = render::VaryingSet4<DeferredFrameTransformPointer, DeferredFramebufferPointer, LinearDepthFramebufferPointer, AmbientOcclusionEffect::AOParametersBuffer>;
260 using Config = DebugAmbientOcclusionConfig;
261 using JobModel = render::Job::ModelI<DebugAmbientOcclusion, Inputs, Config>;
263 DebugAmbientOcclusion();
265 void configure(
const Config& config);
266 void run(
const render::RenderContextPointer& renderContext,
const Inputs& inputs);
274 glm::vec4 pixelInfo { 0.0f, 0.0f, 0.0f, 0.0f };
278 gpu::StructBuffer<Parameters> _parametersBuffer;
280 const gpu::PipelinePointer& getDebugPipeline();
282 gpu::PipelinePointer _debugPipeline;
284 bool _showCursorPixel{
false };