From 9332f82d54a70cf9347aa855c15921844c0ebb32 Mon Sep 17 00:00:00 2001 From: samcake Date: Sun, 17 Jul 2016 17:13:07 -0700 Subject: [PATCH] Carrefully improving the curvature generation performances --- .../render-utils/src/DebugDeferredBuffer.cpp | 12 +- .../render-utils/src/DebugDeferredBuffer.h | 3 +- .../render-utils/src/DeferredTransform.slh | 5 + .../render-utils/src/RenderDeferredTask.cpp | 18 +- .../render-utils/src/SurfaceGeometryPass.cpp | 260 ++++++++++++------ .../render-utils/src/SurfaceGeometryPass.h | 90 +++++- .../src/surfaceGeometry_makeCurvature.slf | 5 + libraries/render/src/render/BlurTask.cpp | 9 + libraries/render/src/render/BlurTask.h | 5 + libraries/render/src/render/BlurTask.slh | 11 +- .../utilities/render/deferredLighting.qml | 1 + .../developer/utilities/render/statsGPU.qml | 7 +- 12 files changed, 321 insertions(+), 105 deletions(-) diff --git a/libraries/render-utils/src/DebugDeferredBuffer.cpp b/libraries/render-utils/src/DebugDeferredBuffer.cpp index e32c0c2884..73aa614233 100644 --- a/libraries/render-utils/src/DebugDeferredBuffer.cpp +++ b/libraries/render-utils/src/DebugDeferredBuffer.cpp @@ -144,7 +144,13 @@ static const std::string DEFAULT_SHADOW_SHADER { 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_LINEAR_DEPTH_2_SHADER{ + "vec4 getFragmentColor() {" + // " return vec4(vec3(1.0 - texture(pyramidMap, uv).x * 0.01), 1.0);" + " return vec4(vec3(1.0 - textureLod(pyramidMap, uv, 1).x * 0.01), 1.0);" " }" }; @@ -252,8 +258,10 @@ std::string DebugDeferredBuffer::getShaderSourceCode(Mode mode, std::string cust return DEFAULT_LIGHTING_SHADER; case ShadowMode: return DEFAULT_SHADOW_SHADER; - case PyramidDepthMode: + case LinearDepthMode: return DEFAULT_PYRAMID_DEPTH_SHADER; + case LinearDepth2Mode: + return DEFAULT_LINEAR_DEPTH_2_SHADER; case CurvatureMode: return DEFAULT_CURVATURE_SHADER; case NormalCurvatureMode: diff --git a/libraries/render-utils/src/DebugDeferredBuffer.h b/libraries/render-utils/src/DebugDeferredBuffer.h index 1053779577..2f919930d3 100644 --- a/libraries/render-utils/src/DebugDeferredBuffer.h +++ b/libraries/render-utils/src/DebugDeferredBuffer.h @@ -63,7 +63,8 @@ protected: ScatteringMode, LightingMode, ShadowMode, - PyramidDepthMode, + LinearDepthMode, + LinearDepth2Mode, CurvatureMode, NormalCurvatureMode, DiffusedCurvatureMode, diff --git a/libraries/render-utils/src/DeferredTransform.slh b/libraries/render-utils/src/DeferredTransform.slh index 814a59a407..b3881c4c71 100644 --- a/libraries/render-utils/src/DeferredTransform.slh +++ b/libraries/render-utils/src/DeferredTransform.slh @@ -61,6 +61,11 @@ float getProjectionNear() { return planeD / planeC; } +// positive far distance of the projection +float getPosLinearDepthFar() { + return -frameTransform._depthInfo.z; +} + mat4 getViewInverse() { return frameTransform._viewInverse; } diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 0c47768bcf..d54cc4f7ce 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -103,7 +103,7 @@ RenderDeferredTask::RenderDeferredTask(CullFunctor cullFunctor) { const auto fullFrameRangeTimer = addJob("BeginRangeTimer"); const auto opaqueRangeTimer = addJob("BeginOpaqueRangeTimer"); - const auto prepareDeferredInputs = SurfaceGeometryPass::Inputs(primaryFramebuffer, lightingModel).hasVarying(); + const auto prepareDeferredInputs = PrepareDeferred::Inputs(primaryFramebuffer, lightingModel).hasVarying(); const auto prepareDeferredOutputs = addJob("PrepareDeferred", prepareDeferredInputs); const auto deferredFramebuffer = prepareDeferredOutputs.getN(0); const auto lightingFramebuffer = prepareDeferredOutputs.getN(1); @@ -117,15 +117,23 @@ RenderDeferredTask::RenderDeferredTask(CullFunctor cullFunctor) { addJob("OpaqueRangeTimer", opaqueRangeTimer); - const auto curvatureRangeTimer = addJob("BeginCurvatureRangeTimer"); - // Opaque all rendered, generate surface geometry buffers - const auto surfaceGeometryPassInputs = SurfaceGeometryPass::Inputs(deferredFrameTransform, deferredFramebuffer).hasVarying(); + // Opaque all rendered + + // Linear Depth Pass + const auto linearDepthPassInputs = LinearDepthPass::Inputs(deferredFrameTransform, deferredFramebuffer).hasVarying(); + const auto linearDepthPassOutputs = addJob("LinearDepth", linearDepthPassInputs); + const auto linearDepthTarget = linearDepthPassOutputs.getN(0); + const auto linearDepthTexture = linearDepthPassOutputs.getN(2); + + + // Curvature pass + const auto surfaceGeometryPassInputs = SurfaceGeometryPass::Inputs(deferredFrameTransform, deferredFramebuffer, linearDepthTarget).hasVarying(); const auto surfaceGeometryPassOutputs = addJob("SurfaceGeometry", surfaceGeometryPassInputs); const auto surfaceGeometryFramebuffer = surfaceGeometryPassOutputs.getN(0); const auto curvatureFramebuffer = surfaceGeometryPassOutputs.getN(1); - const auto linearDepthTexture = surfaceGeometryPassOutputs.getN(2); + const auto curvatureRangeTimer = addJob("BeginCurvatureRangeTimer"); // TODO: Push this 2 diffusion stages into surfaceGeometryPass as they are working together const auto diffuseCurvaturePassInputs = BlurGaussianDepthAware::Inputs(curvatureFramebuffer, linearDepthTexture).hasVarying(); diff --git a/libraries/render-utils/src/SurfaceGeometryPass.cpp b/libraries/render-utils/src/SurfaceGeometryPass.cpp index 66a1c89e77..369341403f 100644 --- a/libraries/render-utils/src/SurfaceGeometryPass.cpp +++ b/libraries/render-utils/src/SurfaceGeometryPass.cpp @@ -10,10 +10,15 @@ // #include "SurfaceGeometryPass.h" +#include + #include #include +const int DepthLinearPass_FrameTransformSlot = 0; +const int DepthLinearPass_DepthMapSlot = 0; + const int SurfaceGeometryPass_FrameTransformSlot = 0; const int SurfaceGeometryPass_ParamsSlot = 1; const int SurfaceGeometryPass_DepthMapSlot = 0; @@ -25,11 +30,11 @@ const int SurfaceGeometryPass_NormalMapSlot = 1; -SurfaceGeometryFramebuffer::SurfaceGeometryFramebuffer() { +LinearDepthFramebuffer::LinearDepthFramebuffer() { } -void SurfaceGeometryFramebuffer::updatePrimaryDepth(const gpu::TexturePointer& depthBuffer) { +void LinearDepthFramebuffer::updatePrimaryDepth(const gpu::TexturePointer& depthBuffer) { //If the depth buffer or size changed, we need to delete our FBOs bool reset = false; if ((_primaryDepthTexture != depthBuffer)) { @@ -49,42 +54,173 @@ void SurfaceGeometryFramebuffer::updatePrimaryDepth(const gpu::TexturePointer& d } } -void SurfaceGeometryFramebuffer::clear() { +void LinearDepthFramebuffer::clear() { _linearDepthFramebuffer.reset(); _linearDepthTexture.reset(); +} + +void LinearDepthFramebuffer::allocate() { + + auto width = _frameSize.x; + auto height = _frameSize.y; + + // For Linear Depth: + _linearDepthTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::RGB), width, height, + gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); + _linearDepthTexture->autoGenerateMips(1); + _linearDepthFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create()); + _linearDepthFramebuffer->setRenderBuffer(0, _linearDepthTexture); + _linearDepthFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, _primaryDepthTexture->getTexelFormat()); +} + +gpu::FramebufferPointer LinearDepthFramebuffer::getLinearDepthFramebuffer() { + if (!_linearDepthFramebuffer) { + allocate(); + } + return _linearDepthFramebuffer; +} + +gpu::TexturePointer LinearDepthFramebuffer::getLinearDepthTexture() { + if (!_linearDepthTexture) { + allocate(); + } + return _linearDepthTexture; +} + + +LinearDepthPass::LinearDepthPass() { +} + +void LinearDepthPass::configure(const Config& config) { +} + +void LinearDepthPass::run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& outputs) { + assert(renderContext->args); + assert(renderContext->args->hasViewFrustum()); + + RenderArgs* args = renderContext->args; + + const auto frameTransform = inputs.get0(); + const auto deferredFramebuffer = inputs.get1(); + + if (!_linearDepthFramebuffer) { + _linearDepthFramebuffer = std::make_shared(); + } + _linearDepthFramebuffer->updatePrimaryDepth(deferredFramebuffer->getPrimaryDepthTexture()); + + auto depthBuffer = deferredFramebuffer->getPrimaryDepthTexture(); + auto normalTexture = deferredFramebuffer->getDeferredNormalTexture(); + + auto linearDepthFBO = _linearDepthFramebuffer->getLinearDepthFramebuffer(); + auto linearDepthTexture = _linearDepthFramebuffer->getLinearDepthTexture(); + + outputs.edit0() = _linearDepthFramebuffer; + outputs.edit1() = linearDepthFBO; + outputs.edit2() = linearDepthTexture; + + auto linearDepthPipeline = getLinearDepthPipeline(); + + auto depthViewport = args->_viewport; + auto furtherDepth = std::numeric_limits::infinity(); + furtherDepth = args->getViewFrustum().getFarClip() + 10.0; + + gpu::doInBatch(args->_context, [=](gpu::Batch& batch) { + _gpuTimer.begin(batch); + batch.enableStereo(false); + + batch.setViewportTransform(depthViewport); + batch.setProjectionTransform(glm::mat4()); + batch.setViewTransform(Transform()); + batch.setModelTransform(gpu::Framebuffer::evalSubregionTexcoordTransform(_linearDepthFramebuffer->getDepthFrameSize(), depthViewport)); + + batch.setUniformBuffer(DepthLinearPass_FrameTransformSlot, frameTransform->getFrameTransformBuffer()); + + // Pyramid pass + batch.setFramebuffer(linearDepthFBO); + batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(furtherDepth, 0.0f, 0.0f, 0.0f)); + batch.setPipeline(linearDepthPipeline); + batch.setResourceTexture(DepthLinearPass_DepthMapSlot, depthBuffer); + batch.draw(gpu::TRIANGLE_STRIP, 4); + + // batch.setResourceTexture(DepthLinearPass_DepthMapSlot, nullptr); + batch.generateTextureMips(linearDepthFBO->getRenderBuffer(0)); + + _gpuTimer.end(batch); + }); + + auto config = std::static_pointer_cast(renderContext->jobConfig); + config->gpuTime = _gpuTimer.getAverage(); +} + + +const gpu::PipelinePointer& LinearDepthPass::getLinearDepthPipeline() { + if (!_linearDepthPipeline) { + auto vs = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS(); + auto ps = gpu::Shader::createPixel(std::string(surfaceGeometry_makeLinearDepth_frag)); + gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps); + + gpu::Shader::BindingSet slotBindings; + slotBindings.insert(gpu::Shader::Binding(std::string("deferredFrameTransformBuffer"), DepthLinearPass_FrameTransformSlot)); + slotBindings.insert(gpu::Shader::Binding(std::string("depthMap"), DepthLinearPass_DepthMapSlot)); + gpu::Shader::makeProgram(*program, slotBindings); + + + gpu::StatePointer state = gpu::StatePointer(new gpu::State()); + + // Stencil test the curvature pass 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 + _linearDepthPipeline = gpu::Pipeline::create(program, state); + } + + return _linearDepthPipeline; +} + + + +SurfaceGeometryFramebuffer::SurfaceGeometryFramebuffer() { +} + +void SurfaceGeometryFramebuffer::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 SurfaceGeometryFramebuffer::clear() { _curvatureFramebuffer.reset(); _curvatureTexture.reset(); } +gpu::TexturePointer SurfaceGeometryFramebuffer::getLinearDepthTexture() { + return _linearDepthTexture; +} + void SurfaceGeometryFramebuffer::allocate() { auto width = _frameSize.x; auto height = _frameSize.y; - // For Linear Depth: - _linearDepthTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::RGB), width, height, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); - _linearDepthFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create()); - _linearDepthFramebuffer->setRenderBuffer(0, _linearDepthTexture); - _linearDepthFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, _primaryDepthTexture->getTexelFormat()); - _curvatureTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_RGBA_32, width >> getResolutionLevel(), height >> getResolutionLevel(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); _curvatureFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create()); _curvatureFramebuffer->setRenderBuffer(0, _curvatureTexture); -// _curvatureFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, _primaryDepthTexture->getTexelFormat()); -} - -gpu::FramebufferPointer SurfaceGeometryFramebuffer::getLinearDepthFramebuffer() { - if (!_linearDepthFramebuffer) { - allocate(); - } - return _linearDepthFramebuffer; -} - -gpu::TexturePointer SurfaceGeometryFramebuffer::getLinearDepthTexture() { - if (!_linearDepthTexture) { - allocate(); - } - return _linearDepthTexture; } gpu::FramebufferPointer SurfaceGeometryFramebuffer::getCurvatureFramebuffer() { @@ -108,7 +244,6 @@ void SurfaceGeometryFramebuffer::setResolutionLevel(int resolutionLevel) { } } - SurfaceGeometryPass::SurfaceGeometryPass() { Parameters parameters; _parametersBuffer = gpu::BufferView(std::make_shared(sizeof(Parameters), (const gpu::Byte*) ¶meters)); @@ -135,7 +270,7 @@ void SurfaceGeometryPass::configure(const Config& config) { } -void SurfaceGeometryPass::run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& curvatureAndDepth) { +void SurfaceGeometryPass::run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& outputs) { assert(renderContext->args); assert(renderContext->args->hasViewFrustum()); @@ -143,31 +278,28 @@ void SurfaceGeometryPass::run(const render::SceneContextPointer& sceneContext, c const auto frameTransform = inputs.get0(); const auto deferredFramebuffer = inputs.get1(); + const auto linearDepthFramebuffer = inputs.get2(); + + auto linearDepthTexture = linearDepthFramebuffer->getLinearDepthTexture(); if (!_surfaceGeometryFramebuffer) { _surfaceGeometryFramebuffer = std::make_shared(); } - _surfaceGeometryFramebuffer->updatePrimaryDepth(deferredFramebuffer->getPrimaryDepthTexture()); + _surfaceGeometryFramebuffer->updateLinearDepth(linearDepthTexture); - auto depthBuffer = deferredFramebuffer->getPrimaryDepthTexture(); auto normalTexture = deferredFramebuffer->getDeferredNormalTexture(); - auto linearDepthFBO = _surfaceGeometryFramebuffer->getLinearDepthFramebuffer(); - auto linearDepthTexture = _surfaceGeometryFramebuffer->getLinearDepthTexture(); auto curvatureFBO = _surfaceGeometryFramebuffer->getCurvatureFramebuffer(); - auto curvatureTexture = _surfaceGeometryFramebuffer->getCurvatureTexture(); + if (curvatureFBO->getDepthStencilBuffer() != deferredFramebuffer->getPrimaryDepthTexture()) { + curvatureFBO->setDepthStencilBuffer(deferredFramebuffer->getPrimaryDepthTexture(), deferredFramebuffer->getPrimaryDepthTexture()->getTexelFormat()); + } + auto curvatureTexture = _surfaceGeometryFramebuffer->getCurvatureTexture(); - curvatureAndDepth.edit0() = _surfaceGeometryFramebuffer; - curvatureAndDepth.edit1() = curvatureFBO; - curvatureAndDepth.edit2() = linearDepthTexture; + outputs.edit0() = _surfaceGeometryFramebuffer; + outputs.edit1() = curvatureFBO; - auto linearDepthPipeline = getLinearDepthPipeline(); auto curvaturePipeline = getCurvaturePipeline(); - - // gpu::doInBatch(args->_context, [&](gpu::Batch& batch) { - // _gpuTimer.begin(batch); - // }); - + auto depthViewport = args->_viewport; auto curvatureViewport = depthViewport >> _surfaceGeometryFramebuffer->getResolutionLevel(); @@ -175,70 +307,34 @@ void SurfaceGeometryPass::run(const render::SceneContextPointer& sceneContext, c _gpuTimer.begin(batch); batch.enableStereo(false); - batch.setViewportTransform(depthViewport); batch.setProjectionTransform(glm::mat4()); batch.setViewTransform(Transform()); - batch.setModelTransform(gpu::Framebuffer::evalSubregionTexcoordTransform(_surfaceGeometryFramebuffer->getDepthFrameSize(), depthViewport)); - - batch.setUniformBuffer(SurfaceGeometryPass_FrameTransformSlot, frameTransform->getFrameTransformBuffer()); - batch.setUniformBuffer(SurfaceGeometryPass_ParamsSlot, _parametersBuffer); - - // Pyramid pass - batch.setFramebuffer(linearDepthFBO); - batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(args->getViewFrustum().getFarClip(), 0.0f, 0.0f, 0.0f)); - batch.setPipeline(linearDepthPipeline); - batch.setResourceTexture(SurfaceGeometryPass_DepthMapSlot, depthBuffer); - batch.draw(gpu::TRIANGLE_STRIP, 4); batch.setViewportTransform(curvatureViewport); batch.setModelTransform(gpu::Framebuffer::evalSubregionTexcoordTransform(_surfaceGeometryFramebuffer->getCurvatureFrameSize(), curvatureViewport)); + batch.setUniformBuffer(SurfaceGeometryPass_FrameTransformSlot, frameTransform->getFrameTransformBuffer()); + batch.setUniformBuffer(SurfaceGeometryPass_ParamsSlot, _parametersBuffer); + // Curvature pass batch.setFramebuffer(curvatureFBO); - batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(0.0)); + // batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(0.0)); + batch.setPipeline(curvaturePipeline); batch.setResourceTexture(SurfaceGeometryPass_DepthMapSlot, linearDepthTexture); batch.setResourceTexture(SurfaceGeometryPass_NormalMapSlot, normalTexture); batch.draw(gpu::TRIANGLE_STRIP, 4); + batch.setResourceTexture(SurfaceGeometryPass_DepthMapSlot, nullptr); batch.setResourceTexture(SurfaceGeometryPass_NormalMapSlot, nullptr); _gpuTimer.end(batch); }); - - // gpu::doInBatch(args->_context, [&](gpu::Batch& batch) { - // _gpuTimer.end(batch); - // }); auto config = std::static_pointer_cast(renderContext->jobConfig); config->gpuTime = _gpuTimer.getAverage(); } -const gpu::PipelinePointer& SurfaceGeometryPass::getLinearDepthPipeline() { - if (!_linearDepthPipeline) { - auto vs = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS(); - auto ps = gpu::Shader::createPixel(std::string(surfaceGeometry_makeLinearDepth_frag)); - gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps); - - gpu::Shader::BindingSet slotBindings; - slotBindings.insert(gpu::Shader::Binding(std::string("deferredFrameTransformBuffer"), SurfaceGeometryPass_FrameTransformSlot)); - slotBindings.insert(gpu::Shader::Binding(std::string("linearDepthMap"), SurfaceGeometryPass_DepthMapSlot)); - gpu::Shader::makeProgram(*program, slotBindings); - - - gpu::StatePointer state = gpu::StatePointer(new gpu::State()); - - // Stencil test the curvature pass 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 - _linearDepthPipeline = gpu::Pipeline::create(program, state); - } - - return _linearDepthPipeline; -} const gpu::PipelinePointer& SurfaceGeometryPass::getCurvaturePipeline() { if (!_curvaturePipeline) { diff --git a/libraries/render-utils/src/SurfaceGeometryPass.h b/libraries/render-utils/src/SurfaceGeometryPass.h index bdd3997536..8137deda35 100644 --- a/libraries/render-utils/src/SurfaceGeometryPass.h +++ b/libraries/render-utils/src/SurfaceGeometryPass.h @@ -19,23 +19,19 @@ #include "DeferredFramebuffer.h" -// SurfaceGeometryFramebuffer is a helper class gathering in one place theframebuffers and targets describing the surface geometry linear depth and curvature generated -// from a z buffer and a normal buffer -class SurfaceGeometryFramebuffer { +// SurfaceGeometryFramebuffer is a helper class gathering in one place theframebuffers and targets describing the surface geometry linear depth +// from a z buffer +class LinearDepthFramebuffer { public: - SurfaceGeometryFramebuffer(); + LinearDepthFramebuffer(); gpu::FramebufferPointer getLinearDepthFramebuffer(); gpu::TexturePointer getLinearDepthTexture(); - gpu::FramebufferPointer getCurvatureFramebuffer(); - gpu::TexturePointer getCurvatureTexture(); - // Update the depth buffer which will drive the allocation of all the other resources according to its size. void updatePrimaryDepth(const gpu::TexturePointer& depthBuffer); gpu::TexturePointer getPrimaryDepthTexture(); const glm::ivec2& getDepthFrameSize() const { return _frameSize; } - glm::ivec2 getCurvatureFrameSize() const { return _frameSize >> _resolutionLevel; } void setResolutionLevel(int level); int getResolutionLevel() const { return _resolutionLevel; } @@ -48,6 +44,76 @@ protected: gpu::FramebufferPointer _linearDepthFramebuffer; gpu::TexturePointer _linearDepthTexture; + + glm::ivec2 _frameSize; + int _resolutionLevel{ 0 }; +}; + +using LinearDepthFramebufferPointer = std::shared_ptr; + + +class LinearDepthPassConfig : public render::Job::Config { + Q_OBJECT + Q_PROPERTY(double gpuTime READ getGpuTime) +public: + LinearDepthPassConfig() : render::Job::Config(true) {} + + double getGpuTime() { return gpuTime; } + + double gpuTime{ 0.0 }; + +signals: + void dirty(); +}; + +class LinearDepthPass { +public: + using Inputs = render::VaryingSet2; + using Outputs = render::VaryingSet3; + using Config = LinearDepthPassConfig; + using JobModel = render::Job::ModelIO; + + LinearDepthPass(); + + void configure(const Config& config); + void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& outputs); + +private: + typedef gpu::BufferView UniformBufferView; + + LinearDepthFramebufferPointer _linearDepthFramebuffer; + + const gpu::PipelinePointer& getLinearDepthPipeline(); + + gpu::PipelinePointer _linearDepthPipeline; + + gpu::RangeTimer _gpuTimer; +}; + + +// SurfaceGeometryFramebuffer is a helper class gathering in one place theframebuffers and targets describing the surface geometry linear depth and curvature generated +// from a z buffer and a normal buffer +class SurfaceGeometryFramebuffer { +public: + SurfaceGeometryFramebuffer(); + + gpu::FramebufferPointer getCurvatureFramebuffer(); + gpu::TexturePointer getCurvatureTexture(); + + // 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; } + glm::ivec2 getCurvatureFrameSize() const { return _frameSize >> _resolutionLevel; } + + void setResolutionLevel(int level); + int getResolutionLevel() const { return _resolutionLevel; } + +protected: + void clear(); + void allocate(); + + gpu::TexturePointer _linearDepthTexture; gpu::FramebufferPointer _curvatureFramebuffer; gpu::TexturePointer _curvatureTexture; @@ -83,15 +149,15 @@ signals: class SurfaceGeometryPass { public: - using Inputs = render::VaryingSet2; - using Outputs = render::VaryingSet3; + using Inputs = render::VaryingSet3; + using Outputs = render::VaryingSet2; using Config = SurfaceGeometryPassConfig; using JobModel = render::Job::ModelIO; SurfaceGeometryPass(); void configure(const Config& config); - void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& curvatureAndDepth); + void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& outputs); float getCurvatureDepthThreshold() const { return _parametersBuffer.get().curvatureInfo.x; } float getCurvatureBasisScale() const { return _parametersBuffer.get().curvatureInfo.y; } @@ -114,10 +180,8 @@ private: SurfaceGeometryFramebufferPointer _surfaceGeometryFramebuffer; - const gpu::PipelinePointer& getLinearDepthPipeline(); const gpu::PipelinePointer& getCurvaturePipeline(); - gpu::PipelinePointer _linearDepthPipeline; gpu::PipelinePointer _curvaturePipeline; diff --git a/libraries/render-utils/src/surfaceGeometry_makeCurvature.slf b/libraries/render-utils/src/surfaceGeometry_makeCurvature.slf index c5cb12aeb8..552481304f 100644 --- a/libraries/render-utils/src/surfaceGeometry_makeCurvature.slf +++ b/libraries/render-utils/src/surfaceGeometry_makeCurvature.slf @@ -109,6 +109,11 @@ void main(void) { // Fetch the z under the pixel (stereo or not) float Zeye = getZEye(framePixelPos); + if (Zeye <= -getPosLinearDepthFar()) { + // outFragColor = vec4(0.0); + // return; + discard; + } float nearPlaneScale = 0.5 * getProjectionNear(); diff --git a/libraries/render/src/render/BlurTask.cpp b/libraries/render/src/render/BlurTask.cpp index 041d69370a..64f960f957 100644 --- a/libraries/render/src/render/BlurTask.cpp +++ b/libraries/render/src/render/BlurTask.cpp @@ -78,6 +78,14 @@ void BlurParams::setDepthThreshold(float threshold) { } } +void BlurParams::setLinearDepthPosFar(float farPosDepth) { + auto linearDepthInfo = _parametersBuffer.get().linearDepthInfo; + if (farPosDepth != linearDepthInfo.x) { + _parametersBuffer.edit().linearDepthInfo.x = farPosDepth; + } +} + + BlurInOutResource::BlurInOutResource(bool generateOutputFramebuffer) : _generateOutputFramebuffer(generateOutputFramebuffer) { @@ -220,6 +228,7 @@ void BlurGaussian::run(const SceneContextPointer& sceneContext, const RenderCont _parameters->setWidthHeight(args->_viewport.z, args->_viewport.w, args->_context->isStereo()); glm::ivec2 textureSize(blurringResources.sourceTexture->getDimensions()); _parameters->setTexcoordTransform(gpu::Framebuffer::evalSubregionTexcoordTransformCoefficients(textureSize, args->_viewport)); + _parameters->setLinearDepthPosFar(args->getViewFrustum().getFarClip()); gpu::doInBatch(args->_context, [=](gpu::Batch& batch) { batch.enableStereo(false); diff --git a/libraries/render/src/render/BlurTask.h b/libraries/render/src/render/BlurTask.h index 88228d1d86..c6e4e76ca5 100644 --- a/libraries/render/src/render/BlurTask.h +++ b/libraries/render/src/render/BlurTask.h @@ -29,6 +29,8 @@ public: void setDepthPerspective(float oneOverTan2FOV); void setDepthThreshold(float threshold); + void setLinearDepthPosFar(float farPosDepth); + // Class describing the uniform buffer with all the parameters common to the blur shaders class Params { public: @@ -47,6 +49,9 @@ public: // stereo info if blurring a stereo render glm::vec4 stereoInfo{ 0.0f }; + // LinearDepth info is { f } + glm::vec4 linearDepthInfo{ 0.0f }; + Params() {} }; gpu::BufferView _parametersBuffer; diff --git a/libraries/render/src/render/BlurTask.slh b/libraries/render/src/render/BlurTask.slh index c66eaff00b..8ba1126413 100644 --- a/libraries/render/src/render/BlurTask.slh +++ b/libraries/render/src/render/BlurTask.slh @@ -27,6 +27,7 @@ struct BlurParameters { vec4 filterInfo; vec4 depthInfo; vec4 stereoInfo; + vec4 linearDepthInfo; }; uniform blurParamsBuffer { @@ -54,6 +55,10 @@ float getDepthPerspective() { return parameters.depthInfo.w; } +float getPosLinearDepthFar() { + return parameters.linearDepthInfo.x; +} + <@endfunc@> @@ -92,8 +97,12 @@ uniform sampler2D depthMap; vec4 pixelShaderGaussianDepthAware(vec2 texcoord, vec2 direction, vec2 pixelStep) { texcoord = evalTexcoordTransformed(texcoord); - float sampleDepth = texture(depthMap, texcoord).x; + float sampleDepth = -texture(depthMap, texcoord).x; vec4 sampleCenter = texture(sourceMap, texcoord); + if (sampleDepth <= getPosLinearDepthFar()) { + discard; + //return sampleCenter; + } // Calculate the width scale. float distanceToProjectionWindow = getDepthPerspective(); diff --git a/scripts/developer/utilities/render/deferredLighting.qml b/scripts/developer/utilities/render/deferredLighting.qml index 3f1b1ac010..098f101b6d 100644 --- a/scripts/developer/utilities/render/deferredLighting.qml +++ b/scripts/developer/utilities/render/deferredLighting.qml @@ -151,6 +151,7 @@ Column { ListElement { text: "Lighting"; color: "White" } ListElement { text: "Shadow"; color: "White" } ListElement { text: "Linear Depth"; color: "White" } + ListElement { text: "Linear Depth LOD2"; color: "White" } ListElement { text: "Mid Curvature"; color: "White" } ListElement { text: "Mid Normal"; color: "White" } ListElement { text: "Low Curvature"; color: "White" } diff --git a/scripts/developer/utilities/render/statsGPU.qml b/scripts/developer/utilities/render/statsGPU.qml index 7282b753cc..03a17d93a6 100644 --- a/scripts/developer/utilities/render/statsGPU.qml +++ b/scripts/developer/utilities/render/statsGPU.qml @@ -41,9 +41,14 @@ Item { object: Render.getConfig("OpaqueRangeTimer"), prop: "gpuTime", label: "Opaque", - color: "#0000FF" + color: "#FFFFFF" }, { + object: Render.getConfig("LinearDepth"), + prop: "gpuTime", + label: "LinearDepth", + color: "#00FF00" + },{ object: Render.getConfig("SurfaceGeometry"), prop: "gpuTime", label: "SurfaceGeometry",