From 10643feb7859543042773cd420110f34c95dfac1 Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Wed, 6 Sep 2017 18:40:38 +0200 Subject: [PATCH] Working with specific zpass rendering for outline. Debug script needs relinking to correct config --- libraries/render-utils/src/OutlineEffect.cpp | 95 ++++++++++++++++--- libraries/render-utils/src/OutlineEffect.h | 14 ++- .../render-utils/src/RenderDeferredTask.cpp | 2 +- .../render-utils/src/RenderPipelines.cpp | 48 ++++++++-- .../render-utils/src/RenderShadowTask.cpp | 42 +------- libraries/render/src/render/FilterTask.cpp | 30 ++++-- libraries/render/src/render/FilterTask.h | 17 +++- 7 files changed, 175 insertions(+), 73 deletions(-) diff --git a/libraries/render-utils/src/OutlineEffect.cpp b/libraries/render-utils/src/OutlineEffect.cpp index a99ced93f0..3876a87c02 100644 --- a/libraries/render-utils/src/OutlineEffect.cpp +++ b/libraries/render-utils/src/OutlineEffect.cpp @@ -13,8 +13,7 @@ #include "GeometryCache.h" #include - -#include "RenderDeferredTask.h" +#include #include "gpu/Context.h" #include "gpu/StandardShaderLib.h" @@ -24,6 +23,10 @@ #include "debug_deferred_buffer_frag.h" #include "Outline_frag.h" +using namespace render; + +extern void initZPassPipelines(ShapePlumber& plumber, gpu::StatePointer state); + OutlineFramebuffer::OutlineFramebuffer() { } @@ -299,6 +302,61 @@ const gpu::PipelinePointer& DebugOutline::getDebugPipeline() { return _debugPipeline; } +void DrawOutlineDepth::run(const render::RenderContextPointer& renderContext, const render::ShapeBounds& inShapes) { + assert(renderContext->args); + assert(renderContext->args->hasViewFrustum()); + + RenderArgs* args = renderContext->args; + ShapeKey::Builder defaultKeyBuilder; + + gpu::doInBatch(args->_context, [&](gpu::Batch& batch) { + args->_batch = &batch; + + // Setup camera, projection and viewport for all items + batch.setViewportTransform(args->_viewport); + batch.setStateScissorRect(args->_viewport); + + glm::mat4 projMat; + Transform viewMat; + args->getViewFrustum().evalProjectionMatrix(projMat); + args->getViewFrustum().evalViewTransform(viewMat); + + batch.setProjectionTransform(projMat); + batch.setViewTransform(viewMat); + + batch.clearFramebuffer( + gpu::Framebuffer::BUFFER_DEPTH, + vec4(vec3(1.0, 1.0, 1.0), 0.0), 1.0, 0, true); + + auto shadowPipeline = _shapePlumber->pickPipeline(args, defaultKeyBuilder); + auto shadowSkinnedPipeline = _shapePlumber->pickPipeline(args, defaultKeyBuilder.withSkinned()); + + std::vector skinnedShapeKeys{}; + + // Iterate through all inShapes and render the unskinned + args->_shapePipeline = shadowPipeline; + batch.setPipeline(shadowPipeline->pipeline); + for (auto items : inShapes) { + if (items.first.isSkinned()) { + skinnedShapeKeys.push_back(items.first); + } + else { + renderItems(renderContext, items.second); + } + } + + // Reiterate to render the skinned + args->_shapePipeline = shadowSkinnedPipeline; + batch.setPipeline(shadowSkinnedPipeline->pipeline); + for (const auto& key : skinnedShapeKeys) { + renderItems(renderContext, inShapes.at(key)); + } + + args->_shapePipeline = nullptr; + args->_batch = nullptr; + }); +} + DrawOutlineTask::DrawOutlineTask() { } @@ -311,25 +369,36 @@ void DrawOutlineTask::build(JobModel& task, const render::Varying& inputs, rende const auto input = inputs.get(); const auto selectedMetas = inputs.getN(0); const auto shapePlumber = input.get1(); - const auto lightingModel = inputs.getN(2); - const auto deferredFramebuffer = inputs.getN(3); - const auto primaryFramebuffer = inputs.getN(4); - const auto deferredFrameTransform = inputs.getN(5); + const auto deferredFramebuffer = inputs.getN(2); + const auto primaryFramebuffer = inputs.getN(3); + const auto deferredFrameTransform = inputs.getN(4); - const auto& outlinedItems = task.addJob("OutlinedMetaToSubItems", selectedMetas); + // Prepare the ShapePipeline + ShapePlumberPointer shapePlumberZPass = std::make_shared(); + { + auto state = std::make_shared(); + state->setDepthTest(true, true, gpu::LESS_EQUAL); + state->setColorWriteMask(0); - // Render opaque outline objects first in DeferredBuffer - const auto outlineInputs = DrawStateSortDeferred::Inputs(outlinedItems, lightingModel).asVarying(); - task.addJob("DrawOutlinedDepth", outlineInputs, shapePlumber); + initZPassPipelines(*shapePlumberZPass, state); + } + + const auto& outlinedItemIDs = task.addJob("MetaToSubItemIDs", selectedMetas); + const auto& outlinedItems = task.addJob("MetaToSubItems", outlinedItemIDs, true); + + // Sort + const auto& sortedPipelines = task.addJob("PipelineSort", outlinedItems); + const auto& sortedShapes = task.addJob("DepthSort", sortedPipelines); + task.addJob("Depth", sortedShapes, shapePlumberZPass); // Retrieve z value of the outlined objects const auto outlinePrepareInputs = PrepareOutline::Inputs(outlinedItems, deferredFramebuffer).asVarying(); - const auto outlinedFrameBuffer = task.addJob("CopyOutlineDepth", outlinePrepareInputs); + const auto outlinedFrameBuffer = task.addJob("CopyDepth", outlinePrepareInputs); // Draw outline const auto drawOutlineInputs = DrawOutline::Inputs(deferredFrameTransform, deferredFramebuffer, outlinedFrameBuffer, primaryFramebuffer).asVarying(); - task.addJob("DrawOutlineEffect", drawOutlineInputs); + task.addJob("Effect", drawOutlineInputs); // Debug outline - task.addJob("DebugOutline", outlinedFrameBuffer); + task.addJob("Debug", outlinedFrameBuffer); } diff --git a/libraries/render-utils/src/OutlineEffect.h b/libraries/render-utils/src/OutlineEffect.h index ccc1e03fdd..a0e1823a56 100644 --- a/libraries/render-utils/src/OutlineEffect.h +++ b/libraries/render-utils/src/OutlineEffect.h @@ -165,11 +165,21 @@ private: bool _isDisplayDepthEnabled{ false }; }; -#include "LightingModel.h" +class DrawOutlineDepth { +public: + using JobModel = render::Job::ModelI; + + DrawOutlineDepth(render::ShapePlumberPointer shapePlumber) : _shapePlumber{ shapePlumber } {} + void run(const render::RenderContextPointer& renderContext, + const render::ShapeBounds& inShapes); + +protected: + render::ShapePlumberPointer _shapePlumber; +}; class DrawOutlineTask { public: - using Inputs = render::VaryingSet6; + using Inputs = render::VaryingSet5; using Config = render::Task::Config; using JobModel = render::Task::ModelI; diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 5ea506e18f..d396377969 100644 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -166,7 +166,7 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren const auto toneMappingInputs = ToneMappingDeferred::Inputs(lightingFramebuffer, primaryFramebuffer).asVarying(); task.addJob("ToneMapping", toneMappingInputs); - const auto outlineInputs = DrawOutlineTask::Inputs(selectedMetas, shapePlumber, lightingModel, deferredFramebuffer, primaryFramebuffer, deferredFrameTransform).asVarying(); + const auto outlineInputs = DrawOutlineTask::Inputs(selectedMetas, shapePlumber, deferredFramebuffer, primaryFramebuffer, deferredFrameTransform).asVarying(); task.addJob("DrawOutline", outlineInputs); { // DEbug the bounds of the rendered items, still look at the zbuffer diff --git a/libraries/render-utils/src/RenderPipelines.cpp b/libraries/render-utils/src/RenderPipelines.cpp index 0353e10407..7f644add72 100644 --- a/libraries/render-utils/src/RenderPipelines.cpp +++ b/libraries/render-utils/src/RenderPipelines.cpp @@ -21,19 +21,15 @@ #include "render/DrawTask.h" #include "model_vert.h" -#include "model_shadow_vert.h" #include "model_normal_map_vert.h" #include "model_lightmap_vert.h" #include "model_lightmap_normal_map_vert.h" #include "skin_model_vert.h" -#include "skin_model_shadow_vert.h" #include "skin_model_normal_map_vert.h" -#include "model_shadow_fade_vert.h" #include "model_lightmap_fade_vert.h" #include "model_lightmap_normal_map_fade_vert.h" #include "skin_model_fade_vert.h" -#include "skin_model_shadow_fade_vert.h" #include "skin_model_normal_map_fade_vert.h" #include "simple_vert.h" @@ -50,7 +46,6 @@ #include "model_frag.h" #include "model_unlit_frag.h" -#include "model_shadow_frag.h" #include "model_normal_map_frag.h" #include "model_normal_specular_map_frag.h" #include "model_specular_map_frag.h" @@ -59,7 +54,6 @@ #include "model_normal_map_fade_vert.h" #include "model_fade_frag.h" -#include "model_shadow_fade_frag.h" #include "model_unlit_fade_frag.h" #include "model_normal_map_fade_frag.h" #include "model_normal_specular_map_fade_frag.h" @@ -95,6 +89,17 @@ #include "overlay3D_model_unlit_frag.h" #include "overlay3D_model_translucent_unlit_frag.h" +#include "model_shadow_vert.h" +#include "skin_model_shadow_vert.h" + +#include "model_shadow_frag.h" +#include "skin_model_shadow_frag.h" + +#include "model_shadow_fade_vert.h" +#include "skin_model_shadow_fade_vert.h" + +#include "model_shadow_fade_frag.h" +#include "skin_model_shadow_fade_frag.h" using namespace render; using namespace std::placeholders; @@ -102,6 +107,7 @@ using namespace std::placeholders; void initOverlay3DPipelines(ShapePlumber& plumber, bool depthTest = false); void initDeferredPipelines(ShapePlumber& plumber, const render::ShapePipeline::BatchSetter& batchSetter, const render::ShapePipeline::ItemSetter& itemSetter); void initForwardPipelines(ShapePlumber& plumber); +void initZPassPipelines(ShapePlumber& plumber, gpu::StatePointer state); void addPlumberPipeline(ShapePlumber& plumber, const ShapeKey& key, const gpu::ShaderPointer& vertex, const gpu::ShaderPointer& pixel, @@ -566,3 +572,33 @@ void lightBatchSetter(const ShapePipeline& pipeline, gpu::Batch& batch, RenderAr pipeline.locations->lightAmbientMapUnit); } } + +void initZPassPipelines(ShapePlumber& shapePlumber, gpu::StatePointer state) { + auto modelVertex = gpu::Shader::createVertex(std::string(model_shadow_vert)); + auto modelPixel = gpu::Shader::createPixel(std::string(model_shadow_frag)); + gpu::ShaderPointer modelProgram = gpu::Shader::createProgram(modelVertex, modelPixel); + shapePlumber.addPipeline( + ShapeKey::Filter::Builder().withoutSkinned().withoutFade(), + modelProgram, state); + + auto skinVertex = gpu::Shader::createVertex(std::string(skin_model_shadow_vert)); + auto skinPixel = gpu::Shader::createPixel(std::string(skin_model_shadow_frag)); + gpu::ShaderPointer skinProgram = gpu::Shader::createProgram(skinVertex, skinPixel); + shapePlumber.addPipeline( + ShapeKey::Filter::Builder().withSkinned().withoutFade(), + skinProgram, state); + + auto modelFadeVertex = gpu::Shader::createVertex(std::string(model_shadow_fade_vert)); + auto modelFadePixel = gpu::Shader::createPixel(std::string(model_shadow_fade_frag)); + gpu::ShaderPointer modelFadeProgram = gpu::Shader::createProgram(modelFadeVertex, modelFadePixel); + shapePlumber.addPipeline( + ShapeKey::Filter::Builder().withoutSkinned().withFade(), + modelFadeProgram, state); + + auto skinFadeVertex = gpu::Shader::createVertex(std::string(skin_model_shadow_fade_vert)); + auto skinFadePixel = gpu::Shader::createPixel(std::string(skin_model_shadow_fade_frag)); + gpu::ShaderPointer skinFadeProgram = gpu::Shader::createProgram(skinFadeVertex, skinFadePixel); + shapePlumber.addPipeline( + ShapeKey::Filter::Builder().withSkinned().withFade(), + skinFadeProgram, state); +} diff --git a/libraries/render-utils/src/RenderShadowTask.cpp b/libraries/render-utils/src/RenderShadowTask.cpp index ac80c03873..d32857bc65 100644 --- a/libraries/render-utils/src/RenderShadowTask.cpp +++ b/libraries/render-utils/src/RenderShadowTask.cpp @@ -22,20 +22,10 @@ #include "DeferredLightingEffect.h" #include "FramebufferCache.h" -#include "model_shadow_vert.h" -#include "skin_model_shadow_vert.h" - -#include "model_shadow_frag.h" -#include "skin_model_shadow_frag.h" - -#include "model_shadow_fade_vert.h" -#include "skin_model_shadow_fade_vert.h" - -#include "model_shadow_fade_frag.h" -#include "skin_model_shadow_fade_frag.h" - using namespace render; +extern void initZPassPipelines(ShapePlumber& plumber, gpu::StatePointer state); + void RenderShadowMap::run(const render::RenderContextPointer& renderContext, const render::ShapeBounds& inShapes) { assert(renderContext->args); @@ -108,33 +98,7 @@ void RenderShadowTask::build(JobModel& task, const render::Varying& input, rende state->setCullMode(gpu::State::CULL_BACK); state->setDepthTest(true, true, gpu::LESS_EQUAL); - auto modelVertex = gpu::Shader::createVertex(std::string(model_shadow_vert)); - auto modelPixel = gpu::Shader::createPixel(std::string(model_shadow_frag)); - gpu::ShaderPointer modelProgram = gpu::Shader::createProgram(modelVertex, modelPixel); - shapePlumber->addPipeline( - ShapeKey::Filter::Builder().withoutSkinned().withoutFade(), - modelProgram, state); - - auto skinVertex = gpu::Shader::createVertex(std::string(skin_model_shadow_vert)); - auto skinPixel = gpu::Shader::createPixel(std::string(skin_model_shadow_frag)); - gpu::ShaderPointer skinProgram = gpu::Shader::createProgram(skinVertex, skinPixel); - shapePlumber->addPipeline( - ShapeKey::Filter::Builder().withSkinned().withoutFade(), - skinProgram, state); - - auto modelFadeVertex = gpu::Shader::createVertex(std::string(model_shadow_fade_vert)); - auto modelFadePixel = gpu::Shader::createPixel(std::string(model_shadow_fade_frag)); - gpu::ShaderPointer modelFadeProgram = gpu::Shader::createProgram(modelFadeVertex, modelFadePixel); - shapePlumber->addPipeline( - ShapeKey::Filter::Builder().withoutSkinned().withFade(), - modelFadeProgram, state); - - auto skinFadeVertex = gpu::Shader::createVertex(std::string(skin_model_shadow_fade_vert)); - auto skinFadePixel = gpu::Shader::createPixel(std::string(skin_model_shadow_fade_frag)); - gpu::ShaderPointer skinFadeProgram = gpu::Shader::createProgram(skinFadeVertex, skinFadePixel); - shapePlumber->addPipeline( - ShapeKey::Filter::Builder().withSkinned().withFade(), - skinFadeProgram, state); + initZPassPipelines(*shapePlumber, state); } const auto cachedMode = task.addJob("ShadowSetup"); diff --git a/libraries/render/src/render/FilterTask.cpp b/libraries/render/src/render/FilterTask.cpp index b4da280697..39bc19adc7 100644 --- a/libraries/render/src/render/FilterTask.cpp +++ b/libraries/render/src/render/FilterTask.cpp @@ -98,9 +98,8 @@ void SelectSortItems::run(const RenderContextPointer& renderContext, const ItemB } } -void MetaToSubItems::run(const RenderContextPointer& renderContext, const ItemBounds& inItems, ItemBounds& outItems) { +void MetaToSubItems::run(const RenderContextPointer& renderContext, const ItemBounds& inItems, ItemIDs& outItems) { auto& scene = renderContext->_scene; - ItemIDs outItemIds; // Now we have a selection of items to render outItems.clear(); @@ -108,14 +107,25 @@ void MetaToSubItems::run(const RenderContextPointer& renderContext, const ItemBo for (auto idBound : inItems) { auto& item = scene->getItem(idBound.id); - item.fetchMetaSubItems(outItemIds); - } - - // Transform Item IDs to ItemBounds - for (auto id : outItemIds) { - auto& item = scene->getItem(id); - - outItems.emplace_back(ItemBound{ id, item.getBound() }); + item.fetchMetaSubItems(outItems); } } +void IDsToBounds::run(const RenderContextPointer& renderContext, const ItemIDs& inItems, ItemBounds& outItems) { + auto& scene = renderContext->_scene; + + // Now we have a selection of items to render + outItems.clear(); + + if (!_disableAABBs) { + for (auto id : inItems) { + auto& item = scene->getItem(id); + + outItems.emplace_back(ItemBound{ id, item.getBound() }); + } + } else { + for (auto id : inItems) { + outItems.emplace_back(ItemBound{ id }); + } + } +} diff --git a/libraries/render/src/render/FilterTask.h b/libraries/render/src/render/FilterTask.h index b9b02017da..2f8b53722f 100644 --- a/libraries/render/src/render/FilterTask.h +++ b/libraries/render/src/render/FilterTask.h @@ -135,11 +135,24 @@ namespace render { // From meta-Items, generate the sub-items class MetaToSubItems { public: - using JobModel = Job::ModelIO; + using JobModel = Job::ModelIO; MetaToSubItems() {} - void run(const RenderContextPointer& renderContext, const ItemBounds& inItems, ItemBounds& outItems); + void run(const RenderContextPointer& renderContext, const ItemBounds& inItems, ItemIDs& outItems); + }; + + // From item IDs build item bounds + class IDsToBounds { + public: + using JobModel = Job::ModelIO; + + IDsToBounds(bool disableAABBs = false) : _disableAABBs(disableAABBs) {} + + void run(const RenderContextPointer& renderContext, const ItemIDs& inItems, ItemBounds& outItems); + + private: + bool _disableAABBs{ false }; }; }