From 6f93fb311492d42390992d0cd53131cadba4c5b9 Mon Sep 17 00:00:00 2001 From: samcake Date: Tue, 19 Jan 2016 12:12:51 -0800 Subject: [PATCH] Can now process the AO at lower resolution in orer to gsave performances --- examples/utilities/tools/renderEngineDebug.js | 7 ++- .../src/AmbientOcclusionEffect.cpp | 30 +++++++++--- .../render-utils/src/AmbientOcclusionEffect.h | 5 ++ .../render-utils/src/DebugDeferredBuffer.cpp | 31 +++++------- .../render-utils/src/DebugDeferredBuffer.h | 3 +- libraries/render-utils/src/DeferredBuffer.slh | 6 ++- .../src/DeferredLightingEffect.cpp | 49 ++++++++++++------- .../render-utils/src/FramebufferCache.cpp | 41 ++++++++++++---- libraries/render-utils/src/FramebufferCache.h | 8 ++- .../render-utils/src/RenderDeferredTask.cpp | 1 + .../src/RenderScriptingInterface.h | 1 + .../src/debug_deferred_buffer.slf | 2 +- libraries/render-utils/src/ssao.slh | 20 +++++--- .../render-utils/src/ssao_makeOcclusion.slf | 6 +-- .../src/ssao_makeVerticalBlur.slf | 2 +- libraries/render/src/render/Context.h | 1 + 16 files changed, 146 insertions(+), 67 deletions(-) diff --git a/examples/utilities/tools/renderEngineDebug.js b/examples/utilities/tools/renderEngineDebug.js index 8cd1312609..f57f451e61 100755 --- a/examples/utilities/tools/renderEngineDebug.js +++ b/examples/utilities/tools/renderEngineDebug.js @@ -12,7 +12,7 @@ Script.include("cookies.js"); var MENU = "Developer>Render>Debug Deferred Buffer"; -var ACTIONS = ["Off", "Diffuse", "Metallic", "Roughness", "Normal", "Depth", "Lighting", "PyramidDepth", "AmbientOcclusion", "OcclusionRaw", "OcclusionBlurred", "Custom"]; +var ACTIONS = ["Off", "Diffuse", "Metallic", "Roughness", "Normal", "Depth", "Lighting", "Shadow", "PyramidDepth", "AmbientOcclusion", "OcclusionBlurred", "Custom"]; var SETTINGS_KEY = "EngineDebugScript.DebugMode"; Number.prototype.clamp = function(min, max) { @@ -99,6 +99,11 @@ panel.newSlider("Tone Mapping Exposure", -10, 10, function() { return Render.tone.exposure; }, function (value) { return (value); }); +panel.newSlider("Ambient Occlusion Resolution Level", 0.0, 4.0, + function (value) { Render.ambientOcclusion.resolutionLevel = value; }, + function() { return Render.ambientOcclusion.resolutionLevel; }, + function (value) { return (value); }); + panel.newSlider("Ambient Occlusion Radius", 0.0, 2.0, function (value) { Render.ambientOcclusion.radius = value; }, function() { return Render.ambientOcclusion.radius; }, diff --git a/libraries/render-utils/src/AmbientOcclusionEffect.cpp b/libraries/render-utils/src/AmbientOcclusionEffect.cpp index 8eea44bec3..20393816dc 100644 --- a/libraries/render-utils/src/AmbientOcclusionEffect.cpp +++ b/libraries/render-utils/src/AmbientOcclusionEffect.cpp @@ -197,8 +197,8 @@ const gpu::PipelinePointer& AmbientOcclusionEffect::getVBlurPipeline() { 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)); // Vertical blur write just the final result Occlusion value in the alpha channel - state->setColorWriteMask(false, false, false, true); - + state->setColorWriteMask(true, true, true, false); + // Good to go add the brand new pipeline _vBlurPipeline = gpu::Pipeline::create(program, state); } @@ -210,6 +210,17 @@ void AmbientOcclusionEffect::setDepthInfo(float nearZ, float farZ) { _frameTransformBuffer.edit()._depthInfo = glm::vec4(nearZ*farZ, farZ -nearZ, -farZ, 0.0f); } +void AmbientOcclusionEffect::setResolutionLevel(int level) { + level = std::max(0, std::min(level, 4)); + if (level != getResolutionLevel()) { + auto& current = _parametersBuffer.edit()._resolutionInfo; + current.x = (float)level; + + // Communicate the change to the Framebuffer cache + DependencyManager::get()->setAmbientOcclusionResolutionLevel(level); + } +} + void AmbientOcclusionEffect::setRadius(float radius) { radius = std::max(0.01f, radius); if (radius != getRadius()) { @@ -294,7 +305,6 @@ void AmbientOcclusionEffect::run(const render::SceneContextPointer& sceneContext auto pyramidFBO = framebufferCache->getDepthPyramidFramebuffer(); auto occlusionFBO = framebufferCache->getOcclusionFramebuffer(); auto occlusionBlurredFBO = framebufferCache->getOcclusionBlurredFramebuffer(); - auto occlusionFinalFBO = framebufferCache->getDeferredFramebufferDepthColor(); QSize framebufferSize = framebufferCache->getFrameBufferSize(); float sMin = args->_viewport.x / (float)framebufferSize.width(); @@ -302,6 +312,8 @@ void AmbientOcclusionEffect::run(const render::SceneContextPointer& sceneContext float tMin = args->_viewport.y / (float)framebufferSize.height(); float tHeight = args->_viewport.w / (float)framebufferSize.height(); + auto resolutionLevel = getResolutionLevel(); + // Update the depth info with near and far (same for stereo) setDepthInfo(args->_viewFrustum->getNearClip(), args->_viewFrustum->getFarClip()); @@ -367,6 +379,12 @@ void AmbientOcclusionEffect::run(const render::SceneContextPointer& sceneContext // 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); + } + // Occlusion pass batch.setFramebuffer(occlusionFBO); batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(1.0f)); @@ -375,14 +393,14 @@ void AmbientOcclusionEffect::run(const render::SceneContextPointer& sceneContext batch.draw(gpu::TRIANGLE_STRIP, 4); batch.setResourceTexture(AmbientOcclusionEffect_PyramidMapSlot + 1, gpu::TexturePointer()); - // Blur 1 pass + // Blur 1st pass batch.setFramebuffer(occlusionBlurredFBO); batch.setPipeline(firstHBlurPipeline); batch.setResourceTexture(AmbientOcclusionEffect_OcclusionMapSlot, occlusionFBO->getRenderBuffer(0)); batch.draw(gpu::TRIANGLE_STRIP, 4); - // Blur 2 pass - batch.setFramebuffer(occlusionFinalFBO); + // Blur 2nd pass + batch.setFramebuffer(occlusionFBO); batch.setPipeline(lastVBlurPipeline); batch.setResourceTexture(AmbientOcclusionEffect_OcclusionMapSlot, occlusionBlurredFBO->getRenderBuffer(0)); batch.draw(gpu::TRIANGLE_STRIP, 4); diff --git a/libraries/render-utils/src/AmbientOcclusionEffect.h b/libraries/render-utils/src/AmbientOcclusionEffect.h index 8cda1c355c..4919d89b04 100644 --- a/libraries/render-utils/src/AmbientOcclusionEffect.h +++ b/libraries/render-utils/src/AmbientOcclusionEffect.h @@ -24,6 +24,9 @@ public: void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); + void setResolutionLevel(int level); + int getResolutionLevel() const { return _parametersBuffer.get()._resolutionInfo.x; } + void setRadius(float radius); float getRadius() const { return _parametersBuffer.get()._radiusInfo.x; } @@ -87,6 +90,8 @@ private: // Class describing the uniform buffer with all the parameters common to the AO shaders class Parameters { public: + // Resolution info + glm::vec4 _resolutionInfo{ 1.0, 1.0, 1.0, 1.0 }; // radius info is { R, R^2, 1 / R^6, ObscuranceScale} glm::vec4 _radiusInfo{ 0.5, 0.5 * 0.5, 1.0 / (0.25 * 0.25 * 0.25), 1.0 }; // Dithering info diff --git a/libraries/render-utils/src/DebugDeferredBuffer.cpp b/libraries/render-utils/src/DebugDeferredBuffer.cpp index 3491e5a416..c504a58848 100644 --- a/libraries/render-utils/src/DebugDeferredBuffer.cpp +++ b/libraries/render-utils/src/DebugDeferredBuffer.cpp @@ -35,8 +35,8 @@ enum Slots { Lighting, Shadow, Pyramid, - OcclusionRaw, - OcclusionBlurred + AmbientOcclusion, + AmbientOcclusionBlurred }; static const std::string DEFAULT_DIFFUSE_SHADER { @@ -79,24 +79,19 @@ static const std::string DEFAULT_SHADOW_SHADER{ " }" }; -static const std::string DEFAULT_AMBIENT_OCCLUSION_SHADER{ - "vec4 getFragmentColor() {" - " return vec4(vec3(texture(diffuseMap, uv).a), 1.0);" - " }" -}; - static const std::string DEFAULT_PYRAMID_DEPTH_SHADER { "vec4 getFragmentColor() {" " return vec4(vec3(1.0 - texture(pyramidMap, uv).x * 0.01), 1.0);" //" return vec4(vec3(1.0 - textureLod(pyramidMap, uv, 3).x * 0.01), 1.0);" " }" }; -static const std::string DEFAULT_OCCLUSION_RAW_SHADER { + +static const std::string DEFAULT_AMBIENT_OCCLUSION_SHADER{ "vec4 getFragmentColor() {" - " return vec4(vec3(texture(occlusionRawMap, uv).x), 1.0);" + " return vec4(vec3(texture(occlusionMap, uv).x), 1.0);" " }" }; -static const std::string DEFAULT_OCCLUSION_BLURRED_SHADER { +static const std::string DEFAULT_AMBIENT_OCCLUSION_BLURRED_SHADER{ "vec4 getFragmentColor() {" " return vec4(vec3(texture(occlusionBlurredMap, uv).x), 1.0);" " }" @@ -148,10 +143,8 @@ std::string DebugDeferredBuffer::getShaderSourceCode(Modes mode, std::string cus return DEFAULT_PYRAMID_DEPTH_SHADER; case AmbientOcclusionMode: return DEFAULT_AMBIENT_OCCLUSION_SHADER; - case OcclusionRawMode: - return DEFAULT_OCCLUSION_RAW_SHADER; - case OcclusionBlurredMode: - return DEFAULT_OCCLUSION_BLURRED_SHADER; + case AmbientOcclusionBlurredMode: + return DEFAULT_AMBIENT_OCCLUSION_BLURRED_SHADER; case CustomMode: return getFileContent(customFile, DEFAULT_CUSTOM_SHADER); } @@ -201,8 +194,8 @@ const gpu::PipelinePointer& DebugDeferredBuffer::getPipeline(Modes mode, std::st slotBindings.insert(gpu::Shader::Binding("lightingMap", Lighting)); slotBindings.insert(gpu::Shader::Binding("shadowMapColor", Shadow)); slotBindings.insert(gpu::Shader::Binding("pyramidMap", Pyramid)); - slotBindings.insert(gpu::Shader::Binding("occlusionRawMap", OcclusionRaw)); - slotBindings.insert(gpu::Shader::Binding("occlusionBlurredMap", OcclusionBlurred)); + slotBindings.insert(gpu::Shader::Binding("occlusionMap", AmbientOcclusion)); + slotBindings.insert(gpu::Shader::Binding("occlusionBlurredMap", AmbientOcclusionBlurred)); gpu::Shader::makeProgram(*program, slotBindings); auto pipeline = gpu::Pipeline::create(program, std::make_shared()); @@ -260,8 +253,8 @@ void DebugDeferredBuffer::run(const SceneContextPointer& sceneContext, const Ren batch.setResourceTexture(Lighting, framebufferCache->getLightingTexture()); batch.setResourceTexture(Shadow, lightStage.lights[0]->shadow.framebuffer->getRenderBuffer(0)); batch.setResourceTexture(Pyramid, framebufferCache->getDepthPyramidTexture()); - batch.setResourceTexture(OcclusionRaw, framebufferCache->getOcclusionTexture()); - batch.setResourceTexture(OcclusionBlurred, framebufferCache->getOcclusionBlurredTexture()); + batch.setResourceTexture(AmbientOcclusion, framebufferCache->getOcclusionTexture()); + batch.setResourceTexture(AmbientOcclusionBlurred, framebufferCache->getOcclusionBlurredTexture()); const glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f); const glm::vec2 bottomLeft(renderContext->_deferredDebugSize.x, renderContext->_deferredDebugSize.y); diff --git a/libraries/render-utils/src/DebugDeferredBuffer.h b/libraries/render-utils/src/DebugDeferredBuffer.h index 03187b589d..ef0fe512b2 100644 --- a/libraries/render-utils/src/DebugDeferredBuffer.h +++ b/libraries/render-utils/src/DebugDeferredBuffer.h @@ -35,8 +35,7 @@ private: ShadowMode, PyramidDepthMode, AmbientOcclusionMode, - OcclusionRawMode, - OcclusionBlurredMode, + AmbientOcclusionBlurredMode, CustomMode // Needs to stay last }; struct CustomPipeline { diff --git a/libraries/render-utils/src/DeferredBuffer.slh b/libraries/render-utils/src/DeferredBuffer.slh index 7555f25886..3f9aef6dd1 100755 --- a/libraries/render-utils/src/DeferredBuffer.slh +++ b/libraries/render-utils/src/DeferredBuffer.slh @@ -24,6 +24,9 @@ uniform sampler2D specularMap; // the depth texture uniform sampler2D depthMap; +// the obscurance texture +uniform sampler2D obscuranceMap; + // the lighting texture uniform sampler2D lightingMap; @@ -82,6 +85,7 @@ DeferredFragment unpackDeferredFragment(DeferredTransform deferredTransform, vec frag.normalVal = texture(normalMap, texcoord); frag.diffuseVal = texture(diffuseMap, texcoord); frag.specularVal = texture(specularMap, texcoord); + frag.obscurance = texture(obscuranceMap, texcoord).x; if (getStereoMode(deferredTransform)) { if (texcoord.x > 0.5) { @@ -100,10 +104,10 @@ DeferredFragment unpackDeferredFragment(DeferredTransform deferredTransform, vec } frag.diffuse = frag.diffuseVal.xyz; - frag.obscurance = frag.diffuseVal.w; frag.specular = frag.specularVal.xyz; frag.gloss = frag.specularVal.w; + return frag; } diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 5af89e7afc..e43e76c87a 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -49,6 +49,15 @@ struct LightLocations { int shadowTransformBuffer; }; +enum { + DEFERRED_BUFFER_COLOR_UNIT = 0, + DEFERRED_BUFFER_NORMAL_UNIT = 1, + DEFERRED_BUFFER_EMISSIVE_UNIT = 2, + DEFERRED_BUFFER_DEPTH_UNIT = 3, + DEFERRED_BUFFER_OBSCURANCE_UNIT = 4, + SHADOW_MAP_UNIT = 5, + SKYBOX_MAP_UNIT = 6, +}; static void loadLightProgram(const char* vertSource, const char* fragSource, bool lightVolume, gpu::PipelinePointer& program, LightLocationsPtr& locations); void DeferredLightingEffect::init() { @@ -172,16 +181,17 @@ void DeferredLightingEffect::render(RenderArgs* args) { batch.setStateScissorRect(args->_viewport); // BInd the G-Buffer surfaces - batch.setResourceTexture(0, framebufferCache->getDeferredColorTexture()); - batch.setResourceTexture(1, framebufferCache->getDeferredNormalTexture()); - batch.setResourceTexture(2, framebufferCache->getDeferredSpecularTexture()); - batch.setResourceTexture(3, framebufferCache->getPrimaryDepthTexture()); + batch.setResourceTexture(DEFERRED_BUFFER_COLOR_UNIT, framebufferCache->getDeferredColorTexture()); + batch.setResourceTexture(DEFERRED_BUFFER_NORMAL_UNIT, framebufferCache->getDeferredNormalTexture()); + batch.setResourceTexture(DEFERRED_BUFFER_EMISSIVE_UNIT, framebufferCache->getDeferredSpecularTexture()); + batch.setResourceTexture(DEFERRED_BUFFER_DEPTH_UNIT, framebufferCache->getPrimaryDepthTexture()); + batch.setResourceTexture(DEFERRED_BUFFER_OBSCURANCE_UNIT, framebufferCache->getOcclusionTexture()); assert(_lightStage.lights.size() > 0); const auto& globalShadow = _lightStage.lights[0]->shadow; // Bind the shadow buffer - batch.setResourceTexture(4, globalShadow.map); + batch.setResourceTexture(SHADOW_MAP_UNIT, globalShadow.map); // THe main viewport is assumed to be the mono viewport (or the 2 stereo faces side by side within that viewport) auto monoViewport = args->_viewport; @@ -323,7 +333,7 @@ void DeferredLightingEffect::render(RenderArgs* args) { } if (useSkyboxCubemap) { - batch.setResourceTexture(5, _skybox->getCubemap()); + batch.setResourceTexture(SKYBOX_MAP_UNIT, _skybox->getCubemap()); } if (locations->lightBufferUnit >= 0) { @@ -345,7 +355,7 @@ void DeferredLightingEffect::render(RenderArgs* args) { } if (useSkyboxCubemap) { - batch.setResourceTexture(5, nullptr); + batch.setResourceTexture(SKYBOX_MAP_UNIT, nullptr); } } @@ -461,10 +471,14 @@ void DeferredLightingEffect::render(RenderArgs* args) { } // Probably not necessary in the long run because the gpu layer would unbound this texture if used as render target - batch.setResourceTexture(0, nullptr); - batch.setResourceTexture(1, nullptr); - batch.setResourceTexture(2, nullptr); - batch.setResourceTexture(3, nullptr); + batch.setResourceTexture(DEFERRED_BUFFER_COLOR_UNIT, nullptr); + batch.setResourceTexture(DEFERRED_BUFFER_NORMAL_UNIT, nullptr); + batch.setResourceTexture(DEFERRED_BUFFER_EMISSIVE_UNIT, nullptr); + batch.setResourceTexture(DEFERRED_BUFFER_DEPTH_UNIT, nullptr); + batch.setResourceTexture(DEFERRED_BUFFER_OBSCURANCE_UNIT, nullptr); + batch.setResourceTexture(SHADOW_MAP_UNIT, nullptr); + batch.setResourceTexture(SKYBOX_MAP_UNIT, nullptr); + batch.setUniformBuffer(_directionalLightLocations->deferredTransformBuffer, nullptr); }); @@ -489,12 +503,13 @@ static void loadLightProgram(const char* vertSource, const char* fragSource, boo gpu::ShaderPointer program = gpu::Shader::createProgram(VS, PS); gpu::Shader::BindingSet slotBindings; - slotBindings.insert(gpu::Shader::Binding(std::string("diffuseMap"), 0)); - slotBindings.insert(gpu::Shader::Binding(std::string("normalMap"), 1)); - slotBindings.insert(gpu::Shader::Binding(std::string("specularMap"), 2)); - slotBindings.insert(gpu::Shader::Binding(std::string("depthMap"), 3)); - slotBindings.insert(gpu::Shader::Binding(std::string("shadowMap"), 4)); - slotBindings.insert(gpu::Shader::Binding(std::string("skyboxMap"), 5)); + slotBindings.insert(gpu::Shader::Binding(std::string("diffuseMap"), DEFERRED_BUFFER_COLOR_UNIT)); + slotBindings.insert(gpu::Shader::Binding(std::string("normalMap"), DEFERRED_BUFFER_NORMAL_UNIT)); + slotBindings.insert(gpu::Shader::Binding(std::string("specularMap"), DEFERRED_BUFFER_EMISSIVE_UNIT)); + slotBindings.insert(gpu::Shader::Binding(std::string("depthMap"), DEFERRED_BUFFER_DEPTH_UNIT)); + slotBindings.insert(gpu::Shader::Binding(std::string("obscuranceMap"), DEFERRED_BUFFER_OBSCURANCE_UNIT)); + slotBindings.insert(gpu::Shader::Binding(std::string("shadowMap"), SHADOW_MAP_UNIT)); + slotBindings.insert(gpu::Shader::Binding(std::string("skyboxMap"), SKYBOX_MAP_UNIT)); static const int LIGHT_GPU_SLOT = 3; static const int ATMOSPHERE_GPU_SLOT = 4; diff --git a/libraries/render-utils/src/FramebufferCache.cpp b/libraries/render-utils/src/FramebufferCache.cpp index 075d9ca69f..025c0285d4 100644 --- a/libraries/render-utils/src/FramebufferCache.cpp +++ b/libraries/render-utils/src/FramebufferCache.cpp @@ -111,17 +111,32 @@ void FramebufferCache::createPrimaryFramebuffer() { _depthPyramidFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat); - _occlusionTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGB), width, height, defaultSampler)); + 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_POINT_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(gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGB), width, height, defaultSampler)); + + _occlusionBlurredTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height, defaultSampler)); _occlusionBlurredFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create()); _occlusionBlurredFramebuffer->setRenderBuffer(0, _occlusionBlurredTexture); _occlusionBlurredFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat); - } gpu::FramebufferPointer FramebufferCache::getPrimaryFramebuffer() { @@ -230,30 +245,38 @@ gpu::TexturePointer FramebufferCache::getDepthPyramidTexture() { return _depthPyramidTexture; } +void FramebufferCache::setAmbientOcclusionResolutionLevel(int level) { + level = std::max(0, std::min(level, 4)); + if (level != _AOResolutionLevel) { + _AOResolutionLevel = level; + resizeAmbientOcclusionBuffers(); + } +} + gpu::FramebufferPointer FramebufferCache::getOcclusionFramebuffer() { if (!_occlusionFramebuffer) { - createPrimaryFramebuffer(); + resizeAmbientOcclusionBuffers(); } return _occlusionFramebuffer; } gpu::TexturePointer FramebufferCache::getOcclusionTexture() { if (!_occlusionTexture) { - createPrimaryFramebuffer(); + resizeAmbientOcclusionBuffers(); } return _occlusionTexture; } gpu::FramebufferPointer FramebufferCache::getOcclusionBlurredFramebuffer() { if (!_occlusionBlurredFramebuffer) { - createPrimaryFramebuffer(); + resizeAmbientOcclusionBuffers(); } return _occlusionBlurredFramebuffer; } gpu::TexturePointer FramebufferCache::getOcclusionBlurredTexture() { if (!_occlusionBlurredTexture) { - createPrimaryFramebuffer(); + 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 f0600d85bb..cf126b20b1 100644 --- a/libraries/render-utils/src/FramebufferCache.h +++ b/libraries/render-utils/src/FramebufferCache.h @@ -46,7 +46,8 @@ public: gpu::FramebufferPointer getDepthPyramidFramebuffer(); gpu::TexturePointer getDepthPyramidTexture(); - + + void setAmbientOcclusionResolutionLevel(int level); gpu::FramebufferPointer getOcclusionFramebuffer(); gpu::TexturePointer getOcclusionTexture(); gpu::FramebufferPointer getOcclusionBlurredFramebuffer(); @@ -102,6 +103,11 @@ private: gpu::TexturePointer _occlusionBlurredTexture; QSize _frameBufferSize{ 100, 100 }; + int _AOResolutionLevel = 0; + + // 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 935723d864..3396e44d58 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -172,6 +172,7 @@ void RenderDeferredTask::run(const SceneContextPointer& sceneContext, const Rend setOcclusionStatus(renderContext->getOcclusionStatus()); if (_occlusionJobIndex >= 0) { + _jobs[_occlusionJobIndex].edit().setResolutionLevel(renderContext->getAmbientOcclusion().resolutionLevel); _jobs[_occlusionJobIndex].edit().setRadius(renderContext->getAmbientOcclusion().radius); _jobs[_occlusionJobIndex].edit().setLevel(renderContext->getAmbientOcclusion().level); _jobs[_occlusionJobIndex].edit().setNumSamples(renderContext->getAmbientOcclusion().numSamples); diff --git a/libraries/render-utils/src/RenderScriptingInterface.h b/libraries/render-utils/src/RenderScriptingInterface.h index 95741ce641..41448f06c6 100644 --- a/libraries/render-utils/src/RenderScriptingInterface.h +++ b/libraries/render-utils/src/RenderScriptingInterface.h @@ -70,6 +70,7 @@ namespace RenderScripting { Q_OBJECT public: + Q_PROPERTY(int resolutionLevel MEMBER resolutionLevel) Q_PROPERTY(float radius MEMBER radius) Q_PROPERTY(float level MEMBER level) Q_PROPERTY(int numSamples MEMBER numSamples) diff --git a/libraries/render-utils/src/debug_deferred_buffer.slf b/libraries/render-utils/src/debug_deferred_buffer.slf index 3a96486d41..bbc50fa97a 100644 --- a/libraries/render-utils/src/debug_deferred_buffer.slf +++ b/libraries/render-utils/src/debug_deferred_buffer.slf @@ -15,7 +15,7 @@ <@include DeferredBuffer.slh@> uniform sampler2D pyramidMap; -uniform sampler2D occlusionRawMap; +uniform sampler2D occlusionMap; uniform sampler2D occlusionBlurredMap; in vec2 uv; diff --git a/libraries/render-utils/src/ssao.slh b/libraries/render-utils/src/ssao.slh index 733c6b9074..3cf24f2ebd 100644 --- a/libraries/render-utils/src/ssao.slh +++ b/libraries/render-utils/src/ssao.slh @@ -39,6 +39,7 @@ struct AmbientOcclusionFrameTransform { }; struct AmbientOcclusionParams { + vec4 _resolutionInfo; vec4 _radiusInfo; vec4 _ditheringInfo; vec4 _sampleInfo; @@ -53,8 +54,13 @@ uniform ambientOcclusionParamsBuffer { AmbientOcclusionParams params; }; + +int getResolutionLevel() { + return int(params._resolutionInfo.x); +} + vec2 getWidthHeight() { - return frameTransform._pixelInfo.zw; + return vec2(ivec2(frameTransform._pixelInfo.zw) >> getResolutionLevel()); } float getProjScale() { return getWidthHeight().y * frameTransform._projection[0][1][1] * 0.5; @@ -67,14 +73,16 @@ bool isStereo() { return frameTransform._stereoInfo.x > 0.0f; } -ivec2 getStereoSideInfo(int xPos) { - return (xPos < frameTransform._stereoInfo.y ? ivec2(0, 0) : ivec2(1, int(frameTransform._stereoInfo.y)) ); +float getStereoSideWidth() { + return float(int(frameTransform._stereoInfo.y) >> getResolutionLevel()); } -float getStereoSideWidth() { - return (frameTransform._stereoInfo.y); +ivec2 getStereoSideInfo(int xPos) { + int sideWidth = int(getStereoSideWidth()); + return (xPos < sideWidth ? ivec2(0, 0) : ivec2(1, sideWidth) ); } + float evalZeyeFromZdb(float depth) { return frameTransform._depthInfo.x / (depth * frameTransform._depthInfo.y + frameTransform._depthInfo.z); } @@ -199,7 +207,7 @@ vec3 getBlurredOcclusion(vec2 coord) { for (int r = -blurRadius; r <= -1; ++r) { weightedSums += evalTapWeightedValue(r, ssC, key); } - // then possitive side + // then positive side for (int r = 1; r <= blurRadius; ++r) { weightedSums += evalTapWeightedValue(r, ssC, key); } diff --git a/libraries/render-utils/src/ssao_makeOcclusion.slf b/libraries/render-utils/src/ssao_makeOcclusion.slf index 6e128945c5..1cfef02ba5 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, 0).x; + return -texelFetch(pyramidMap, pixel, getResolutionLevel()).x; } vec3 evalEyePositionFromZeye(ivec2 side, float Zeye, vec2 texcoord) { @@ -62,8 +62,8 @@ vec3 getOffsetPosition(ivec2 side, ivec2 ssC, vec2 unitOffset, float ssR) { // We need to divide by 2^mipLevel to read the appropriately scaled coordinate from a MIP-map. // Manually clamp to the texture size because texelFetch bypasses the texture unit - ivec2 mipP = clamp(ssPFull >> mipLevel, ivec2(0), textureSize(pyramidMap, mipLevel) - ivec2(1)); - P.z = -texelFetch(pyramidMap, mipP, mipLevel).r; + ivec2 mipP = clamp(ssPFull >> mipLevel, ivec2(0), textureSize(pyramidMap, getResolutionLevel() + mipLevel) - ivec2(1)); + P.z = -texelFetch(pyramidMap, mipP, getResolutionLevel() + mipLevel).r; // P.z = -texelFetch(pyramidMap, ssPFull, 0).r; // Offset to pixel center diff --git a/libraries/render-utils/src/ssao_makeVerticalBlur.slf b/libraries/render-utils/src/ssao_makeVerticalBlur.slf index 40ad63b94e..f0a6139906 100644 --- a/libraries/render-utils/src/ssao_makeVerticalBlur.slf +++ b/libraries/render-utils/src/ssao_makeVerticalBlur.slf @@ -18,5 +18,5 @@ out vec4 outFragColor; void main(void) { float occlusion = getBlurredOcclusion(gl_FragCoord.xy).x; - outFragColor = vec4(0.0, 0.0, 0.0, occlusion); + outFragColor = vec4(occlusion, 0.0, 0.0, occlusion); } diff --git a/libraries/render/src/render/Context.h b/libraries/render/src/render/Context.h index baca2640a0..b32f3ad66b 100644 --- a/libraries/render/src/render/Context.h +++ b/libraries/render/src/render/Context.h @@ -74,6 +74,7 @@ public: class AmbientOcclusion { public: + int resolutionLevel = 0; float radius = 0.5f; // radius in meters of the AO effect float level = 0.5f; // Level of the obscrance value int numSamples = 11; // Num Samples per pixel