From 110adc5c227e983e880ad69882895e6e802d4054 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Mon, 19 Oct 2015 15:21:25 -0700 Subject: [PATCH 1/2] fix model LOD behavior --- interface/resources/qml/Stats.qml | 24 ++++++++++++++++--- interface/src/LODManager.cpp | 14 ++++++++--- interface/src/ui/Stats.cpp | 8 +++++-- interface/src/ui/Stats.h | 16 +++++++++---- .../render-utils/src/MeshPartPayload.cpp | 8 +++---- libraries/render-utils/src/MeshPartPayload.h | 3 --- .../render-utils/src/RenderDeferredTask.cpp | 6 +++-- libraries/render/src/render/DrawTask.cpp | 23 +++++++++++++++++- libraries/render/src/render/DrawTask.h | 22 ++++++++++++++++- 9 files changed, 100 insertions(+), 24 deletions(-) diff --git a/interface/resources/qml/Stats.qml b/interface/resources/qml/Stats.qml index 780f9cb89f..c98d4741b0 100644 --- a/interface/resources/qml/Stats.qml +++ b/interface/resources/qml/Stats.qml @@ -181,15 +181,33 @@ Item { color: root.fontColor; font.pixelSize: root.fontSize visible: root.expanded; - text: "\tMesh Parts Rendered Opaque: " + root.meshOpaque + - " / Translucent: " + root.meshTranslucent; + text: "\tItems Rendered Opaque: " + root.opaqueRendered + + " / Translucent: " + root.translucentRendered + + " / Other: " + root.otherRendered; } Text { color: root.fontColor; font.pixelSize: root.fontSize visible: root.expanded; text: "\tOpaque considered: " + root.opaqueConsidered + - " / Out of view: " + root.opaqueOutOfView + " / Too small: " + root.opaqueTooSmall; + " / Out of view: " + root.opaqueOutOfView + + " / Too small: " + root.opaqueTooSmall; + } + Text { + color: root.fontColor; + font.pixelSize: root.fontSize + visible: root.expanded; + text: "\tTranslucent considered: " + root.translucentConsidered + + " / Out of view: " + root.translucentOutOfView + + " / Too small: " + root.translucentTooSmall; + } + Text { + color: root.fontColor; + font.pixelSize: root.fontSize + visible: root.expanded; + text: "\tOther considered: " + root.otherConsidered + + " / Out of view: " + root.otherOutOfView + + " / Too small: " + root.otherTooSmall; } Text { color: root.fontColor; diff --git a/interface/src/LODManager.cpp b/interface/src/LODManager.cpp index 2a2edef831..0d2681ac72 100644 --- a/interface/src/LODManager.cpp +++ b/interface/src/LODManager.cpp @@ -229,7 +229,8 @@ bool LODManager::shouldRender(const RenderArgs* args, const AABox& bounds) { static bool shouldRenderTableNeedsBuilding = true; static QMap shouldRenderTable; if (shouldRenderTableNeedsBuilding) { - + qDebug() << "LODManager::shouldRender() rebuilding table!"; + float SMALLEST_SCALE_IN_TABLE = 0.001f; // 1mm is plenty small float scale = maxScale; float factor = 1.0f; @@ -254,8 +255,15 @@ bool LODManager::shouldRender(const RenderArgs* args, const AABox& bounds) { if (closestScale < largestDimension) { visibleDistanceAtClosestScale *= 2.0f; } - - return distanceToCamera <= visibleDistanceAtClosestScale; + + bool result = distanceToCamera <= visibleDistanceAtClosestScale; + + /* + qDebug() << "LODManager::shouldRender() bounds:" << bounds << "result:" << result + << "distanceToCamera:" << distanceToCamera << "visibleDistanceAtClosestScale:" << visibleDistanceAtClosestScale; + */ + + return result; }; // TODO: This is essentially the same logic used to render octree cells, but since models are more detailed then octree cells diff --git a/interface/src/ui/Stats.cpp b/interface/src/ui/Stats.cpp index 7e2143c454..1c0c03e16c 100644 --- a/interface/src/ui/Stats.cpp +++ b/interface/src/ui/Stats.cpp @@ -342,14 +342,18 @@ void Stats::setRenderDetails(const RenderDetails& details) { STAT_UPDATE(triangles, details._trianglesRendered); STAT_UPDATE(materialSwitches, details._materialSwitches); if (_expanded) { - STAT_UPDATE(meshOpaque, details._opaque._rendered); - STAT_UPDATE(meshTranslucent, details._opaque._rendered); STAT_UPDATE(opaqueConsidered, details._opaque._considered); STAT_UPDATE(opaqueOutOfView, details._opaque._outOfView); STAT_UPDATE(opaqueTooSmall, details._opaque._tooSmall); + STAT_UPDATE(opaqueRendered, details._opaque._rendered); STAT_UPDATE(translucentConsidered, details._translucent._considered); STAT_UPDATE(translucentOutOfView, details._translucent._outOfView); STAT_UPDATE(translucentTooSmall, details._translucent._tooSmall); + STAT_UPDATE(translucentRendered, details._translucent._rendered); + STAT_UPDATE(otherConsidered, details._other._considered); + STAT_UPDATE(otherOutOfView, details._other._outOfView); + STAT_UPDATE(otherTooSmall, details._other._tooSmall); + STAT_UPDATE(otherRendered, details._other._rendered); } } diff --git a/interface/src/ui/Stats.h b/interface/src/ui/Stats.h index f1426a9e37..39e3c6b24a 100644 --- a/interface/src/ui/Stats.h +++ b/interface/src/ui/Stats.h @@ -58,14 +58,18 @@ class Stats : public QQuickItem { STATS_PROPERTY(int, triangles, 0) STATS_PROPERTY(int, quads, 0) STATS_PROPERTY(int, materialSwitches, 0) - STATS_PROPERTY(int, meshOpaque, 0) - STATS_PROPERTY(int, meshTranslucent, 0) STATS_PROPERTY(int, opaqueConsidered, 0) STATS_PROPERTY(int, opaqueOutOfView, 0) STATS_PROPERTY(int, opaqueTooSmall, 0) + STATS_PROPERTY(int, opaqueRendered, 0) STATS_PROPERTY(int, translucentConsidered, 0) STATS_PROPERTY(int, translucentOutOfView, 0) STATS_PROPERTY(int, translucentTooSmall, 0) + STATS_PROPERTY(int, translucentRendered, 0) + STATS_PROPERTY(int, otherConsidered, 0) + STATS_PROPERTY(int, otherOutOfView, 0) + STATS_PROPERTY(int, otherTooSmall, 0) + STATS_PROPERTY(int, otherRendered, 0) STATS_PROPERTY(QString, sendingMode, QString()) STATS_PROPERTY(QString, packetStats, QString()) STATS_PROPERTY(QString, lodStatus, QString()) @@ -135,14 +139,18 @@ signals: void trianglesChanged(); void quadsChanged(); void materialSwitchesChanged(); - void meshOpaqueChanged(); - void meshTranslucentChanged(); void opaqueConsideredChanged(); void opaqueOutOfViewChanged(); void opaqueTooSmallChanged(); + void opaqueRenderedChanged(); void translucentConsideredChanged(); void translucentOutOfViewChanged(); void translucentTooSmallChanged(); + void translucentRenderedChanged(); + void otherConsideredChanged(); + void otherOutOfViewChanged(); + void otherTooSmallChanged(); + void otherRenderedChanged(); void sendingModeChanged(); void packetStatsChanged(); void lodStatusChanged(); diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp index 54b0bacf6e..80327b7e54 100644 --- a/libraries/render-utils/src/MeshPartPayload.cpp +++ b/libraries/render-utils/src/MeshPartPayload.cpp @@ -89,11 +89,9 @@ render::ItemKey MeshPartPayload::getKey() const { } render::Item::Bound MeshPartPayload::getBound() const { - if (_isBoundInvalid) { - model->getPartBounds(meshIndex, partIndex); - _isBoundInvalid = false; - } - return _bound; + // NOTE: we can't cache this bounds because we need to handle the case of a moving + // entity or mesh part. + return model->getPartBounds(meshIndex, partIndex); } void MeshPartPayload::drawCall(gpu::Batch& batch) const { diff --git a/libraries/render-utils/src/MeshPartPayload.h b/libraries/render-utils/src/MeshPartPayload.h index 7e476445e6..51e577e7c7 100644 --- a/libraries/render-utils/src/MeshPartPayload.h +++ b/libraries/render-utils/src/MeshPartPayload.h @@ -55,9 +55,6 @@ public: bool _hasColorAttrib = false; bool _isSkinned = false; bool _isBlendShaped = false; - - mutable render::Item::Bound _bound; - mutable bool _isBoundInvalid = true; }; namespace render { diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index df062e3fa9..845c96372c 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -76,7 +76,7 @@ RenderDeferredTask::RenderDeferredTask() : Task() { } ) ))); - _jobs.push_back(Job(new CullItems::JobModel("CullOpaque", _jobs.back().getOutput()))); + _jobs.push_back(Job(new CullItemsOpaque::JobModel("CullOpaque", _jobs.back().getOutput()))); _jobs.push_back(Job(new DepthSortItems::JobModel("DepthSortOpaque", _jobs.back().getOutput()))); auto& renderedOpaques = _jobs.back().getOutput(); _jobs.push_back(Job(new DrawOpaqueDeferred::JobModel("DrawOpaqueDeferred", _jobs.back().getOutput()))); @@ -105,7 +105,9 @@ RenderDeferredTask::RenderDeferredTask() : Task() { } ) ))); - _jobs.push_back(Job(new CullItems::JobModel("CullTransparent", _jobs.back().getOutput()))); + _jobs.push_back(Job(new CullItemsTransparent::JobModel("CullTransparent", _jobs.back().getOutput()))); + + _jobs.push_back(Job(new DepthSortItems::JobModel("DepthSortTransparent", _jobs.back().getOutput(), DepthSortItems(false)))); _jobs.push_back(Job(new DrawTransparentDeferred::JobModel("TransparentDeferred", _jobs.back().getOutput()))); diff --git a/libraries/render/src/render/DrawTask.cpp b/libraries/render/src/render/DrawTask.cpp index e2c4c5f747..877567aecd 100755 --- a/libraries/render/src/render/DrawTask.cpp +++ b/libraries/render/src/render/DrawTask.cpp @@ -115,6 +115,26 @@ void CullItems::run(const SceneContextPointer& sceneContext, const RenderContext outItems.clear(); outItems.reserve(inItems.size()); + RenderArgs* args = renderContext->args; + args->_details.pointTo(RenderDetails::OTHER_ITEM); + cullItems(sceneContext, renderContext, inItems, outItems); +} + +void CullItemsOpaque::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outItems) { + + outItems.clear(); + outItems.reserve(inItems.size()); + RenderArgs* args = renderContext->args; + args->_details.pointTo(RenderDetails::OPAQUE_ITEM); + cullItems(sceneContext, renderContext, inItems, outItems); +} + +void CullItemsTransparent::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outItems) { + + outItems.clear(); + outItems.reserve(inItems.size()); + RenderArgs* args = renderContext->args; + args->_details.pointTo(RenderDetails::TRANSLUCENT_ITEM); cullItems(sceneContext, renderContext, inItems, outItems); } @@ -233,9 +253,10 @@ void DrawLight::run(const SceneContextPointer& sceneContext, const RenderContext ItemIDsBounds culledItems; culledItems.reserve(inItems.size()); + RenderArgs* args = renderContext->args; + args->_details.pointTo(RenderDetails::OTHER_ITEM); cullItems(sceneContext, renderContext, inItems, culledItems); - RenderArgs* args = renderContext->args; gpu::doInBatch(args->_context, [=](gpu::Batch& batch) { args->_batch = &batch; renderItems(sceneContext, renderContext, culledItems); diff --git a/libraries/render/src/render/DrawTask.h b/libraries/render/src/render/DrawTask.h index b7a03b81e2..1db666a512 100755 --- a/libraries/render/src/render/DrawTask.h +++ b/libraries/render/src/render/DrawTask.h @@ -230,11 +230,31 @@ public: class CullItems { public: + CullItems() { + qDebug() << "CullItems() created... "; + } void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outItems); - typedef Job::ModelIO JobModel; }; +class CullItemsOpaque { +public: + CullItemsOpaque() { + qDebug() << "CullItemsOpaque() created... "; + } + void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outItems); + typedef Job::ModelIO JobModel; +}; + +class CullItemsTransparent { +public: + CullItemsTransparent() { + qDebug() << "CullItemsTransparent() created... "; + } + void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outItems); + typedef Job::ModelIO JobModel; +}; + class DepthSortItems { public: bool _frontToBack = true; From 0b2bf8bda8725f445b8fc59e90862d542c424e19 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Mon, 19 Oct 2015 15:23:45 -0700 Subject: [PATCH 2/2] remove some dead code --- interface/src/LODManager.cpp | 11 +---------- libraries/render/src/render/DrawTask.h | 9 --------- 2 files changed, 1 insertion(+), 19 deletions(-) diff --git a/interface/src/LODManager.cpp b/interface/src/LODManager.cpp index 0d2681ac72..368143e36e 100644 --- a/interface/src/LODManager.cpp +++ b/interface/src/LODManager.cpp @@ -229,8 +229,6 @@ bool LODManager::shouldRender(const RenderArgs* args, const AABox& bounds) { static bool shouldRenderTableNeedsBuilding = true; static QMap shouldRenderTable; if (shouldRenderTableNeedsBuilding) { - qDebug() << "LODManager::shouldRender() rebuilding table!"; - float SMALLEST_SCALE_IN_TABLE = 0.001f; // 1mm is plenty small float scale = maxScale; float factor = 1.0f; @@ -256,14 +254,7 @@ bool LODManager::shouldRender(const RenderArgs* args, const AABox& bounds) { visibleDistanceAtClosestScale *= 2.0f; } - bool result = distanceToCamera <= visibleDistanceAtClosestScale; - - /* - qDebug() << "LODManager::shouldRender() bounds:" << bounds << "result:" << result - << "distanceToCamera:" << distanceToCamera << "visibleDistanceAtClosestScale:" << visibleDistanceAtClosestScale; - */ - - return result; + return distanceToCamera <= visibleDistanceAtClosestScale; }; // TODO: This is essentially the same logic used to render octree cells, but since models are more detailed then octree cells diff --git a/libraries/render/src/render/DrawTask.h b/libraries/render/src/render/DrawTask.h index 1db666a512..ed51273f88 100755 --- a/libraries/render/src/render/DrawTask.h +++ b/libraries/render/src/render/DrawTask.h @@ -230,27 +230,18 @@ public: class CullItems { public: - CullItems() { - qDebug() << "CullItems() created... "; - } void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outItems); typedef Job::ModelIO JobModel; }; class CullItemsOpaque { public: - CullItemsOpaque() { - qDebug() << "CullItemsOpaque() created... "; - } void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outItems); typedef Job::ModelIO JobModel; }; class CullItemsTransparent { public: - CullItemsTransparent() { - qDebug() << "CullItemsTransparent() created... "; - } void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outItems); typedef Job::ModelIO JobModel; };