From 3fa2babec2ea97178ae2030982459f6b511366b7 Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Wed, 31 Jan 2018 11:55:46 +0100 Subject: [PATCH] Moved cascade frustum pre-computation to single ShadowSetup job --- .../render-utils/src/RenderShadowTask.cpp | 75 ++++++++++++++++--- libraries/render-utils/src/RenderShadowTask.h | 61 ++++++++++----- scripts/developer/utilities/render/shadow.qml | 41 +++++----- 3 files changed, 128 insertions(+), 49 deletions(-) diff --git a/libraries/render-utils/src/RenderShadowTask.cpp b/libraries/render-utils/src/RenderShadowTask.cpp index 2b5ab09c06..b83911582c 100644 --- a/libraries/render-utils/src/RenderShadowTask.cpp +++ b/libraries/render-utils/src/RenderShadowTask.cpp @@ -213,7 +213,7 @@ void RenderShadowTask::build(JobModel& task, const render::Varying& input, rende initZPassPipelines(*shapePlumber, state); } - task.addJob("ShadowSetup"); + const auto coarseFrustum = task.addJob("ShadowSetup"); for (auto i = 0; i < SHADOW_CASCADE_MAX_COUNT; i++) { char jobName[64]; @@ -243,7 +243,31 @@ void RenderShadowTask::configure(const Config& configuration) { // Task::configure(configuration); } -void RenderShadowSetup::run(const render::RenderContextPointer& renderContext) { +RenderShadowSetup::RenderShadowSetup() : + _coarseShadowFrustum{ std::make_shared() } { + +} + +void RenderShadowSetup::configure(const Config& configuration) { + setConstantBias(0, configuration.constantBias0); + setConstantBias(1, configuration.constantBias1); + setConstantBias(2, configuration.constantBias2); + setConstantBias(3, configuration.constantBias3); + setSlopeBias(0, configuration.slopeBias0); + setSlopeBias(1, configuration.slopeBias1); + setSlopeBias(2, configuration.slopeBias2); + setSlopeBias(3, configuration.slopeBias3); +} + +void RenderShadowSetup::setConstantBias(int cascadeIndex, float value) { + _bias[cascadeIndex]._constant = value * value * value * 0.004f; +} + +void RenderShadowSetup::setSlopeBias(int cascadeIndex, float value) { + _bias[cascadeIndex]._slope = value * value * value * 0.01f; +} + +void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, Output& output) { auto lightStage = renderContext->_scene->getStage(); assert(lightStage); // Cache old render args @@ -252,12 +276,46 @@ void RenderShadowSetup::run(const render::RenderContextPointer& renderContext) { const auto globalShadow = lightStage->getCurrentKeyShadow(); if (globalShadow) { globalShadow->setKeylightFrustum(args->getViewFrustum(), SHADOW_FRUSTUM_NEAR, SHADOW_FRUSTUM_FAR); - } -} + auto firstCascadeFrustum = globalShadow->getCascade(0).getFrustum(); + unsigned int cascadeIndex; + _coarseShadowFrustum->setPosition(firstCascadeFrustum->getPosition()); + _coarseShadowFrustum->setOrientation(firstCascadeFrustum->getOrientation()); -void RenderShadowCascadeSetup::configure(const Config& configuration) { - _fixedBias = configuration.fixedBias * configuration.fixedBias * configuration.fixedBias * 0.004f; - _slopeBias = configuration.slopeBias * configuration.slopeBias * configuration.slopeBias * 0.01f; + // Adjust each cascade frustum + for (cascadeIndex = 0; cascadeIndex < globalShadow->getCascadeCount(); ++cascadeIndex) { + auto& bias = _bias[cascadeIndex]; + globalShadow->setKeylightCascadeFrustum(cascadeIndex, args->getViewFrustum(), + SHADOW_FRUSTUM_NEAR, SHADOW_FRUSTUM_FAR, + bias._constant, bias._slope); + } + // Now adjust coarse frustum bounds + auto left = glm::dot(firstCascadeFrustum->getFarTopLeft(), firstCascadeFrustum->getRight()); + auto right = glm::dot(firstCascadeFrustum->getFarTopRight(), firstCascadeFrustum->getRight()); + auto top = glm::dot(firstCascadeFrustum->getFarTopLeft(), firstCascadeFrustum->getUp()); + auto bottom = glm::dot(firstCascadeFrustum->getFarBottomRight(), firstCascadeFrustum->getUp()); + auto near = firstCascadeFrustum->getNearClip(); + auto far = firstCascadeFrustum->getFarClip(); + for (cascadeIndex = 1; cascadeIndex < globalShadow->getCascadeCount(); ++cascadeIndex) { + auto cascadeLeft = glm::dot(firstCascadeFrustum->getFarTopLeft(), firstCascadeFrustum->getRight()); + auto cascadeRight = glm::dot(firstCascadeFrustum->getFarTopRight(), firstCascadeFrustum->getRight()); + auto cascadeTop = glm::dot(firstCascadeFrustum->getFarTopLeft(), firstCascadeFrustum->getUp()); + auto cascadeBottom = glm::dot(firstCascadeFrustum->getFarBottomRight(), firstCascadeFrustum->getUp()); + auto cascadeNear = firstCascadeFrustum->getNearClip(); + auto cascadeFar = firstCascadeFrustum->getFarClip(); + left = glm::min(left, cascadeLeft); + right = glm::max(right, cascadeRight); + bottom = glm::min(bottom, cascadeBottom); + top = glm::max(top, cascadeTop); + near = glm::min(near, cascadeNear); + far = glm::max(far, cascadeFar); + } + _coarseShadowFrustum->setProjection(glm::ortho(left, right, bottom, top, near, far)); + _coarseShadowFrustum->calculate(); + + output = _coarseShadowFrustum; + } else { + output = nullptr; + } } void RenderShadowCascadeSetup::run(const render::RenderContextPointer& renderContext, Outputs& output) { @@ -273,9 +331,6 @@ void RenderShadowCascadeSetup::run(const render::RenderContextPointer& renderCon if (globalShadow && _cascadeIndexgetCascadeCount()) { output.edit1() = ItemFilter::Builder::visibleWorldItems().withTypeShape().withOpaque().withoutLayered(); - globalShadow->setKeylightCascadeFrustum(_cascadeIndex, args->getViewFrustum(), SHADOW_FRUSTUM_NEAR, SHADOW_FRUSTUM_FAR, - _fixedBias, _slopeBias); - // Set the keylight render args args->pushViewFrustum(*(globalShadow->getCascade(_cascadeIndex).getFrustum())); args->_renderMode = RenderArgs::SHADOW_RENDER_MODE; diff --git a/libraries/render-utils/src/RenderShadowTask.h b/libraries/render-utils/src/RenderShadowTask.h index 7e5655b375..f488c46b8e 100644 --- a/libraries/render-utils/src/RenderShadowTask.h +++ b/libraries/render-utils/src/RenderShadowTask.h @@ -17,6 +17,8 @@ #include +#include "Shadows_shared.slh" + class ViewFrustum; class RenderShadowMap { @@ -53,43 +55,64 @@ public: void configure(const Config& configuration); }; -class RenderShadowSetup { -public: - using JobModel = render::Job::Model; - - RenderShadowSetup() {} - void run(const render::RenderContextPointer& renderContext); - -}; - -class RenderShadowCascadeSetupConfig : public render::Job::Config { +class RenderShadowSetupConfig : public render::Job::Config { Q_OBJECT - Q_PROPERTY(float fixedBias MEMBER fixedBias NOTIFY dirty) - Q_PROPERTY(float slopeBias MEMBER slopeBias NOTIFY dirty) + Q_PROPERTY(float constantBias0 MEMBER constantBias0 NOTIFY dirty) + Q_PROPERTY(float constantBias1 MEMBER constantBias1 NOTIFY dirty) + Q_PROPERTY(float constantBias2 MEMBER constantBias2 NOTIFY dirty) + Q_PROPERTY(float constantBias3 MEMBER constantBias3 NOTIFY dirty) + Q_PROPERTY(float slopeBias0 MEMBER slopeBias0 NOTIFY dirty) + Q_PROPERTY(float slopeBias1 MEMBER slopeBias1 NOTIFY dirty) + Q_PROPERTY(float slopeBias2 MEMBER slopeBias2 NOTIFY dirty) + Q_PROPERTY(float slopeBias3 MEMBER slopeBias3 NOTIFY dirty) public: - float fixedBias{ 0.15f }; - float slopeBias{ 0.55f }; + float constantBias0{ 0.15f }; + float constantBias1{ 0.15f }; + float constantBias2{ 0.15f }; + float constantBias3{ 0.15f }; + float slopeBias0{ 0.55f }; + float slopeBias1{ 0.55f }; + float slopeBias2{ 0.55f }; + float slopeBias3{ 0.55f }; signals: void dirty(); }; +class RenderShadowSetup { +public: + using Output = ViewFrustumPointer; + using Config = RenderShadowSetupConfig; + using JobModel = render::Job::ModelO; + + RenderShadowSetup(); + void configure(const Config& configuration); + void run(const render::RenderContextPointer& renderContext, Output& output); + +private: + + ViewFrustumPointer _coarseShadowFrustum; + struct { + float _constant; + float _slope; + } _bias[SHADOW_CASCADE_MAX_COUNT]; + + void setConstantBias(int cascadeIndex, float value); + void setSlopeBias(int cascadeIndex, float value); +}; + class RenderShadowCascadeSetup { public: using Outputs = render::VaryingSet3; - using Config = RenderShadowCascadeSetupConfig; - using JobModel = render::Job::ModelO; + using JobModel = render::Job::ModelO; RenderShadowCascadeSetup(unsigned int cascadeIndex) : _cascadeIndex{ cascadeIndex } {} - void configure(const Config& configuration); void run(const render::RenderContextPointer& renderContext, Outputs& output); private: unsigned int _cascadeIndex; - float _fixedBias{ 0.1f }; - float _slopeBias{ 0.1f }; }; class RenderShadowCascadeTeardown { diff --git a/scripts/developer/utilities/render/shadow.qml b/scripts/developer/utilities/render/shadow.qml index a077ab9f50..3400dcd847 100644 --- a/scripts/developer/utilities/render/shadow.qml +++ b/scripts/developer/utilities/render/shadow.qml @@ -18,6 +18,7 @@ Column { id: root spacing: 8 property var viewConfig: Render.getConfig("RenderMainView.DrawViewFrustum"); + property var shadowConfig : Render.getConfig("RenderMainView.ShadowSetup"); property var shadow0Config: Render.getConfig("RenderMainView.DrawShadowFrustum0"); property var shadow1Config: Render.getConfig("RenderMainView.DrawShadowFrustum1"); property var shadow2Config: Render.getConfig("RenderMainView.DrawShadowFrustum2"); @@ -80,34 +81,34 @@ Column { } } ConfigSlider { - label: qsTr("Cascade 0 fixed bias") + label: qsTr("Cascade 0 constant bias") integral: false - config: Render.getConfig("RenderMainView.ShadowCascadeSetup0") - property: "fixedBias" + config: shadowConfig + property: "constantBias0" max: 1.0 min: 0.0 } ConfigSlider { - label: qsTr("Cascade 1 fixed bias") + label: qsTr("Cascade 1 constant bias") integral: false - config: Render.getConfig("RenderMainView.ShadowCascadeSetup1") - property: "fixedBias" + config: shadowConfig + property: "constantBias1" max: 1.0 min: 0.0 } ConfigSlider { - label: qsTr("Cascade 2 fixed bias") + label: qsTr("Cascade 2 constant bias") integral: false - config: Render.getConfig("RenderMainView.ShadowCascadeSetup2") - property: "fixedBias" + config: shadowConfig + property: "constantBias2" max: 1.0 min: 0.0 } ConfigSlider { - label: qsTr("Cascade 3 fixed bias") + label: qsTr("Cascade 3 constant bias") integral: false - config: Render.getConfig("RenderMainView.ShadowCascadeSetup3") - property: "fixedBias" + config: shadowConfig + property: "constantBias3" max: 1.0 min: 0.0 } @@ -115,32 +116,32 @@ Column { ConfigSlider { label: qsTr("Cascade 0 slope bias") integral: false - config: Render.getConfig("RenderMainView.ShadowCascadeSetup0") - property: "slopeBias" + config: shadowConfig + property: "slopeBias0" max: 1.0 min: 0.0 } ConfigSlider { label: qsTr("Cascade 1 slope bias") integral: false - config: Render.getConfig("RenderMainView.ShadowCascadeSetup1") - property: "slopeBias" + config: shadowConfig + property: "slopeBias1" max: 1.0 min: 0.0 } ConfigSlider { label: qsTr("Cascade 2 slope bias") integral: false - config: Render.getConfig("RenderMainView.ShadowCascadeSetup2") - property: "slopeBias" + config: shadowConfig + property: "slopeBias2" max: 1.0 min: 0.0 } ConfigSlider { label: qsTr("Cascade 3 slope bias") integral: false - config: Render.getConfig("RenderMainView.ShadowCascadeSetup3") - property: "slopeBias" + config: shadowConfig + property: "slopeBias3" max: 1.0 min: 0.0 }