Working with specific zpass rendering for outline. Debug script needs relinking to correct config

This commit is contained in:
Olivier Prat 2017-09-06 18:40:38 +02:00
parent d6ea01c4f3
commit 10643feb78
7 changed files with 175 additions and 73 deletions

View file

@ -13,8 +13,7 @@
#include "GeometryCache.h"
#include <render/FilterTask.h>
#include "RenderDeferredTask.h"
#include <render/SortTask.h>
#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<ShapeKey> 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<Inputs>();
const auto selectedMetas = inputs.getN<Inputs>(0);
const auto shapePlumber = input.get1();
const auto lightingModel = inputs.getN<Inputs>(2);
const auto deferredFramebuffer = inputs.getN<Inputs>(3);
const auto primaryFramebuffer = inputs.getN<Inputs>(4);
const auto deferredFrameTransform = inputs.getN<Inputs>(5);
const auto deferredFramebuffer = inputs.getN<Inputs>(2);
const auto primaryFramebuffer = inputs.getN<Inputs>(3);
const auto deferredFrameTransform = inputs.getN<Inputs>(4);
const auto& outlinedItems = task.addJob<render::MetaToSubItems>("OutlinedMetaToSubItems", selectedMetas);
// Prepare the ShapePipeline
ShapePlumberPointer shapePlumberZPass = std::make_shared<ShapePlumber>();
{
auto state = std::make_shared<gpu::State>();
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<DrawStateSortDeferred>("DrawOutlinedDepth", outlineInputs, shapePlumber);
initZPassPipelines(*shapePlumberZPass, state);
}
const auto& outlinedItemIDs = task.addJob<render::MetaToSubItems>("MetaToSubItemIDs", selectedMetas);
const auto& outlinedItems = task.addJob<render::IDsToBounds>("MetaToSubItems", outlinedItemIDs, true);
// Sort
const auto& sortedPipelines = task.addJob<render::PipelineSortShapes>("PipelineSort", outlinedItems);
const auto& sortedShapes = task.addJob<render::DepthSortShapes>("DepthSort", sortedPipelines);
task.addJob<DrawOutlineDepth>("Depth", sortedShapes, shapePlumberZPass);
// Retrieve z value of the outlined objects
const auto outlinePrepareInputs = PrepareOutline::Inputs(outlinedItems, deferredFramebuffer).asVarying();
const auto outlinedFrameBuffer = task.addJob<PrepareOutline>("CopyOutlineDepth", outlinePrepareInputs);
const auto outlinedFrameBuffer = task.addJob<PrepareOutline>("CopyDepth", outlinePrepareInputs);
// Draw outline
const auto drawOutlineInputs = DrawOutline::Inputs(deferredFrameTransform, deferredFramebuffer, outlinedFrameBuffer, primaryFramebuffer).asVarying();
task.addJob<DrawOutline>("DrawOutlineEffect", drawOutlineInputs);
task.addJob<DrawOutline>("Effect", drawOutlineInputs);
// Debug outline
task.addJob<DebugOutline>("DebugOutline", outlinedFrameBuffer);
task.addJob<DebugOutline>("Debug", outlinedFrameBuffer);
}

View file

@ -165,11 +165,21 @@ private:
bool _isDisplayDepthEnabled{ false };
};
#include "LightingModel.h"
class DrawOutlineDepth {
public:
using JobModel = render::Job::ModelI<DrawOutlineDepth, render::ShapeBounds>;
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<render::ItemBounds, render::ShapePlumberPointer, LightingModelPointer, DeferredFramebufferPointer, gpu::FramebufferPointer, DeferredFrameTransformPointer>;
using Inputs = render::VaryingSet5<render::ItemBounds, render::ShapePlumberPointer, DeferredFramebufferPointer, gpu::FramebufferPointer, DeferredFrameTransformPointer>;
using Config = render::Task::Config;
using JobModel = render::Task::ModelI<DrawOutlineTask, Inputs, Config>;

View file

@ -166,7 +166,7 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
const auto toneMappingInputs = ToneMappingDeferred::Inputs(lightingFramebuffer, primaryFramebuffer).asVarying();
task.addJob<ToneMappingDeferred>("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<DrawOutlineTask>("DrawOutline", outlineInputs);
{ // DEbug the bounds of the rendered items, still look at the zbuffer

View file

@ -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);
}

View file

@ -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<RenderShadowSetup>("ShadowSetup");

View file

@ -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 });
}
}
}

View file

@ -135,11 +135,24 @@ namespace render {
// From meta-Items, generate the sub-items
class MetaToSubItems {
public:
using JobModel = Job::ModelIO<MetaToSubItems, ItemBounds, ItemBounds>;
using JobModel = Job::ModelIO<MetaToSubItems, ItemBounds, ItemIDs>;
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, ItemIDs, ItemBounds>;
IDsToBounds(bool disableAABBs = false) : _disableAABBs(disableAABBs) {}
void run(const RenderContextPointer& renderContext, const ItemIDs& inItems, ItemBounds& outItems);
private:
bool _disableAABBs{ false };
};
}