From 7de6079df89feec5020b7273905fa455de7bb541 Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Tue, 8 Aug 2017 15:28:36 +0200 Subject: [PATCH] Added PrepareOutline job to save outlined zbuffer --- libraries/gpu/src/gpu/Format.cpp | 2 + libraries/gpu/src/gpu/Format.h | 2 + .../render-utils/src/RenderDeferredTask.cpp | 12 +++ libraries/render-utils/src/RenderOutline.cpp | 76 +++++++++++++++++++ libraries/render-utils/src/RenderOutline.h | 53 +++++++++++++ .../src/surfaceGeometry_copyDepth.slf | 20 +++++ 6 files changed, 165 insertions(+) create mode 100644 libraries/render-utils/src/RenderOutline.cpp create mode 100644 libraries/render-utils/src/RenderOutline.h create mode 100644 libraries/render-utils/src/surfaceGeometry_copyDepth.slf diff --git a/libraries/gpu/src/gpu/Format.cpp b/libraries/gpu/src/gpu/Format.cpp index b15f8d929f..4079606286 100644 --- a/libraries/gpu/src/gpu/Format.cpp +++ b/libraries/gpu/src/gpu/Format.cpp @@ -30,6 +30,8 @@ const Element Element::VEC2NU8_XY{ VEC2, NUINT8, XY }; const Element Element::COLOR_R11G11B10{ SCALAR, FLOAT, R11G11B10 }; const Element Element::VEC4F_COLOR_RGBA{ VEC4, FLOAT, RGBA }; +const Element Element::COLOR_RED_FLOAT{ SCALAR, FLOAT, RED }; +const Element Element::COLOR_RED_HALF{ SCALAR, HALF, RED }; const Element Element::VEC2F_UV{ VEC2, FLOAT, UV }; const Element Element::VEC2F_XY{ VEC2, FLOAT, XY }; const Element Element::VEC3F_XYZ{ VEC3, FLOAT, XYZ }; diff --git a/libraries/gpu/src/gpu/Format.h b/libraries/gpu/src/gpu/Format.h index c4d88236da..19965077b5 100644 --- a/libraries/gpu/src/gpu/Format.h +++ b/libraries/gpu/src/gpu/Format.h @@ -314,6 +314,8 @@ public: static const Element COLOR_COMPRESSED_SRGBA_HIGH; static const Element VEC2NU8_XY; static const Element VEC4F_COLOR_RGBA; + static const Element COLOR_RED_FLOAT; + static const Element COLOR_RED_HALF; static const Element VEC2F_UV; static const Element VEC2F_XY; static const Element VEC3F_XYZ; diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 20c999019b..01c111151f 100644 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -39,6 +39,8 @@ #include "AntialiasingEffect.h" #include "ToneMappingEffect.h" #include "SubsurfaceScattering.h" +#include "PickItemsJob.h" +#include "RenderOutline.h" #include @@ -85,6 +87,16 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren // draw a stencil mask in hidden regions of the framebuffer. task.addJob("PrepareStencil", primaryFramebuffer); + // Select items that need to be outlined + const auto outlinedOpaques = task.addJob("PickOutlined", opaques); + + // Render opaque outline objects first in DeferredBuffer + const auto opaqueOutlineInputs = DrawStateSortDeferred::Inputs(outlinedOpaques, lightingModel).hasVarying(); + task.addJob("DrawOpaqueOutlined", opaqueOutlineInputs, shapePlumber); + + // Retrieve z value of the outlined objects + const auto outlinedZBuffer = task.addJob("PrepareOutline", deferredFramebuffer); + // Render opaque objects in DeferredBuffer const auto opaqueInputs = DrawStateSortDeferred::Inputs(opaques, lightingModel).hasVarying(); task.addJob("DrawOpaqueDeferred", opaqueInputs, shapePlumber); diff --git a/libraries/render-utils/src/RenderOutline.cpp b/libraries/render-utils/src/RenderOutline.cpp new file mode 100644 index 0000000000..6ecf86143f --- /dev/null +++ b/libraries/render-utils/src/RenderOutline.cpp @@ -0,0 +1,76 @@ +// +// RenderOutline.cpp +// render-utils/src/ +// +// Created by Olivier Prat on 08/08/17. +// Copyright 2017 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +#include "RenderOutline.h" + +#include "gpu/Context.h" +#include "gpu/StandardShaderLib.h" + +#include "surfaceGeometry_copyDepth_frag.h" + +void PrepareOutline::run(const render::RenderContextPointer& renderContext, const PrepareOutline::Input& deferredFramebuffer, PrepareOutline::Output& output) { + glm::uvec2 frameSize(renderContext->args->_viewport.z, renderContext->args->_viewport.w); + auto args = renderContext->args; + + // Resizing framebuffers instead of re-building them seems to cause issues with threaded + // rendering + if (_outlineFramebuffer && _outlineFramebuffer->getSize() != frameSize) { + _outlineFramebuffer.reset(); + } + + if (!_outlineFramebuffer) { + _outlineFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("deferredOutline")); + auto colorFormat = gpu::Element::COLOR_RED_HALF; + + auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT); + auto primaryColorTexture = gpu::Texture::createRenderBuffer(colorFormat, frameSize.x, frameSize.y, gpu::Texture::SINGLE_MIP, defaultSampler); + + _outlineFramebuffer->setRenderBuffer(0, primaryColorTexture); + } + + if (!_copyDepthPipeline) { + auto vs = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS(); + auto ps = gpu::Shader::createPixel(std::string(surfaceGeometry_copyDepth_frag)); + gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps); + + gpu::Shader::BindingSet slotBindings; + slotBindings.insert(gpu::Shader::Binding(std::string("depthMap"), 0)); + gpu::Shader::makeProgram(*program, slotBindings); + + gpu::StatePointer state = gpu::StatePointer(new gpu::State()); + + state->setColorWriteMask(true, false, false, false); + + // Good to go add the brand new pipeline + _copyDepthPipeline = gpu::Pipeline::create(program, state); + } + + gpu::doInBatch(args->_context, [&](gpu::Batch& batch) { + auto depthBuffer = deferredFramebuffer->getPrimaryDepthTexture(); + + // Copy depth to texture as we will overwrite + batch.enableStereo(false); + + batch.setViewportTransform(args->_viewport); + batch.setProjectionTransform(glm::mat4()); + batch.resetViewTransform(); + batch.setModelTransform(gpu::Framebuffer::evalSubregionTexcoordTransform(frameSize, args->_viewport)); + + batch.setFramebuffer(_outlineFramebuffer); + batch.setPipeline(_copyDepthPipeline); + batch.setResourceTexture(0, depthBuffer); + batch.draw(gpu::TRIANGLE_STRIP, 4); + + // Restore previous frame buffer + batch.setFramebuffer(deferredFramebuffer->getDeferredFramebuffer()); + }); + + output = _outlineFramebuffer->getRenderBuffer(0); +} diff --git a/libraries/render-utils/src/RenderOutline.h b/libraries/render-utils/src/RenderOutline.h new file mode 100644 index 0000000000..a97f2033ef --- /dev/null +++ b/libraries/render-utils/src/RenderOutline.h @@ -0,0 +1,53 @@ +// +// RenderOutline.h +// render-utils/src/ +// +// Created by Olivier Prat on 08/08/17. +// Copyright 2017 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_render_utils_RenderOutline_h +#define hifi_render_utils_RenderOutline_h + +#include +#include "DeferredFramebuffer.h" + +/* +class PickItemsConfig : public render::Job::Config { + Q_OBJECT + Q_PROPERTY(bool isEnabled MEMBER isEnabled NOTIFY dirty) + +public: + + bool isEnabled{ false }; + +signals: + + void dirty(); +}; +*/ +class PrepareOutline { + +public: + + using Input = DeferredFramebufferPointer; + // Output will contain outlined objects only z-depth texture + using Output = gpu::TexturePointer; + using JobModel = render::Job::ModelIO; + + PrepareOutline() {} + + void run(const render::RenderContextPointer& renderContext, const PrepareOutline::Input& input, PrepareOutline::Output& output); + +private: + + gpu::FramebufferPointer _outlineFramebuffer; + gpu::PipelinePointer _copyDepthPipeline; +}; + +#endif // hifi_render_utils_RenderOutline_h + + diff --git a/libraries/render-utils/src/surfaceGeometry_copyDepth.slf b/libraries/render-utils/src/surfaceGeometry_copyDepth.slf new file mode 100644 index 0000000000..9db8cdbb01 --- /dev/null +++ b/libraries/render-utils/src/surfaceGeometry_copyDepth.slf @@ -0,0 +1,20 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// Created by Olivier Prat on 08/08/17. +// Copyright 2017 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +uniform sampler2D depthMap; + +out vec4 outFragColor; + +void main(void) { + float Zdb = texelFetch(depthMap, ivec2(gl_FragCoord.xy), 0).x; + outFragColor = vec4(Zdb, 0.0, 0.0, 1.0); +} +