mirror of
https://github.com/overte-org/overte.git
synced 2025-04-19 15:43:50 +02:00
Factor out SortTask to fix shadows
This commit is contained in:
parent
56aac35348
commit
30fbd99d11
11 changed files with 192 additions and 127 deletions
|
@ -10,27 +10,30 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "RenderDeferredTask.h"
|
||||
|
||||
#include <PerfStat.h>
|
||||
#include <PathUtils.h>
|
||||
#include <RenderArgs.h>
|
||||
#include <ViewFrustum.h>
|
||||
#include <gpu/Context.h>
|
||||
|
||||
#include <render/CullTask.h>
|
||||
#include <render/SortTask.h>
|
||||
#include <render/DrawTask.h>
|
||||
#include <render/DrawStatus.h>
|
||||
#include <render/DrawSceneOctree.h>
|
||||
|
||||
#include "DebugDeferredBuffer.h"
|
||||
#include "DeferredLightingEffect.h"
|
||||
#include "FramebufferCache.h"
|
||||
#include "HitEffect.h"
|
||||
#include "TextureCache.h"
|
||||
|
||||
#include "render/DrawTask.h"
|
||||
#include "render/DrawStatus.h"
|
||||
#include "render/DrawSceneOctree.h"
|
||||
#include "AmbientOcclusionEffect.h"
|
||||
#include "AntialiasingEffect.h"
|
||||
#include "ToneMappingEffect.h"
|
||||
|
||||
#include "RenderDeferredTask.h"
|
||||
|
||||
using namespace render;
|
||||
|
||||
extern void initStencilPipeline(gpu::PipelinePointer& pipeline);
|
||||
|
|
|
@ -12,9 +12,8 @@
|
|||
#ifndef hifi_RenderDeferredTask_h
|
||||
#define hifi_RenderDeferredTask_h
|
||||
|
||||
#include "gpu/Pipeline.h"
|
||||
|
||||
#include "render/DrawTask.h"
|
||||
#include <gpu/Pipeline.h>
|
||||
#include <render/CullTask.h>
|
||||
|
||||
class SetupDeferred {
|
||||
public:
|
||||
|
|
|
@ -9,16 +9,20 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "RenderShadowTask.h"
|
||||
|
||||
#include <gpu/Context.h>
|
||||
|
||||
#include <ViewFrustum.h>
|
||||
|
||||
#include "render/Context.h"
|
||||
#include <render/Context.h>
|
||||
#include <render/CullTask.h>
|
||||
#include <render/SortTask.h>
|
||||
#include <render/DrawTask.h>
|
||||
|
||||
#include "DeferredLightingEffect.h"
|
||||
#include "FramebufferCache.h"
|
||||
|
||||
#include "RenderShadowTask.h"
|
||||
|
||||
#include "model_shadow_vert.h"
|
||||
#include "skin_model_shadow_vert.h"
|
||||
|
||||
|
@ -28,7 +32,7 @@
|
|||
using namespace render;
|
||||
|
||||
void RenderShadowMap::run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext,
|
||||
const render::ShapesIDsBounds& inShapes) {
|
||||
const render::ShapeBounds& inShapes) {
|
||||
assert(renderContext->args);
|
||||
assert(renderContext->args->_viewFrustum);
|
||||
|
||||
|
@ -111,11 +115,11 @@ RenderShadowTask::RenderShadowTask(CullFunctor cullFunctor) : Task(std::make_sha
|
|||
const auto culledShadowSelection = addJob<CullSpatialSelection>("CullShadowSelection", shadowSelection, cullFunctor, RenderDetails::SHADOW, shadowFilter);
|
||||
|
||||
// Sort
|
||||
const auto sortedShapes = addJob<PipelineSortShapes>("PipelineSortShadowSort", culledShadowSelection);
|
||||
const auto shadowShapes = addJob<DepthSortItems>("DepthSortShadowMap", sortedShapes);
|
||||
const auto sortedPipelines = addJob<PipelineSortShapes>("PipelineSortShadowSort", culledShadowSelection);
|
||||
const auto sortedShapes = addJob<DepthSortShapes>("DepthSortShadowMap", sortedPipelines);
|
||||
|
||||
// GPU jobs: Render to shadow map
|
||||
addJob<RenderShadowMap>("RenderShadowMap", shadowShapes, shapePlumber);
|
||||
addJob<RenderShadowMap>("RenderShadowMap", sortedShapes, shapePlumber);
|
||||
}
|
||||
|
||||
void RenderShadowTask::configure(const Config& configuration) {
|
||||
|
|
|
@ -15,17 +15,17 @@
|
|||
#include <gpu/Framebuffer.h>
|
||||
#include <gpu/Pipeline.h>
|
||||
|
||||
#include <render/DrawTask.h>
|
||||
#include <render/CullTask.h>
|
||||
|
||||
class ViewFrustum;
|
||||
|
||||
class RenderShadowMap {
|
||||
public:
|
||||
using JobModel = render::Job::ModelI<RenderShadowMap, render::ShapesIDsBounds>;
|
||||
using JobModel = render::Job::ModelI<RenderShadowMap, render::ShapeBounds>;
|
||||
|
||||
RenderShadowMap(render::ShapePlumberPointer shapePlumber) : _shapePlumber{ shapePlumber } {}
|
||||
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext,
|
||||
const render::ShapesIDsBounds& inShapes);
|
||||
const render::ShapeBounds& inShapes);
|
||||
|
||||
protected:
|
||||
render::ShapePlumberPointer _shapePlumber;
|
||||
|
|
|
@ -62,73 +62,6 @@ void render::cullItems(const RenderContextPointer& renderContext, const CullFunc
|
|||
details._rendered += (int)outItems.size();
|
||||
}
|
||||
|
||||
struct ItemBoundSort {
|
||||
float _centerDepth = 0.0f;
|
||||
float _nearDepth = 0.0f;
|
||||
float _farDepth = 0.0f;
|
||||
ItemID _id = 0;
|
||||
AABox _bounds;
|
||||
|
||||
ItemBoundSort() {}
|
||||
ItemBoundSort(float centerDepth, float nearDepth, float farDepth, ItemID id, const AABox& bounds) : _centerDepth(centerDepth), _nearDepth(nearDepth), _farDepth(farDepth), _id(id), _bounds(bounds) {}
|
||||
};
|
||||
|
||||
struct FrontToBackSort {
|
||||
bool operator() (const ItemBoundSort& left, const ItemBoundSort& right) {
|
||||
return (left._centerDepth < right._centerDepth);
|
||||
}
|
||||
};
|
||||
|
||||
struct BackToFrontSort {
|
||||
bool operator() (const ItemBoundSort& left, const ItemBoundSort& right) {
|
||||
return (left._centerDepth > right._centerDepth);
|
||||
}
|
||||
};
|
||||
|
||||
void render::depthSortItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, bool frontToBack, const ItemBounds& inItems, ItemBounds& outItems) {
|
||||
assert(renderContext->args);
|
||||
assert(renderContext->args->_viewFrustum);
|
||||
|
||||
auto& scene = sceneContext->_scene;
|
||||
RenderArgs* args = renderContext->args;
|
||||
|
||||
|
||||
// Allocate and simply copy
|
||||
outItems.clear();
|
||||
outItems.reserve(inItems.size());
|
||||
|
||||
|
||||
// Make a local dataset of the center distance and closest point distance
|
||||
std::vector<ItemBoundSort> itemBoundSorts;
|
||||
itemBoundSorts.reserve(outItems.size());
|
||||
|
||||
for (auto itemDetails : inItems) {
|
||||
auto item = scene->getItem(itemDetails.id);
|
||||
auto bound = itemDetails.bound; // item.getBound();
|
||||
float distance = args->_viewFrustum->distanceToCamera(bound.calcCenter());
|
||||
|
||||
itemBoundSorts.emplace_back(ItemBoundSort(distance, distance, distance, itemDetails.id, bound));
|
||||
}
|
||||
|
||||
// sort against Z
|
||||
if (frontToBack) {
|
||||
FrontToBackSort frontToBackSort;
|
||||
std::sort(itemBoundSorts.begin(), itemBoundSorts.end(), frontToBackSort);
|
||||
} else {
|
||||
BackToFrontSort backToFrontSort;
|
||||
std::sort(itemBoundSorts.begin(), itemBoundSorts.end(), backToFrontSort);
|
||||
}
|
||||
|
||||
// FInally once sorted result to a list of itemID
|
||||
for (auto& item : itemBoundSorts) {
|
||||
outItems.emplace_back(ItemBound(item._id, item._bounds));
|
||||
}
|
||||
}
|
||||
|
||||
void DepthSortItems::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemBounds& inItems, ItemBounds& outItems) {
|
||||
depthSortItems(sceneContext, renderContext, _frontToBack, inItems, outItems);
|
||||
}
|
||||
|
||||
void FetchNonspatialItems::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, ItemBounds& outItems) {
|
||||
assert(renderContext->args);
|
||||
assert(renderContext->args->_viewFrustum);
|
||||
|
|
|
@ -21,7 +21,6 @@ namespace render {
|
|||
|
||||
void cullItems(const RenderContextPointer& renderContext, const CullFunctor& cullFunctor, RenderDetails::Item& details,
|
||||
const ItemBounds& inItems, ItemBounds& outItems);
|
||||
void depthSortItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, bool frontToBack, const ItemBounds& inItems, ItemBounds& outItems);
|
||||
|
||||
class FetchNonspatialItems {
|
||||
public:
|
||||
|
@ -184,16 +183,6 @@ namespace render {
|
|||
}
|
||||
}
|
||||
};
|
||||
|
||||
class DepthSortItems {
|
||||
public:
|
||||
using JobModel = Job::ModelIO<DepthSortItems, ItemBounds, ItemBounds>;
|
||||
|
||||
bool _frontToBack;
|
||||
DepthSortItems(bool frontToBack = true) : _frontToBack(frontToBack) {}
|
||||
|
||||
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemBounds& inItems, ItemBounds& outItems);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // hifi_render_CullTask_h;
|
|
@ -73,23 +73,3 @@ void DrawLight::run(const SceneContextPointer& sceneContext, const RenderContext
|
|||
args->_batch = nullptr;
|
||||
});
|
||||
}
|
||||
|
||||
void PipelineSortShapes::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemBounds& inItems, ShapesIDsBounds& outShapes) {
|
||||
auto& scene = sceneContext->_scene;
|
||||
outShapes.clear();
|
||||
|
||||
for (const auto& item : inItems) {
|
||||
auto key = scene->getItem(item.id).getShapeKey();
|
||||
auto outItems = outShapes.find(key);
|
||||
if (outItems == outShapes.end()) {
|
||||
outItems = outShapes.insert(std::make_pair(key, ItemBounds{})).first;
|
||||
outItems->second.reserve(inItems.size());
|
||||
}
|
||||
|
||||
outItems->second.push_back(item);
|
||||
}
|
||||
|
||||
for (auto& items : outShapes) {
|
||||
items.second.shrink_to_fit();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,10 +13,6 @@
|
|||
#define hifi_render_DrawTask_h
|
||||
|
||||
#include "Engine.h"
|
||||
#include "CullTask.h"
|
||||
#include "ShapePipeline.h"
|
||||
#include "gpu/Batch.h"
|
||||
|
||||
|
||||
namespace render {
|
||||
|
||||
|
@ -31,12 +27,6 @@ public:
|
|||
protected:
|
||||
};
|
||||
|
||||
class PipelineSortShapes {
|
||||
public:
|
||||
using JobModel = Job::ModelIO<PipelineSortShapes, ItemBounds, ShapesIDsBounds>;
|
||||
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemBounds& inItems, ShapesIDsBounds& outShapes);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // hifi_render_DrawTask_h
|
||||
|
|
|
@ -465,7 +465,7 @@ public:
|
|||
using ItemBounds = std::vector<ItemBound>;
|
||||
|
||||
// A map of items by ShapeKey to optimize rendering pipeline assignments
|
||||
using ShapesIDsBounds = std::unordered_map<ShapeKey, ItemBounds, ShapeKey::Hash, ShapeKey::KeyEqual>;
|
||||
using ShapeBounds = std::unordered_map<ShapeKey, ItemBounds, ShapeKey::Hash, ShapeKey::KeyEqual>;
|
||||
|
||||
}
|
||||
|
||||
|
|
120
libraries/render/src/render/SortTask.cpp
Normal file
120
libraries/render/src/render/SortTask.cpp
Normal file
|
@ -0,0 +1,120 @@
|
|||
//
|
||||
// CullTask.cpp
|
||||
// render/src/render
|
||||
//
|
||||
// Created by Sam Gateau on 2/2/16.
|
||||
// Copyright 2016 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 "SortTask.h"
|
||||
#include "ShapePipeline.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <ViewFrustum.h>
|
||||
|
||||
using namespace render;
|
||||
|
||||
struct ItemBoundSort {
|
||||
float _centerDepth = 0.0f;
|
||||
float _nearDepth = 0.0f;
|
||||
float _farDepth = 0.0f;
|
||||
ItemID _id = 0;
|
||||
AABox _bounds;
|
||||
|
||||
ItemBoundSort() {}
|
||||
ItemBoundSort(float centerDepth, float nearDepth, float farDepth, ItemID id, const AABox& bounds) : _centerDepth(centerDepth), _nearDepth(nearDepth), _farDepth(farDepth), _id(id), _bounds(bounds) {}
|
||||
};
|
||||
|
||||
struct FrontToBackSort {
|
||||
bool operator() (const ItemBoundSort& left, const ItemBoundSort& right) {
|
||||
return (left._centerDepth < right._centerDepth);
|
||||
}
|
||||
};
|
||||
|
||||
struct BackToFrontSort {
|
||||
bool operator() (const ItemBoundSort& left, const ItemBoundSort& right) {
|
||||
return (left._centerDepth > right._centerDepth);
|
||||
}
|
||||
};
|
||||
|
||||
void render::depthSortItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, bool frontToBack, const ItemBounds& inItems, ItemBounds& outItems) {
|
||||
assert(renderContext->args);
|
||||
assert(renderContext->args->_viewFrustum);
|
||||
|
||||
auto& scene = sceneContext->_scene;
|
||||
RenderArgs* args = renderContext->args;
|
||||
|
||||
|
||||
// Allocate and simply copy
|
||||
outItems.clear();
|
||||
outItems.reserve(inItems.size());
|
||||
|
||||
|
||||
// Make a local dataset of the center distance and closest point distance
|
||||
std::vector<ItemBoundSort> itemBoundSorts;
|
||||
itemBoundSorts.reserve(outItems.size());
|
||||
|
||||
for (auto itemDetails : inItems) {
|
||||
auto item = scene->getItem(itemDetails.id);
|
||||
auto bound = itemDetails.bound; // item.getBound();
|
||||
float distance = args->_viewFrustum->distanceToCamera(bound.calcCenter());
|
||||
|
||||
itemBoundSorts.emplace_back(ItemBoundSort(distance, distance, distance, itemDetails.id, bound));
|
||||
}
|
||||
|
||||
// sort against Z
|
||||
if (frontToBack) {
|
||||
FrontToBackSort frontToBackSort;
|
||||
std::sort(itemBoundSorts.begin(), itemBoundSorts.end(), frontToBackSort);
|
||||
} else {
|
||||
BackToFrontSort backToFrontSort;
|
||||
std::sort(itemBoundSorts.begin(), itemBoundSorts.end(), backToFrontSort);
|
||||
}
|
||||
|
||||
// Finally once sorted result to a list of itemID
|
||||
for (auto& item : itemBoundSorts) {
|
||||
outItems.emplace_back(ItemBound(item._id, item._bounds));
|
||||
}
|
||||
}
|
||||
|
||||
void PipelineSortShapes::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemBounds& inItems, ShapeBounds& outShapes) {
|
||||
auto& scene = sceneContext->_scene;
|
||||
outShapes.clear();
|
||||
|
||||
for (const auto& item : inItems) {
|
||||
auto key = scene->getItem(item.id).getShapeKey();
|
||||
auto outItems = outShapes.find(key);
|
||||
if (outItems == outShapes.end()) {
|
||||
outItems = outShapes.insert(std::make_pair(key, ItemBounds{})).first;
|
||||
outItems->second.reserve(inItems.size());
|
||||
}
|
||||
|
||||
outItems->second.push_back(item);
|
||||
}
|
||||
|
||||
for (auto& items : outShapes) {
|
||||
items.second.shrink_to_fit();
|
||||
}
|
||||
}
|
||||
|
||||
void DepthSortShapes::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ShapeBounds& inShapes, ShapeBounds& outShapes) {
|
||||
outShapes.clear();
|
||||
outShapes.reserve(inShapes.size());
|
||||
|
||||
for (auto& pipeline : inShapes) {
|
||||
auto& inItems = pipeline.second;
|
||||
auto outItems = outShapes.find(pipeline.first);
|
||||
if (outItems == outShapes.end()) {
|
||||
outItems = outShapes.insert(std::make_pair(pipeline.first, ItemBounds{})).first;
|
||||
}
|
||||
|
||||
depthSortItems(sceneContext, renderContext, _frontToBack, inItems, outItems->second);
|
||||
}
|
||||
}
|
||||
|
||||
void DepthSortItems::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemBounds& inItems, ItemBounds& outItems) {
|
||||
depthSortItems(sceneContext, renderContext, _frontToBack, inItems, outItems);
|
||||
}
|
47
libraries/render/src/render/SortTask.h
Normal file
47
libraries/render/src/render/SortTask.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
//
|
||||
// SortTask.h
|
||||
// render/src/render
|
||||
//
|
||||
// Created by Zach Pomerantz on 2/26/2016.
|
||||
// Copyright 2016 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_SortTask_h
|
||||
#define hifi_render_SortTask_h
|
||||
|
||||
#include "Engine.h"
|
||||
|
||||
namespace render {
|
||||
void depthSortItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, bool frontToBack, const ItemBounds& inItems, ItemBounds& outItems);
|
||||
|
||||
class PipelineSortShapes {
|
||||
public:
|
||||
using JobModel = Job::ModelIO<PipelineSortShapes, ItemBounds, ShapeBounds>;
|
||||
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemBounds& inItems, ShapeBounds& outShapes);
|
||||
};
|
||||
|
||||
class DepthSortShapes {
|
||||
public:
|
||||
using JobModel = Job::ModelIO<DepthSortShapes, ShapeBounds, ShapeBounds>;
|
||||
|
||||
bool _frontToBack;
|
||||
DepthSortShapes(bool frontToBack = true) : _frontToBack(frontToBack) {}
|
||||
|
||||
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ShapeBounds& inShapes, ShapeBounds& outShapes);
|
||||
};
|
||||
|
||||
class DepthSortItems {
|
||||
public:
|
||||
using JobModel = Job::ModelIO<DepthSortItems, ItemBounds, ItemBounds>;
|
||||
|
||||
bool _frontToBack;
|
||||
DepthSortItems(bool frontToBack = true) : _frontToBack(frontToBack) {}
|
||||
|
||||
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemBounds& inItems, ItemBounds& outItems);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // hifi_render_SortTask_h;
|
Loading…
Reference in a new issue