From afb1ebf42e6094ecd79862edee4b457bdf51b1ad Mon Sep 17 00:00:00 2001 From: samcake Date: Tue, 26 Jul 2016 23:19:41 -0700 Subject: [PATCH] Revolutionizing ao --- .../src/AmbientOcclusionEffect.cpp | 207 ++++++++++++------ .../render-utils/src/AmbientOcclusionEffect.h | 51 ++++- .../render-utils/src/DebugDeferredBuffer.cpp | 17 +- .../render-utils/src/DebugDeferredBuffer.h | 3 +- .../src/DeferredLightingEffect.cpp | 11 +- .../render-utils/src/DeferredLightingEffect.h | 5 +- .../render-utils/src/FramebufferCache.cpp | 70 ------ libraries/render-utils/src/FramebufferCache.h | 17 -- .../render-utils/src/RenderDeferredTask.cpp | 7 +- .../render-utils/src/SurfaceGeometryPass.cpp | 2 +- libraries/render-utils/src/ssao.slh | 3 + .../render-utils/src/ssao_makeOcclusion.slf | 18 +- 12 files changed, 221 insertions(+), 190 deletions(-) diff --git a/libraries/render-utils/src/AmbientOcclusionEffect.cpp b/libraries/render-utils/src/AmbientOcclusionEffect.cpp index 4b283731d2..929f4896b3 100644 --- a/libraries/render-utils/src/AmbientOcclusionEffect.cpp +++ b/libraries/render-utils/src/AmbientOcclusionEffect.cpp @@ -33,6 +33,91 @@ #include "ssao_makeHorizontalBlur_frag.h" #include "ssao_makeVerticalBlur_frag.h" + +AmbientOcclusionFramebuffer::AmbientOcclusionFramebuffer() { +} + +void AmbientOcclusionFramebuffer::updateLinearDepth(const gpu::TexturePointer& linearDepthBuffer) { + //If the depth buffer or size changed, we need to delete our FBOs + bool reset = false; + if ((_linearDepthTexture != linearDepthBuffer)) { + _linearDepthTexture = linearDepthBuffer; + reset = true; + } + if (_linearDepthTexture) { + auto newFrameSize = glm::ivec2(_linearDepthTexture->getDimensions()); + if (_frameSize != newFrameSize) { + _frameSize = newFrameSize; + reset = true; + } + } + + if (reset) { + clear(); + } +} + +void AmbientOcclusionFramebuffer::clear() { + _occlusionFramebuffer.reset(); + _occlusionTexture.reset(); + _occlusionBlurredFramebuffer.reset(); + _occlusionBlurredTexture.reset(); +} + +gpu::TexturePointer AmbientOcclusionFramebuffer::getLinearDepthTexture() { + return _linearDepthTexture; +} + +void AmbientOcclusionFramebuffer::allocate() { + + auto width = _frameSize.x; + auto height = _frameSize.y; + + _occlusionTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_RGBA_32, width, height, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); + _occlusionFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create()); + _occlusionFramebuffer->setRenderBuffer(0, _occlusionTexture); + + _occlusionBlurredTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_RGBA_32, width, height, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); + _occlusionBlurredFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create()); + _occlusionBlurredFramebuffer->setRenderBuffer(0, _occlusionBlurredTexture); +} + +gpu::FramebufferPointer AmbientOcclusionFramebuffer::getOcclusionFramebuffer() { + if (!_occlusionFramebuffer) { + allocate(); + } + return _occlusionFramebuffer; +} + +gpu::TexturePointer AmbientOcclusionFramebuffer::getOcclusionTexture() { + if (!_occlusionTexture) { + allocate(); + } + return _occlusionTexture; +} + +gpu::FramebufferPointer AmbientOcclusionFramebuffer::getOcclusionBlurredFramebuffer() { + if (!_occlusionBlurredFramebuffer) { + allocate(); + } + return _occlusionBlurredFramebuffer; +} + +gpu::TexturePointer AmbientOcclusionFramebuffer::getOcclusionBlurredTexture() { + if (!_occlusionBlurredTexture) { + allocate(); + } + return _occlusionBlurredTexture; +} + +void AmbientOcclusionFramebuffer::setResolutionLevel(int resolutionLevel) { + if (resolutionLevel != getResolutionLevel()) { + clear(); + _resolutionLevel = resolutionLevel; + } +} + + class GaussianDistribution { public: @@ -90,8 +175,7 @@ public: const int AmbientOcclusionEffect_FrameTransformSlot = 0; const int AmbientOcclusionEffect_ParamsSlot = 1; -const int AmbientOcclusionEffect_DepthMapSlot = 0; -const int AmbientOcclusionEffect_PyramidMapSlot = 0; +const int AmbientOcclusionEffect_LinearDepthMapSlot = 0; const int AmbientOcclusionEffect_OcclusionMapSlot = 0; AmbientOcclusionEffect::AmbientOcclusionEffect() { @@ -147,13 +231,22 @@ void AmbientOcclusionEffect::configure(const Config& config) { current.y = 1.0f / config.numSamples; } + if (!_framebuffer) { + _framebuffer = std::make_shared(); + } + + _framebuffer->setResolutionLevel(config.resolutionLevel); + if (config.resolutionLevel != getResolutionLevel()) { + _parametersBuffer.edit().resolutionInfo.w = config.resolutionLevel; + } + const auto& resolutionLevel = config.resolutionLevel; if (resolutionLevel != getResolutionLevel()) { auto& current = _parametersBuffer.edit().resolutionInfo; current.x = (float)resolutionLevel; // Communicate the change to the Framebuffer cache - DependencyManager::get()->setAmbientOcclusionResolutionLevel(resolutionLevel); + // DependencyManager::get()->setAmbientOcclusionResolutionLevel(resolutionLevel); } if (config.blurRadius != getBlurRadius()) { @@ -177,32 +270,6 @@ void AmbientOcclusionEffect::configure(const Config& config) { } } -const gpu::PipelinePointer& AmbientOcclusionEffect::getPyramidPipeline() { - if (!_pyramidPipeline) { - auto vs = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS(); - auto ps = gpu::Shader::createPixel(std::string(ssao_makePyramid_frag)); - gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps); - - gpu::Shader::BindingSet slotBindings; - slotBindings.insert(gpu::Shader::Binding(std::string("ambientOcclusionFrameTransformBuffer"), AmbientOcclusionEffect_FrameTransformSlot)); - slotBindings.insert(gpu::Shader::Binding(std::string("ambientOcclusionParamsBuffer"), AmbientOcclusionEffect_ParamsSlot)); - slotBindings.insert(gpu::Shader::Binding(std::string("depthMap"), AmbientOcclusionEffect_DepthMapSlot)); - gpu::Shader::makeProgram(*program, slotBindings); - - - gpu::StatePointer state = gpu::StatePointer(new gpu::State()); - - // Stencil test the pyramid passe for objects pixels only, not the background - state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); - - state->setColorWriteMask(true, false, false, false); - - // Good to go add the brand new pipeline - _pyramidPipeline = gpu::Pipeline::create(program, state); - } - return _pyramidPipeline; -} - const gpu::PipelinePointer& AmbientOcclusionEffect::getOcclusionPipeline() { if (!_occlusionPipeline) { auto vs = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS(); @@ -212,7 +279,7 @@ const gpu::PipelinePointer& AmbientOcclusionEffect::getOcclusionPipeline() { gpu::Shader::BindingSet slotBindings; slotBindings.insert(gpu::Shader::Binding(std::string("ambientOcclusionFrameTransformBuffer"), AmbientOcclusionEffect_FrameTransformSlot)); slotBindings.insert(gpu::Shader::Binding(std::string("ambientOcclusionParamsBuffer"), AmbientOcclusionEffect_ParamsSlot)); - slotBindings.insert(gpu::Shader::Binding(std::string("pyramidMap"), AmbientOcclusionEffect_PyramidMapSlot)); + slotBindings.insert(gpu::Shader::Binding(std::string("pyramidMap"), AmbientOcclusionEffect_LinearDepthMapSlot)); gpu::Shader::makeProgram(*program, slotBindings); gpu::StatePointer state = gpu::StatePointer(new gpu::State()); @@ -282,8 +349,7 @@ void AmbientOcclusionEffect::updateGaussianDistribution() { GaussianDistribution::evalSampling(coefs, Parameters::GAUSSIAN_COEFS_LENGTH, getBlurRadius(), getBlurDeviation()); } -void AmbientOcclusionEffect::run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext) { -#ifdef FIX_THE_FRAMEBUFFER_CACHE +void AmbientOcclusionEffect::run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& outputs) { assert(renderContext->args); assert(renderContext->args->hasViewFrustum()); @@ -294,18 +360,39 @@ void AmbientOcclusionEffect::run(const render::SceneContextPointer& sceneContext return; } - auto framebufferCache = DependencyManager::get(); - auto depthBuffer = framebufferCache->getPrimaryDepthTexture(); - auto normalBuffer = framebufferCache->getDeferredNormalTexture(); - auto pyramidFBO = framebufferCache->getDepthPyramidFramebuffer(); - auto occlusionFBO = framebufferCache->getOcclusionFramebuffer(); - auto occlusionBlurredFBO = framebufferCache->getOcclusionBlurredFramebuffer(); + const auto frameTransform = inputs.get0(); + const auto deferredFramebuffer = inputs.get1(); + const auto linearDepthFramebuffer = inputs.get2(); + + auto linearDepthTexture = linearDepthFramebuffer->getLinearDepthTexture(); + auto normalTexture = deferredFramebuffer->getDeferredNormalTexture(); + auto sourceViewport = args->_viewport; + auto occlusionViewport = sourceViewport; - QSize framebufferSize = framebufferCache->getFrameBufferSize(); - float sMin = args->_viewport.x / (float)framebufferSize.width(); - float sWidth = args->_viewport.z / (float)framebufferSize.width(); - float tMin = args->_viewport.y / (float)framebufferSize.height(); - float tHeight = args->_viewport.w / (float)framebufferSize.height(); + if (!_framebuffer) { + _framebuffer = std::make_shared(); + } + + if (_framebuffer->getResolutionLevel() > 0) { + linearDepthTexture = linearDepthFramebuffer->getHalfLinearDepthTexture(); + normalTexture = linearDepthFramebuffer->getHalfNormalTexture(); + occlusionViewport = occlusionViewport >> _framebuffer->getResolutionLevel(); + } + + _framebuffer->updateLinearDepth(linearDepthTexture); + + + auto occlusionFBO = _framebuffer->getOcclusionFramebuffer(); + auto occlusionBlurredFBO = _framebuffer->getOcclusionBlurredFramebuffer(); + + outputs = _framebuffer; + + auto framebufferSize = _framebuffer->getSourceFrameSize(); + + float sMin = args->_viewport.x / (float)framebufferSize.x; + float sWidth = args->_viewport.z / (float)framebufferSize.x; + float tMin = args->_viewport.y / (float)framebufferSize.y; + float tHeight = args->_viewport.w / (float)framebufferSize.y; auto resolutionLevel = getResolutionLevel(); @@ -341,7 +428,6 @@ void AmbientOcclusionEffect::run(const render::SceneContextPointer& sceneContext } - auto pyramidPipeline = getPyramidPipeline(); auto occlusionPipeline = getOcclusionPipeline(); auto firstHBlurPipeline = getHBlurPipeline(); auto lastVBlurPipeline = getVBlurPipeline(); @@ -351,7 +437,7 @@ void AmbientOcclusionEffect::run(const render::SceneContextPointer& sceneContext _gpuTimer.begin(batch); - batch.setViewportTransform(args->_viewport); + batch.setViewportTransform(occlusionViewport); batch.setProjectionTransform(glm::mat4()); batch.setViewTransform(Transform()); @@ -363,32 +449,18 @@ void AmbientOcclusionEffect::run(const render::SceneContextPointer& sceneContext batch.setUniformBuffer(AmbientOcclusionEffect_FrameTransformSlot, _frameTransformBuffer); batch.setUniformBuffer(AmbientOcclusionEffect_ParamsSlot, _parametersBuffer); - - // Pyramid pass - batch.setFramebuffer(pyramidFBO); - batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(args->getViewFrustum().getFarClip(), 0.0f, 0.0f, 0.0f)); - batch.setPipeline(pyramidPipeline); - batch.setResourceTexture(AmbientOcclusionEffect_DepthMapSlot, depthBuffer); - batch.draw(gpu::TRIANGLE_STRIP, 4); - - // Make pyramid mips - batch.generateTextureMips(pyramidFBO->getRenderBuffer(0)); - - // Adjust Viewport for rendering resolution - if (resolutionLevel > 0) { - glm::ivec4 viewport(args->_viewport.x, args->_viewport.y, args->_viewport.z >> resolutionLevel, args->_viewport.w >> resolutionLevel); - batch.setViewportTransform(viewport); - } - + + // batch.generateTextureMips(linearDepthTexture); + // Occlusion pass batch.setFramebuffer(occlusionFBO); batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(1.0f)); batch.setPipeline(occlusionPipeline); - batch.setResourceTexture(AmbientOcclusionEffect_PyramidMapSlot, pyramidFBO->getRenderBuffer(0)); + batch.setResourceTexture(AmbientOcclusionEffect_LinearDepthMapSlot, linearDepthTexture); batch.draw(gpu::TRIANGLE_STRIP, 4); - if (getBlurRadius() > 0) { + /* if (getBlurRadius() > 0) { // Blur 1st pass batch.setFramebuffer(occlusionBlurredFBO); batch.setPipeline(firstHBlurPipeline); @@ -400,12 +472,15 @@ void AmbientOcclusionEffect::run(const render::SceneContextPointer& sceneContext batch.setPipeline(lastVBlurPipeline); batch.setResourceTexture(AmbientOcclusionEffect_OcclusionMapSlot, occlusionBlurredFBO->getRenderBuffer(0)); batch.draw(gpu::TRIANGLE_STRIP, 4); - } + }*/ + + + batch.setResourceTexture(AmbientOcclusionEffect_LinearDepthMapSlot, nullptr); + batch.setResourceTexture(AmbientOcclusionEffect_OcclusionMapSlot, nullptr); _gpuTimer.end(batch); }); // Update the timer std::static_pointer_cast(renderContext->jobConfig)->gpuTime = _gpuTimer.getAverage(); -#endif } diff --git a/libraries/render-utils/src/AmbientOcclusionEffect.h b/libraries/render-utils/src/AmbientOcclusionEffect.h index 717c9dc4fc..8c458a5879 100644 --- a/libraries/render-utils/src/AmbientOcclusionEffect.h +++ b/libraries/render-utils/src/AmbientOcclusionEffect.h @@ -16,6 +16,47 @@ #include "render/DrawTask.h" +#include "DeferredFrameTransform.h" +#include "DeferredFramebuffer.h" +#include "SurfaceGeometryPass.h" + +class AmbientOcclusionFramebuffer { +public: + AmbientOcclusionFramebuffer(); + + gpu::FramebufferPointer getOcclusionFramebuffer(); + gpu::TexturePointer getOcclusionTexture(); + + gpu::FramebufferPointer getOcclusionBlurredFramebuffer(); + gpu::TexturePointer getOcclusionBlurredTexture(); + + // Update the source framebuffer size which will drive the allocation of all the other resources. + void updateLinearDepth(const gpu::TexturePointer& linearDepthBuffer); + gpu::TexturePointer getLinearDepthTexture(); + const glm::ivec2& getSourceFrameSize() const { return _frameSize; } + + void setResolutionLevel(int level); + int getResolutionLevel() const { return _resolutionLevel; } + +protected: + void clear(); + void allocate(); + + gpu::TexturePointer _linearDepthTexture; + + gpu::FramebufferPointer _occlusionFramebuffer; + gpu::TexturePointer _occlusionTexture; + + gpu::FramebufferPointer _occlusionBlurredFramebuffer; + gpu::TexturePointer _occlusionBlurredTexture; + + + glm::ivec2 _frameSize; + int _resolutionLevel{ 0 }; +}; + +using AmbientOcclusionFramebufferPointer = std::shared_ptr; + class AmbientOcclusionEffectConfig : public render::Job::Config::Persistent { Q_OBJECT Q_PROPERTY(bool enabled MEMBER enabled NOTIFY dirty) @@ -67,13 +108,15 @@ signals: class AmbientOcclusionEffect { public: + using Inputs = render::VaryingSet3; + using Outputs = AmbientOcclusionFramebufferPointer; using Config = AmbientOcclusionEffectConfig; - using JobModel = render::Job::Model; + using JobModel = render::Job::ModelIO; AmbientOcclusionEffect(); void configure(const Config& config); - void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); + void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& outputs); float getRadius() const { return _parametersBuffer.get().radiusInfo.x; } float getObscuranceLevel() const { return _parametersBuffer.get().radiusInfo.w; } @@ -131,16 +174,16 @@ private: }; gpu::BufferView _parametersBuffer; - const gpu::PipelinePointer& getPyramidPipeline(); const gpu::PipelinePointer& getOcclusionPipeline(); const gpu::PipelinePointer& getHBlurPipeline(); // first const gpu::PipelinePointer& getVBlurPipeline(); // second - gpu::PipelinePointer _pyramidPipeline; gpu::PipelinePointer _occlusionPipeline; gpu::PipelinePointer _hBlurPipeline; gpu::PipelinePointer _vBlurPipeline; + AmbientOcclusionFramebufferPointer _framebuffer; + gpu::RangeTimer _gpuTimer; }; diff --git a/libraries/render-utils/src/DebugDeferredBuffer.cpp b/libraries/render-utils/src/DebugDeferredBuffer.cpp index 8118df5435..ed4eba972f 100644 --- a/libraries/render-utils/src/DebugDeferredBuffer.cpp +++ b/libraries/render-utils/src/DebugDeferredBuffer.cpp @@ -202,14 +202,14 @@ static const std::string DEFAULT_DEBUG_SCATTERING_SHADER{ static const std::string DEFAULT_AMBIENT_OCCLUSION_SHADER{ "vec4 getFragmentColor() {" - " return vec4(vec3(texture(obscuranceMap, uv).x), 1.0);" + " return vec4(vec3(texture(obscuranceMap, uv).xyz), 1.0);" // When drawing color " return vec4(vec3(texture(occlusionMap, uv).xyz), 1.0);" - // when drawing normal " return vec4(normalize(texture(occlusionMap, uv).xyz * 2.0 - vec3(1.0)), 1.0);" + // when drawing normal" return vec4(normalize(texture(occlusionMap, uv).xyz * 2.0 - vec3(1.0)), 1.0);" " }" }; static const std::string DEFAULT_AMBIENT_OCCLUSION_BLURRED_SHADER{ "vec4 getFragmentColor() {" - " return vec4(vec3(texture(occlusionBlurredMap, uv).x), 1.0);" + " return vec4(vec3(texture(occlusionBlurredMap, uv).xyz), 1.0);" " }" }; @@ -379,6 +379,7 @@ void DebugDeferredBuffer::run(const SceneContextPointer& sceneContext, const Ren auto& deferredFramebuffer = inputs.get0(); auto& linearDepthTarget = inputs.get1(); auto& surfaceGeometryFramebuffer = inputs.get2(); + auto& ambientOcclusionFramebuffer = inputs.get3(); gpu::doInBatch(args->_context, [&](gpu::Batch& batch) { batch.enableStereo(false); @@ -414,13 +415,9 @@ void DebugDeferredBuffer::run(const SceneContextPointer& sceneContext, const Ren batch.setResourceTexture(Curvature, surfaceGeometryFramebuffer->getCurvatureTexture()); batch.setResourceTexture(DiffusedCurvature, surfaceGeometryFramebuffer->getLowCurvatureTexture()); - if (DependencyManager::get()->isAmbientOcclusionEnabled()) { - batch.setResourceTexture(AmbientOcclusion, framebufferCache->getOcclusionTexture()); - } else { - // need to assign the white texture if ao is off - batch.setResourceTexture(AmbientOcclusion, textureCache->getWhiteTexture()); - } - batch.setResourceTexture(AmbientOcclusionBlurred, framebufferCache->getOcclusionBlurredTexture()); + + batch.setResourceTexture(AmbientOcclusion, ambientOcclusionFramebuffer->getOcclusionTexture()); + batch.setResourceTexture(AmbientOcclusionBlurred, ambientOcclusionFramebuffer->getOcclusionBlurredTexture()); const glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f); const glm::vec2 bottomLeft(_size.x, _size.y); diff --git a/libraries/render-utils/src/DebugDeferredBuffer.h b/libraries/render-utils/src/DebugDeferredBuffer.h index d6005de349..da78ac081a 100644 --- a/libraries/render-utils/src/DebugDeferredBuffer.h +++ b/libraries/render-utils/src/DebugDeferredBuffer.h @@ -17,6 +17,7 @@ #include #include "DeferredFramebuffer.h" #include "SurfaceGeometryPass.h" +#include "AmbientOcclusionEffect.h" class DebugDeferredBufferConfig : public render::Job::Config { Q_OBJECT @@ -36,7 +37,7 @@ signals: class DebugDeferredBuffer { public: - using Inputs = render::VaryingSet4; + using Inputs = render::VaryingSet4; using Config = DebugDeferredBufferConfig; using JobModel = render::Job::ModelI; diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 6f202f6200..9038b8bada 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -400,7 +400,7 @@ void RenderDeferredSetup::run(const render::SceneContextPointer& sceneContext, c const DeferredFramebufferPointer& deferredFramebuffer, const LightingModelPointer& lightingModel, const SurfaceGeometryFramebufferPointer& surfaceGeometryFramebuffer, - const gpu::FramebufferPointer& lowCurvatureNormalFramebuffer, + const AmbientOcclusionFramebufferPointer& ambientOcclusionFramebuffer, const SubsurfaceScatteringResourcePointer& subsurfaceScatteringResource) { auto args = renderContext->args; @@ -431,7 +431,7 @@ void RenderDeferredSetup::run(const render::SceneContextPointer& sceneContext, c // FIXME: Different render modes should have different tasks if (args->_renderMode == RenderArgs::DEFAULT_RENDER_MODE && deferredLightingEffect->isAmbientOcclusionEnabled()) { - batch.setResourceTexture(DEFERRED_BUFFER_OBSCURANCE_UNIT, framebufferCache->getOcclusionTexture()); + batch.setResourceTexture(DEFERRED_BUFFER_OBSCURANCE_UNIT, ambientOcclusionFramebuffer->getOcclusionTexture()); } else { // need to assign the white texture if ao is off batch.setResourceTexture(DEFERRED_BUFFER_OBSCURANCE_UNIT, textureCache->getWhiteTexture()); @@ -446,9 +446,6 @@ void RenderDeferredSetup::run(const render::SceneContextPointer& sceneContext, c // Subsurface scattering specific if (surfaceGeometryFramebuffer) { batch.setResourceTexture(DEFERRED_BUFFER_CURVATURE_UNIT, surfaceGeometryFramebuffer->getCurvatureTexture()); - } - if (lowCurvatureNormalFramebuffer) { - // batch.setResourceTexture(DEFERRED_BUFFER_DIFFUSED_CURVATURE_UNIT, lowCurvatureNormalFramebuffer->getRenderBuffer(0)); batch.setResourceTexture(DEFERRED_BUFFER_DIFFUSED_CURVATURE_UNIT, surfaceGeometryFramebuffer->getLowCurvatureTexture()); } if (subsurfaceScatteringResource) { @@ -693,7 +690,7 @@ void RenderDeferred::run(const SceneContextPointer& sceneContext, const RenderCo auto deferredFramebuffer = inputs.get1(); auto lightingModel = inputs.get2(); auto surfaceGeometryFramebuffer = inputs.get3(); - auto lowCurvatureNormalFramebuffer = inputs.get4(); + auto ssaoFramebuffer = inputs.get4(); auto subsurfaceScatteringResource = inputs.get5(); auto args = renderContext->args; @@ -701,7 +698,7 @@ void RenderDeferred::run(const SceneContextPointer& sceneContext, const RenderCo _gpuTimer.begin(batch); }); - setupJob.run(sceneContext, renderContext, deferredTransform, deferredFramebuffer, lightingModel, surfaceGeometryFramebuffer, lowCurvatureNormalFramebuffer, subsurfaceScatteringResource); + setupJob.run(sceneContext, renderContext, deferredTransform, deferredFramebuffer, lightingModel, surfaceGeometryFramebuffer, ssaoFramebuffer, subsurfaceScatteringResource); lightsJob.run(sceneContext, renderContext, deferredTransform, deferredFramebuffer, lightingModel); diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index b309299be9..466c58c36e 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -30,6 +30,7 @@ #include "LightStage.h" #include "SurfaceGeometryPass.h" #include "SubsurfaceScattering.h" +#include "AmbientOcclusionEffect.h" class RenderArgs; struct LightLocations; @@ -138,7 +139,7 @@ public: const DeferredFramebufferPointer& deferredFramebuffer, const LightingModelPointer& lightingModel, const SurfaceGeometryFramebufferPointer& surfaceGeometryFramebuffer, - const gpu::FramebufferPointer& lowCurvatureNormalFramebuffer, + const AmbientOcclusionFramebufferPointer& ambientOcclusionFramebuffer, const SubsurfaceScatteringResourcePointer& subsurfaceScatteringResource); }; @@ -178,7 +179,7 @@ signals: class RenderDeferred { public: - using Inputs = render::VaryingSet6 < DeferredFrameTransformPointer, DeferredFramebufferPointer, LightingModelPointer, SurfaceGeometryFramebufferPointer, gpu::FramebufferPointer, SubsurfaceScatteringResourcePointer>; + using Inputs = render::VaryingSet6 < DeferredFrameTransformPointer, DeferredFramebufferPointer, LightingModelPointer, SurfaceGeometryFramebufferPointer, AmbientOcclusionFramebufferPointer, SubsurfaceScatteringResourcePointer>; using Config = RenderDeferredConfig; using JobModel = render::Job::ModelI; diff --git a/libraries/render-utils/src/FramebufferCache.cpp b/libraries/render-utils/src/FramebufferCache.cpp index 5375de273a..ff0fb8db50 100644 --- a/libraries/render-utils/src/FramebufferCache.cpp +++ b/libraries/render-utils/src/FramebufferCache.cpp @@ -35,10 +35,6 @@ void FramebufferCache::setFrameBufferSize(QSize frameBufferSize) { _frameBufferSize = frameBufferSize; _selfieFramebuffer.reset(); _cachedFramebuffers.clear(); - _occlusionFramebuffer.reset(); - _occlusionTexture.reset(); - _occlusionBlurredFramebuffer.reset(); - _occlusionBlurredTexture.reset(); } } @@ -54,35 +50,6 @@ void FramebufferCache::createPrimaryFramebuffer() { _selfieFramebuffer->setRenderBuffer(0, tex); auto smoothSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR); - - - - resizeAmbientOcclusionBuffers(); -} - - -void FramebufferCache::resizeAmbientOcclusionBuffers() { - _occlusionFramebuffer.reset(); - _occlusionTexture.reset(); - _occlusionBlurredFramebuffer.reset(); - _occlusionBlurredTexture.reset(); - - - auto width = _frameBufferSize.width() >> _AOResolutionLevel; - auto height = _frameBufferSize.height() >> _AOResolutionLevel; - auto colorFormat = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGB); - auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR); - // auto depthFormat = gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::DEPTH_STENCIL); // Depth24_Stencil8 texel format - - _occlusionTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height, defaultSampler)); - _occlusionFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create()); - _occlusionFramebuffer->setRenderBuffer(0, _occlusionTexture); - // _occlusionFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat); - - _occlusionBlurredTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height, defaultSampler)); - _occlusionBlurredFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create()); - _occlusionBlurredFramebuffer->setRenderBuffer(0, _occlusionBlurredTexture); - // _occlusionBlurredFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat); } @@ -107,40 +74,3 @@ gpu::FramebufferPointer FramebufferCache::getSelfieFramebuffer() { } return _selfieFramebuffer; } - -void FramebufferCache::setAmbientOcclusionResolutionLevel(int level) { - const int MAX_AO_RESOLUTION_LEVEL = 4; - level = std::max(0, std::min(level, MAX_AO_RESOLUTION_LEVEL)); - if (level != _AOResolutionLevel) { - _AOResolutionLevel = level; - resizeAmbientOcclusionBuffers(); - } -} - -gpu::FramebufferPointer FramebufferCache::getOcclusionFramebuffer() { - if (!_occlusionFramebuffer) { - resizeAmbientOcclusionBuffers(); - } - return _occlusionFramebuffer; -} - -gpu::TexturePointer FramebufferCache::getOcclusionTexture() { - if (!_occlusionTexture) { - resizeAmbientOcclusionBuffers(); - } - return _occlusionTexture; -} - -gpu::FramebufferPointer FramebufferCache::getOcclusionBlurredFramebuffer() { - if (!_occlusionBlurredFramebuffer) { - resizeAmbientOcclusionBuffers(); - } - return _occlusionBlurredFramebuffer; -} - -gpu::TexturePointer FramebufferCache::getOcclusionBlurredTexture() { - if (!_occlusionBlurredTexture) { - resizeAmbientOcclusionBuffers(); - } - return _occlusionBlurredTexture; -} \ No newline at end of file diff --git a/libraries/render-utils/src/FramebufferCache.h b/libraries/render-utils/src/FramebufferCache.h index d3d26c35b0..2f521d7677 100644 --- a/libraries/render-utils/src/FramebufferCache.h +++ b/libraries/render-utils/src/FramebufferCache.h @@ -30,12 +30,6 @@ public: void setFrameBufferSize(QSize frameBufferSize); const QSize& getFrameBufferSize() const { return _frameBufferSize; } - void setAmbientOcclusionResolutionLevel(int level); - gpu::FramebufferPointer getOcclusionFramebuffer(); - gpu::TexturePointer getOcclusionTexture(); - gpu::FramebufferPointer getOcclusionBlurredFramebuffer(); - gpu::TexturePointer getOcclusionBlurredTexture(); - /// Returns the framebuffer object used to render selfie maps; gpu::FramebufferPointer getSelfieFramebuffer(); @@ -56,18 +50,7 @@ private: gpu::FramebufferPointer _selfieFramebuffer; - gpu::FramebufferPointer _occlusionFramebuffer; - gpu::TexturePointer _occlusionTexture; - - gpu::FramebufferPointer _occlusionBlurredFramebuffer; - gpu::TexturePointer _occlusionBlurredTexture; - QSize _frameBufferSize{ 100, 100 }; - int _AOResolutionLevel = 1; // AO perform at half res - - // Resize/reallocate the buffers used for AO - // the size of the AO buffers is scaled by the AOResolutionScale; - void resizeAmbientOcclusionBuffers(); }; #endif // hifi_FramebufferCache_h diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index bb7adf3f80..afff4bac72 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -141,13 +141,14 @@ RenderDeferredTask::RenderDeferredTask(CullFunctor cullFunctor) { const auto scatteringResource = addJob("Scattering"); // AO job - addJob("AmbientOcclusion"); + const auto ambientOcclusionInputs = AmbientOcclusionEffect::Inputs(deferredFrameTransform, deferredFramebuffer, linearDepthTarget).hasVarying(); + const auto ambientOcclusionFramebuffer = addJob("AmbientOcclusion", ambientOcclusionInputs); // Draw Lights just add the lights to the current list of lights to deal with. NOt really gpu job for now. addJob("DrawLight", lights); const auto deferredLightingInputs = RenderDeferred::Inputs(deferredFrameTransform, deferredFramebuffer, lightingModel, - surfaceGeometryFramebuffer, lowCurvatureNormalFramebuffer, scatteringResource).hasVarying(); + surfaceGeometryFramebuffer, ambientOcclusionFramebuffer, scatteringResource).hasVarying(); // DeferredBuffer is complete, now let's shade it into the LightingBuffer addJob("RenderDeferred", deferredLightingInputs); @@ -178,7 +179,7 @@ RenderDeferredTask::RenderDeferredTask(CullFunctor cullFunctor) { addJob("DebugScattering", deferredLightingInputs); // Debugging Deferred buffer job - const auto debugFramebuffers = render::Varying(DebugDeferredBuffer::Inputs(deferredFramebuffer, linearDepthTarget, surfaceGeometryFramebuffer, lowCurvatureNormalFramebuffer)); + const auto debugFramebuffers = render::Varying(DebugDeferredBuffer::Inputs(deferredFramebuffer, linearDepthTarget, surfaceGeometryFramebuffer, ambientOcclusionFramebuffer)); addJob("DebugDeferredBuffer", debugFramebuffers); // Scene Octree Debuging job diff --git a/libraries/render-utils/src/SurfaceGeometryPass.cpp b/libraries/render-utils/src/SurfaceGeometryPass.cpp index fd778d30be..6dc1cb2f9b 100644 --- a/libraries/render-utils/src/SurfaceGeometryPass.cpp +++ b/libraries/render-utils/src/SurfaceGeometryPass.cpp @@ -193,7 +193,7 @@ void LinearDepthPass::run(const render::SceneContextPointer& sceneContext, const batch.setResourceTexture(DepthLinearPass_NormalMapSlot, normalTexture); batch.setPipeline(downsamplePipeline); batch.draw(gpu::TRIANGLE_STRIP, 4); - + _gpuTimer.end(batch); }); diff --git a/libraries/render-utils/src/ssao.slh b/libraries/render-utils/src/ssao.slh index 5fcd224e9d..21e9a5a297 100644 --- a/libraries/render-utils/src/ssao.slh +++ b/libraries/render-utils/src/ssao.slh @@ -76,6 +76,9 @@ bool isStereo() { float getStereoSideWidth() { return float(int(frameTransform._stereoInfo.y) >> getResolutionLevel()); } +float getStereoSideHeight() { + return float(int(frameTransform._pixelInfo.w) >> getResolutionLevel()); +} ivec3 getStereoSideInfo(int xPos) { int sideWidth = int(getStereoSideWidth()); diff --git a/libraries/render-utils/src/ssao_makeOcclusion.slf b/libraries/render-utils/src/ssao_makeOcclusion.slf index 01e44d0bb9..7512d6568c 100644 --- a/libraries/render-utils/src/ssao_makeOcclusion.slf +++ b/libraries/render-utils/src/ssao_makeOcclusion.slf @@ -21,7 +21,7 @@ const int MAX_MIP_LEVEL = 5; uniform sampler2D pyramidMap; float getZEye(ivec2 pixel) { - return -texelFetch(pyramidMap, pixel, getResolutionLevel()).x; + return -texelFetch(pyramidMap, pixel, 0/*getResolutionLevel()*/).x; } vec3 evalEyePositionFromZeye(int side, float Zeye, vec2 texcoord) { @@ -112,7 +112,7 @@ void main(void) { // From now on, ssC is the pixel pos in the side ssC.x -= side.y; - vec2 fragPos = (vec2(ssC) + 0.5) / getStereoSideWidth(); + vec2 fragPos = (vec2(ssC) + 0.5) / vec2(getStereoSideWidth(), getStereoSideHeight()); // The position and normal of the pixel fragment in Eye space vec3 Cp = evalEyePositionFromZeye(side.x, Zeye, fragPos); @@ -146,16 +146,16 @@ void main(void) { outFragColor = vec4(packOcclusionDepth(A, CSZToDephtKey(Cp.z)), 1.0); - + // vec3 v = normalize(Q - Cp); + //outFragColor = vec4((v + vec3(1.0))* 0.5, 1.0); + // outFragColor = vec4((Cn + vec3(1.0))* 0.5, 1.0); }