diff --git a/libraries/render-utils/src/DebugDeferredBuffer.cpp b/libraries/render-utils/src/DebugDeferredBuffer.cpp index 73aa614233..3a8e6a822c 100644 --- a/libraries/render-utils/src/DebugDeferredBuffer.cpp +++ b/libraries/render-utils/src/DebugDeferredBuffer.cpp @@ -46,7 +46,9 @@ enum Slot { Depth, Lighting, Shadow, - Pyramid, + LinearDepth, + HalfLinearDepth, + HalfNormal, Curvature, DiffusedCurvature, Scattering, @@ -141,16 +143,21 @@ static const std::string DEFAULT_SHADOW_SHADER { " }" }; -static const std::string DEFAULT_PYRAMID_DEPTH_SHADER { +static const std::string DEFAULT_LINEAR_DEPTH_SHADER { "vec4 getFragmentColor() {" - " return vec4(vec3(1.0 - texture(pyramidMap, uv).x * 0.01), 1.0);" + " return vec4(vec3(1.0 - texture(linearDepthMap, uv).x * 0.01), 1.0);" " }" }; -static const std::string DEFAULT_LINEAR_DEPTH_2_SHADER{ +static const std::string DEFAULT_HALF_LINEAR_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, 1).x * 0.01), 1.0);" + " return vec4(vec3(1.0 - texture(halfLinearDepthMap, uv).x * 0.01), 1.0);" + " }" +}; + +static const std::string DEFAULT_HALF_NORMAL_SHADER{ + "vec4 getFragmentColor() {" + " return vec4(vec3(texture(halfNormalMap, uv).xyz), 1.0);" " }" }; @@ -259,9 +266,11 @@ std::string DebugDeferredBuffer::getShaderSourceCode(Mode mode, std::string cust case ShadowMode: return DEFAULT_SHADOW_SHADER; case LinearDepthMode: - return DEFAULT_PYRAMID_DEPTH_SHADER; - case LinearDepth2Mode: - return DEFAULT_LINEAR_DEPTH_2_SHADER; + return DEFAULT_LINEAR_DEPTH_SHADER; + case HalfLinearDepthMode: + return DEFAULT_HALF_LINEAR_DEPTH_SHADER; + case HalfNormalMode: + return DEFAULT_HALF_NORMAL_SHADER; case CurvatureMode: return DEFAULT_CURVATURE_SHADER; case NormalCurvatureMode: @@ -325,7 +334,9 @@ const gpu::PipelinePointer& DebugDeferredBuffer::getPipeline(Mode mode, std::str slotBindings.insert(gpu::Shader::Binding("obscuranceMap", AmbientOcclusion)); slotBindings.insert(gpu::Shader::Binding("lightingMap", Lighting)); slotBindings.insert(gpu::Shader::Binding("shadowMap", Shadow)); - slotBindings.insert(gpu::Shader::Binding("pyramidMap", Pyramid)); + slotBindings.insert(gpu::Shader::Binding("linearDepthMap", LinearDepth)); + slotBindings.insert(gpu::Shader::Binding("halfLinearDepthMap", HalfLinearDepth)); + slotBindings.insert(gpu::Shader::Binding("halfNormalMap", HalfNormal)); slotBindings.insert(gpu::Shader::Binding("curvatureMap", Curvature)); slotBindings.insert(gpu::Shader::Binding("diffusedCurvatureMap", DiffusedCurvature)); slotBindings.insert(gpu::Shader::Binding("scatteringMap", Scattering)); @@ -364,8 +375,9 @@ void DebugDeferredBuffer::run(const SceneContextPointer& sceneContext, const Ren RenderArgs* args = renderContext->args; auto& deferredFramebuffer = inputs.get0(); - auto& surfaceGeometryFramebuffer = inputs.get1(); - auto& diffusedCurvatureFramebuffer = inputs.get2(); + auto& linearDepthTarget = inputs.get1(); + auto& surfaceGeometryFramebuffer = inputs.get2(); + auto& diffusedCurvatureFramebuffer = inputs.get3(); gpu::doInBatch(args->_context, [&](gpu::Batch& batch) { batch.enableStereo(false); @@ -395,7 +407,10 @@ void DebugDeferredBuffer::run(const SceneContextPointer& sceneContext, const Ren batch.setResourceTexture(Depth, deferredFramebuffer->getPrimaryDepthTexture()); batch.setResourceTexture(Lighting, deferredFramebuffer->getLightingTexture()); batch.setResourceTexture(Shadow, lightStage.lights[0]->shadow.framebuffer->getDepthStencilBuffer()); - batch.setResourceTexture(Pyramid, surfaceGeometryFramebuffer->getLinearDepthTexture()); + batch.setResourceTexture(LinearDepth, linearDepthTarget->getLinearDepthTexture()); + batch.setResourceTexture(HalfLinearDepth, linearDepthTarget->getHalfLinearDepthTexture()); + batch.setResourceTexture(HalfNormal, linearDepthTarget->getHalfNormalTexture()); + batch.setResourceTexture(Curvature, surfaceGeometryFramebuffer->getCurvatureTexture()); batch.setResourceTexture(DiffusedCurvature, diffusedCurvatureFramebuffer->getRenderBuffer(0)); if (DependencyManager::get()->isAmbientOcclusionEnabled()) { diff --git a/libraries/render-utils/src/DebugDeferredBuffer.h b/libraries/render-utils/src/DebugDeferredBuffer.h index 2f919930d3..d6005de349 100644 --- a/libraries/render-utils/src/DebugDeferredBuffer.h +++ b/libraries/render-utils/src/DebugDeferredBuffer.h @@ -36,7 +36,7 @@ signals: class DebugDeferredBuffer { public: - using Inputs = render::VaryingSet3; + using Inputs = render::VaryingSet4; using Config = DebugDeferredBufferConfig; using JobModel = render::Job::ModelI; @@ -64,7 +64,8 @@ protected: LightingMode, ShadowMode, LinearDepthMode, - LinearDepth2Mode, + HalfLinearDepthMode, + HalfNormalMode, CurvatureMode, NormalCurvatureMode, DiffusedCurvatureMode, diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 76e5f56714..343e9fbed0 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -125,6 +125,8 @@ RenderDeferredTask::RenderDeferredTask(CullFunctor cullFunctor) { const auto linearDepthPassOutputs = addJob("LinearDepth", linearDepthPassInputs); const auto linearDepthTarget = linearDepthPassOutputs.getN(0); const auto linearDepthTexture = linearDepthPassOutputs.getN(2); + const auto halfLinearDepthTexture = linearDepthPassOutputs.getN(3); + const auto halfNormalTexture = linearDepthPassOutputs.getN(4); // Curvature pass @@ -136,7 +138,7 @@ RenderDeferredTask::RenderDeferredTask(CullFunctor cullFunctor) { 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(); + const auto diffuseCurvaturePassInputs = BlurGaussianDepthAware::Inputs(curvatureFramebuffer, halfLinearDepthTexture).hasVarying(); const auto midCurvatureNormalFramebuffer = addJob("DiffuseCurvatureMid", diffuseCurvaturePassInputs); const auto lowCurvatureNormalFramebuffer = addJob("DiffuseCurvatureLow", diffuseCurvaturePassInputs, true); // THis blur pass generates it s render resource @@ -182,7 +184,7 @@ RenderDeferredTask::RenderDeferredTask(CullFunctor cullFunctor) { addJob("DebugScattering", deferredLightingInputs); // Debugging Deferred buffer job - const auto debugFramebuffers = render::Varying(DebugDeferredBuffer::Inputs(deferredFramebuffer, surfaceGeometryFramebuffer, lowCurvatureNormalFramebuffer)); + const auto debugFramebuffers = render::Varying(DebugDeferredBuffer::Inputs(deferredFramebuffer, linearDepthTarget, surfaceGeometryFramebuffer, lowCurvatureNormalFramebuffer)); addJob("DebugDeferredBuffer", debugFramebuffers); // Scene Octree Debuging job diff --git a/libraries/render-utils/src/SurfaceGeometryPass.cpp b/libraries/render-utils/src/SurfaceGeometryPass.cpp index d34d9108d4..57b0b7e08d 100644 --- a/libraries/render-utils/src/SurfaceGeometryPass.cpp +++ b/libraries/render-utils/src/SurfaceGeometryPass.cpp @@ -18,6 +18,7 @@ const int DepthLinearPass_FrameTransformSlot = 0; const int DepthLinearPass_DepthMapSlot = 0; +const int DepthLinearPass_NormalMapSlot = 1; const int SurfaceGeometryPass_FrameTransformSlot = 0; const int SurfaceGeometryPass_ParamsSlot = 1; @@ -25,6 +26,7 @@ const int SurfaceGeometryPass_DepthMapSlot = 0; const int SurfaceGeometryPass_NormalMapSlot = 1; #include "surfaceGeometry_makeLinearDepth_frag.h" +#include "surfaceGeometry_downsampleDepthNormal_frag.h" #include "surfaceGeometry_makeCurvature_frag.h" @@ -45,6 +47,8 @@ void LinearDepthFramebuffer::updatePrimaryDepth(const gpu::TexturePointer& depth auto newFrameSize = glm::ivec2(_primaryDepthTexture->getDimensions()); if (_frameSize != newFrameSize) { _frameSize = newFrameSize; + _halfFrameSize = newFrameSize >> 1; + reset = true; } } @@ -67,10 +71,21 @@ void LinearDepthFramebuffer::allocate() { // 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); + // _linearDepthTexture->autoGenerateMips(1); _linearDepthFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create()); _linearDepthFramebuffer->setRenderBuffer(0, _linearDepthTexture); _linearDepthFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, _primaryDepthTexture->getTexelFormat()); + + // For Downsampling: + _halfLinearDepthTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::RGB), _halfFrameSize.x, _halfFrameSize.y, + gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); + + _halfNormalTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::VEC3, gpu::NUINT8, gpu::RGB), _halfFrameSize.x, _halfFrameSize.y, + gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); + + _downsampleFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create()); + _downsampleFramebuffer->setRenderBuffer(0, _halfLinearDepthTexture); + _downsampleFramebuffer->setRenderBuffer(1, _halfNormalTexture); } gpu::FramebufferPointer LinearDepthFramebuffer::getLinearDepthFramebuffer() { @@ -87,6 +102,27 @@ gpu::TexturePointer LinearDepthFramebuffer::getLinearDepthTexture() { return _linearDepthTexture; } +gpu::FramebufferPointer LinearDepthFramebuffer::getDownsampleFramebuffer() { + if (!_downsampleFramebuffer) { + allocate(); + } + return _downsampleFramebuffer; +} + +gpu::TexturePointer LinearDepthFramebuffer::getHalfLinearDepthTexture() { + if (!_halfLinearDepthTexture) { + allocate(); + } + return _halfLinearDepthTexture; +} + +gpu::TexturePointer LinearDepthFramebuffer::getHalfNormalTexture() { + if (!_halfNormalTexture) { + allocate(); + } + return _halfNormalTexture; +} + LinearDepthPass::LinearDepthPass() { } @@ -114,13 +150,21 @@ void LinearDepthPass::run(const render::SceneContextPointer& sceneContext, const auto linearDepthFBO = _linearDepthFramebuffer->getLinearDepthFramebuffer(); auto linearDepthTexture = _linearDepthFramebuffer->getLinearDepthTexture(); + auto downsampleFBO = _linearDepthFramebuffer->getDownsampleFramebuffer(); + auto halfLinearDepthTexture = _linearDepthFramebuffer->getHalfLinearDepthTexture(); + auto halfNormalTexture = _linearDepthFramebuffer->getHalfNormalTexture(); + outputs.edit0() = _linearDepthFramebuffer; outputs.edit1() = linearDepthFBO; outputs.edit2() = linearDepthTexture; - + outputs.edit3() = halfLinearDepthTexture; + outputs.edit4() = halfNormalTexture; + auto linearDepthPipeline = getLinearDepthPipeline(); + auto downsamplePipeline = getDownsamplePipeline(); auto depthViewport = args->_viewport; + auto halfViewport = depthViewport >> 1; auto furtherDepth = std::numeric_limits::infinity(); furtherDepth = args->getViewFrustum().getFarClip() + 10.0; @@ -135,15 +179,21 @@ void LinearDepthPass::run(const render::SceneContextPointer& sceneContext, const batch.setUniformBuffer(DepthLinearPass_FrameTransformSlot, frameTransform->getFrameTransformBuffer()); - // Pyramid pass + // LinearDepth 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)); + // Downsample + batch.setViewportTransform(halfViewport); + + batch.setFramebuffer(downsampleFBO); + batch.setResourceTexture(DepthLinearPass_DepthMapSlot, linearDepthTexture); + batch.setResourceTexture(DepthLinearPass_NormalMapSlot, normalTexture); + batch.setPipeline(downsamplePipeline); + batch.draw(gpu::TRIANGLE_STRIP, 4); _gpuTimer.end(batch); }); @@ -180,6 +230,32 @@ const gpu::PipelinePointer& LinearDepthPass::getLinearDepthPipeline() { } +const gpu::PipelinePointer& LinearDepthPass::getDownsamplePipeline() { + if (!_downsamplePipeline) { + auto vs = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS(); + auto ps = gpu::Shader::createPixel(std::string(surfaceGeometry_downsampleDepthNormal_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("linearDepthMap"), DepthLinearPass_DepthMapSlot)); + slotBindings.insert(gpu::Shader::Binding(std::string("normalMap"), DepthLinearPass_NormalMapSlot)); + gpu::Shader::makeProgram(*program, slotBindings); + + + gpu::StatePointer state = gpu::StatePointer(new gpu::State()); + + state->setColorWriteMask(true, true, true, false); + + // Good to go add the brand new pipeline + _downsamplePipeline = gpu::Pipeline::create(program, state); + } + + return _downsamplePipeline; +} + + +//#define USE_STENCIL_TEST SurfaceGeometryFramebuffer::SurfaceGeometryFramebuffer() { } @@ -280,19 +356,22 @@ void SurfaceGeometryPass::run(const render::SceneContextPointer& sceneContext, c const auto deferredFramebuffer = inputs.get1(); const auto linearDepthFramebuffer = inputs.get2(); - auto linearDepthTexture = linearDepthFramebuffer->getLinearDepthTexture(); + auto linearDepthTexture = linearDepthFramebuffer->getHalfLinearDepthTexture(); if (!_surfaceGeometryFramebuffer) { _surfaceGeometryFramebuffer = std::make_shared(); } _surfaceGeometryFramebuffer->updateLinearDepth(linearDepthTexture); - auto normalTexture = deferredFramebuffer->getDeferredNormalTexture(); + // auto normalTexture = deferredFramebuffer->getDeferredNormalTexture(); + auto normalTexture = linearDepthFramebuffer->getHalfNormalTexture(); auto curvatureFBO = _surfaceGeometryFramebuffer->getCurvatureFramebuffer(); +#ifdef USE_STENCIL_TEST if (curvatureFBO->getDepthStencilBuffer() != deferredFramebuffer->getPrimaryDepthTexture()) { curvatureFBO->setDepthStencilBuffer(deferredFramebuffer->getPrimaryDepthTexture(), deferredFramebuffer->getPrimaryDepthTexture()->getTexelFormat()); } +#endif auto curvatureTexture = _surfaceGeometryFramebuffer->getCurvatureTexture(); outputs.edit0() = _surfaceGeometryFramebuffer; @@ -301,7 +380,8 @@ void SurfaceGeometryPass::run(const render::SceneContextPointer& sceneContext, c auto curvaturePipeline = getCurvaturePipeline(); auto depthViewport = args->_viewport; - auto curvatureViewport = depthViewport >> _surfaceGeometryFramebuffer->getResolutionLevel(); + auto curvatureViewport = depthViewport >> 1; + // >> _surfaceGeometryFramebuffer->getResolutionLevel(); gpu::doInBatch(args->_context, [=](gpu::Batch& batch) { _gpuTimer.begin(batch); @@ -318,9 +398,13 @@ void SurfaceGeometryPass::run(const render::SceneContextPointer& sceneContext, c // Curvature pass batch.setFramebuffer(curvatureFBO); - - // We can avoid the clear by drawing the same clear vallue from the makeCUrvature shader. slightly better than adding the clear - // batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(0.0)); + + // We can avoid the clear by drawing the same clear vallue from the makeCurvature shader. same performances or no worse + +#ifdef USE_STENCIL_TEST + // Except if stenciling out + batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(0.0)); +#endif batch.setPipeline(curvaturePipeline); batch.setResourceTexture(SurfaceGeometryPass_DepthMapSlot, linearDepthTexture); @@ -354,9 +438,10 @@ const gpu::PipelinePointer& SurfaceGeometryPass::getCurvaturePipeline() { gpu::StatePointer state = gpu::StatePointer(new gpu::State()); +#ifdef USE_STENCIL_TEST // 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)); - +#endif // Good to go add the brand new pipeline _curvaturePipeline = gpu::Pipeline::create(program, state); } diff --git a/libraries/render-utils/src/SurfaceGeometryPass.h b/libraries/render-utils/src/SurfaceGeometryPass.h index 8137deda35..5b9b64a11c 100644 --- a/libraries/render-utils/src/SurfaceGeometryPass.h +++ b/libraries/render-utils/src/SurfaceGeometryPass.h @@ -28,6 +28,10 @@ public: gpu::FramebufferPointer getLinearDepthFramebuffer(); gpu::TexturePointer getLinearDepthTexture(); + gpu::FramebufferPointer getDownsampleFramebuffer(); + gpu::TexturePointer getHalfLinearDepthTexture(); + gpu::TexturePointer getHalfNormalTexture(); + // 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(); @@ -44,8 +48,14 @@ protected: gpu::FramebufferPointer _linearDepthFramebuffer; gpu::TexturePointer _linearDepthTexture; + + gpu::FramebufferPointer _downsampleFramebuffer; + gpu::TexturePointer _halfLinearDepthTexture; + gpu::TexturePointer _halfNormalTexture; + glm::ivec2 _frameSize; + glm::ivec2 _halfFrameSize; int _resolutionLevel{ 0 }; }; @@ -69,7 +79,7 @@ signals: class LinearDepthPass { public: using Inputs = render::VaryingSet2; - using Outputs = render::VaryingSet3; + using Outputs = render::VaryingSet5; using Config = LinearDepthPassConfig; using JobModel = render::Job::ModelIO; @@ -84,9 +94,11 @@ private: LinearDepthFramebufferPointer _linearDepthFramebuffer; const gpu::PipelinePointer& getLinearDepthPipeline(); - gpu::PipelinePointer _linearDepthPipeline; + const gpu::PipelinePointer& getDownsamplePipeline(); + gpu::PipelinePointer _downsamplePipeline; + gpu::RangeTimer _gpuTimer; }; diff --git a/libraries/render-utils/src/debug_deferred_buffer.slf b/libraries/render-utils/src/debug_deferred_buffer.slf index 4b8e8d48ce..079f79c06e 100644 --- a/libraries/render-utils/src/debug_deferred_buffer.slf +++ b/libraries/render-utils/src/debug_deferred_buffer.slf @@ -14,7 +14,9 @@ <@include DeferredBufferRead.slh@> -uniform sampler2D pyramidMap; +uniform sampler2D linearDepthMap; +uniform sampler2D halfLinearDepthMap; +uniform sampler2D halfNormalMap; uniform sampler2D occlusionMap; uniform sampler2D occlusionBlurredMap; uniform sampler2D curvatureMap; diff --git a/libraries/render-utils/src/surfaceGeometry_makeCurvature.slf b/libraries/render-utils/src/surfaceGeometry_makeCurvature.slf index bb3a073a2e..09836f2ab0 100644 --- a/libraries/render-utils/src/surfaceGeometry_makeCurvature.slf +++ b/libraries/render-utils/src/surfaceGeometry_makeCurvature.slf @@ -78,8 +78,10 @@ vec3 getRawNormal(vec2 texcoord) { } vec3 getWorldNormal(vec2 texcoord) { + // vec3 rawNormal = getRawNormal(texcoord); + // return unpackNormal(rawNormal); vec3 rawNormal = getRawNormal(texcoord); - return unpackNormal(rawNormal); + return normalize((rawNormal - vec3(0.5)) * 2.0); } vec3 getWorldNormalDiff(vec2 texcoord, vec2 delta) { diff --git a/libraries/render/src/render/BlurTask.cpp b/libraries/render/src/render/BlurTask.cpp index 4a3118d0d3..597df37b7a 100644 --- a/libraries/render/src/render/BlurTask.cpp +++ b/libraries/render/src/render/BlurTask.cpp @@ -101,9 +101,9 @@ bool BlurInOutResource::updateResources(const gpu::FramebufferPointer& sourceFra _blurredFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create()); // attach depthStencil if present in source - if (sourceFramebuffer->hasDepthStencil()) { - _blurredFramebuffer->setDepthStencilBuffer(sourceFramebuffer->getDepthStencilBuffer(), sourceFramebuffer->getDepthStencilBufferFormat()); - } + //if (sourceFramebuffer->hasDepthStencil()) { + // _blurredFramebuffer->setDepthStencilBuffer(sourceFramebuffer->getDepthStencilBuffer(), sourceFramebuffer->getDepthStencilBufferFormat()); + //} auto blurringSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT); auto blurringTarget = gpu::TexturePointer(gpu::Texture::create2D(sourceFramebuffer->getRenderBuffer(0)->getTexelFormat(), sourceFramebuffer->getWidth(), sourceFramebuffer->getHeight(), blurringSampler)); _blurredFramebuffer->setRenderBuffer(0, blurringTarget); @@ -111,9 +111,9 @@ bool BlurInOutResource::updateResources(const gpu::FramebufferPointer& sourceFra // it would be easier to just call resize on the bluredFramebuffer and let it work if needed but the source might loose it's depth buffer when doing so if ((_blurredFramebuffer->getWidth() != sourceFramebuffer->getWidth()) || (_blurredFramebuffer->getHeight() != sourceFramebuffer->getHeight())) { _blurredFramebuffer->resize(sourceFramebuffer->getWidth(), sourceFramebuffer->getHeight(), sourceFramebuffer->getNumSamples()); - if (sourceFramebuffer->hasDepthStencil()) { - _blurredFramebuffer->setDepthStencilBuffer(sourceFramebuffer->getDepthStencilBuffer(), sourceFramebuffer->getDepthStencilBufferFormat()); - } + //if (sourceFramebuffer->hasDepthStencil()) { + // _blurredFramebuffer->setDepthStencilBuffer(sourceFramebuffer->getDepthStencilBuffer(), sourceFramebuffer->getDepthStencilBufferFormat()); + //} } } @@ -128,18 +128,18 @@ bool BlurInOutResource::updateResources(const gpu::FramebufferPointer& sourceFra _outputFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create()); // attach depthStencil if present in source - if (sourceFramebuffer->hasDepthStencil()) { + /* if (sourceFramebuffer->hasDepthStencil()) { _outputFramebuffer->setDepthStencilBuffer(sourceFramebuffer->getDepthStencilBuffer(), sourceFramebuffer->getDepthStencilBufferFormat()); - } + }*/ auto blurringSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT); auto blurringTarget = gpu::TexturePointer(gpu::Texture::create2D(sourceFramebuffer->getRenderBuffer(0)->getTexelFormat(), sourceFramebuffer->getWidth(), sourceFramebuffer->getHeight(), blurringSampler)); _outputFramebuffer->setRenderBuffer(0, blurringTarget); } else { if ((_outputFramebuffer->getWidth() != sourceFramebuffer->getWidth()) || (_outputFramebuffer->getHeight() != sourceFramebuffer->getHeight())) { _outputFramebuffer->resize(sourceFramebuffer->getWidth(), sourceFramebuffer->getHeight(), sourceFramebuffer->getNumSamples()); - if (sourceFramebuffer->hasDepthStencil()) { + /* if (sourceFramebuffer->hasDepthStencil()) { _outputFramebuffer->setDepthStencilBuffer(sourceFramebuffer->getDepthStencilBuffer(), sourceFramebuffer->getDepthStencilBufferFormat()); - } + }*/ } } @@ -173,7 +173,7 @@ gpu::PipelinePointer BlurGaussian::getBlurVPipeline() { 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->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)); _blurVPipeline = gpu::Pipeline::create(program, state); } @@ -195,7 +195,7 @@ gpu::PipelinePointer BlurGaussian::getBlurHPipeline() { 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->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)); _blurHPipeline = gpu::Pipeline::create(program, state); } @@ -336,22 +336,25 @@ void BlurGaussianDepthAware::run(const SceneContextPointer& sceneContext, const auto blurVPipeline = getBlurVPipeline(); auto blurHPipeline = getBlurHPipeline(); - _parameters->setWidthHeight(args->_viewport.z, args->_viewport.w, args->_context->isStereo()); + auto sourceViewport = args->_viewport; + auto blurViewport = sourceViewport >> 1; + + _parameters->setWidthHeight(blurViewport.z, blurViewport.w, args->_context->isStereo()); glm::ivec2 textureSize(blurringResources.sourceTexture->getDimensions()); - _parameters->setTexcoordTransform(gpu::Framebuffer::evalSubregionTexcoordTransformCoefficients(textureSize, args->_viewport)); + _parameters->setTexcoordTransform(gpu::Framebuffer::evalSubregionTexcoordTransformCoefficients(textureSize, blurViewport)); _parameters->setDepthPerspective(args->getViewFrustum().getProjection()[1][1]); _parameters->setLinearDepthPosFar(args->getViewFrustum().getFarClip()); gpu::doInBatch(args->_context, [=](gpu::Batch& batch) { batch.enableStereo(false); - batch.setViewportTransform(args->_viewport); + batch.setViewportTransform(blurViewport); batch.setUniformBuffer(BlurTask_ParamsSlot, _parameters->_parametersBuffer); batch.setResourceTexture(BlurTask_DepthSlot, depthTexture); batch.setFramebuffer(blurringResources.blurringFramebuffer); - batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(0.0)); + // batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(0.0)); batch.setPipeline(blurVPipeline); batch.setResourceTexture(BlurTask_SourceSlot, blurringResources.sourceTexture); @@ -359,7 +362,7 @@ void BlurGaussianDepthAware::run(const SceneContextPointer& sceneContext, const batch.setFramebuffer(blurringResources.finalFramebuffer); if (_inOutResources._generateOutputFramebuffer) { - batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(0.0)); + // batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(0.0)); } batch.setPipeline(blurHPipeline); diff --git a/libraries/render/src/render/BlurTask.slh b/libraries/render/src/render/BlurTask.slh index de40740c19..d40aca4a76 100644 --- a/libraries/render/src/render/BlurTask.slh +++ b/libraries/render/src/render/BlurTask.slh @@ -95,14 +95,22 @@ vec4 pixelShaderGaussian(vec2 texcoord, vec2 direction, vec2 pixelStep) { uniform sampler2D sourceMap; uniform sampler2D depthMap; +#define NUM_HALF_TAPS 4 + +const float gaussianDistributionCurveHalf[NUM_HALF_TAPS] = float[]( + 0.383f, 0.242f, 0.061f, 0.006f +); +const float gaussianDistributionOffsetHalf[NUM_HALF_TAPS] = float[]( + 0.0f, 1.0f, 2.0f, 3.0f +); + vec4 pixelShaderGaussianDepthAware(vec2 texcoord, vec2 direction, vec2 pixelStep) { texcoord = evalTexcoordTransformed(texcoord); float sampleDepth = texture(depthMap, texcoord).x; - vec4 sampleCenter = texture(sourceMap, texcoord); if (sampleDepth >= getPosLinearDepthFar()) { discard; - //return sampleCenter; } + vec4 sampleCenter = texture(sourceMap, texcoord); // Calculate the width scale. float distanceToProjectionWindow = getDepthPerspective(); @@ -117,21 +125,40 @@ vec4 pixelShaderGaussianDepthAware(vec2 texcoord, vec2 direction, vec2 pixelStep // Accumulate the center sample vec4 srcBlurred = gaussianDistributionCurve[0] * sampleCenter; - - for(int i = 1; i < NUM_TAPS; i++) { + +/* for(int i = 1; i < NUM_TAPS; i++) { // Fetch color and depth for current sample. vec2 sampleCoord = texcoord + (gaussianDistributionOffset[i] * finalStep); float srcDepth = texture(depthMap, sampleCoord).x; vec4 srcSample = texture(sourceMap, sampleCoord); - - + // If the difference in depth is huge, we lerp color back. float s = clamp(depthThreshold * distanceToProjectionWindow * filterScale * abs(srcDepth - sampleDepth), 0.0, 1.0); - // float s = clamp(depthThreshold * distanceToProjectionWindow * filterScale * abs(srcDepth - sampleDepth), 0.0, 1.0); srcSample = mix(srcSample, sampleCenter, s); // Accumulate. srcBlurred += gaussianDistributionCurve[i] * srcSample; + } +*/ + + for(int i = 1; i < NUM_HALF_TAPS; i++) { + // Fetch color and depth for current sample. + vec2 texcoordOffset = (gaussianDistributionOffsetHalf[i] * finalStep); + + float srcDepthN = texture(depthMap, texcoord - texcoordOffset).x; + float srcDepthP = texture(depthMap, texcoord + texcoordOffset).x; + vec4 srcSampleN = texture(sourceMap, texcoord - texcoordOffset); + vec4 srcSampleP = texture(sourceMap, texcoord + texcoordOffset); + + // If the difference in depth is huge, we lerp color back. + float sN = clamp(depthThreshold * distanceToProjectionWindow * filterScale * abs(srcDepthN - sampleDepth), 0.0, 1.0); + float sP = clamp(depthThreshold * distanceToProjectionWindow * filterScale * abs(srcDepthP - sampleDepth), 0.0, 1.0); + + srcSampleN = mix(srcSampleN, sampleCenter, sN); + srcSampleP = mix(srcSampleP, sampleCenter, sP); + + // Accumulate. + srcBlurred += gaussianDistributionCurveHalf[i] * (srcSampleP + srcSampleN); } return srcBlurred; diff --git a/libraries/render/src/render/Task.h b/libraries/render/src/render/Task.h index d5b41e539e..8268090997 100644 --- a/libraries/render/src/render/Task.h +++ b/libraries/render/src/render/Task.h @@ -206,6 +206,21 @@ public: const T4& get4() const { return std::get<4>((*this)).template get(); } T4& edit4() { return std::get<4>((*this)).template edit(); } + virtual Varying operator[] (uint8_t index) const { + if (index == 4) { + return std::get<4>((*this)); + } else if (index == 3) { + return std::get<3>((*this)); + } else if (index == 2) { + return std::get<2>((*this)); + } else if (index == 1) { + return std::get<1>((*this)); + } else { + return std::get<0>((*this)); + } + } + virtual uint8_t length() const { return 5; } + Varying hasVarying() const { return Varying((*this)); } }; diff --git a/scripts/developer/utilities/render/deferredLighting.qml b/scripts/developer/utilities/render/deferredLighting.qml index 098f101b6d..12f21ed366 100644 --- a/scripts/developer/utilities/render/deferredLighting.qml +++ b/scripts/developer/utilities/render/deferredLighting.qml @@ -151,7 +151,8 @@ 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: "Half Linear Depth"; color: "White" } + ListElement { text: "Half Normal"; color: "White" } ListElement { text: "Mid Curvature"; color: "White" } ListElement { text: "Mid Normal"; color: "White" } ListElement { text: "Low Curvature"; color: "White" }