From a4b9ec50e95c73462d1432c34fe93a791c736260 Mon Sep 17 00:00:00 2001 From: sam gateau Date: Fri, 14 Dec 2018 17:00:58 -0800 Subject: [PATCH] one step closer --- .../src/DeferredLightingEffect.cpp | 8 +- libraries/render-utils/src/LightStage.cpp | 5 ++ libraries/render-utils/src/LightStage.h | 2 + .../render-utils/src/RenderDeferredTask.cpp | 2 +- .../render-utils/src/RenderShadowTask.cpp | 82 +++++++++++-------- libraries/render-utils/src/RenderShadowTask.h | 2 +- 6 files changed, 62 insertions(+), 39 deletions(-) diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 98de378505..78cd10ca52 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -436,7 +436,11 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext, assert(lightStage); assert(lightStage->getNumLights() > 0); auto lightAndShadow = lightStage->getCurrentKeyLightAndShadow(*lightFrame); - const auto& globalShadow = lightAndShadow.second; + //const auto& globalShadow = lightAndShadow.second; + LightStage::ShadowPointer globalShadow; + if (shadowFrame && !shadowFrame->_objects.empty()) { + globalShadow = shadowFrame->_objects.front(); + } // Bind the shadow buffers if (globalShadow) { @@ -640,7 +644,7 @@ void RenderDeferred::run(const RenderContextPointer& renderContext, const Inputs args->_batch = &batch; _gpuTimer->begin(batch); - setupJob.run(renderContext, deferredTransform, deferredFramebuffer, lightingModel, lightFrame, hazeFrame, surfaceGeometryFramebuffer, ssaoFramebuffer, subsurfaceScatteringResource, _renderShadows); + setupJob.run(renderContext, deferredTransform, deferredFramebuffer, lightingModel, lightFrame, shadowFrame, hazeFrame, surfaceGeometryFramebuffer, ssaoFramebuffer, subsurfaceScatteringResource, _renderShadows); lightsJob.run(renderContext, deferredTransform, deferredFramebuffer, lightingModel, surfaceGeometryFramebuffer, lightClusters); diff --git a/libraries/render-utils/src/LightStage.cpp b/libraries/render-utils/src/LightStage.cpp index d5e1ca4644..ad3a86507e 100644 --- a/libraries/render-utils/src/LightStage.cpp +++ b/libraries/render-utils/src/LightStage.cpp @@ -152,6 +152,11 @@ LightStage::Shadow::Shadow(graphics::LightPointer light, float maxDistance, unsi setMaxDistance(maxDistance); } +void LightStage::Shadow::setLight(graphics::LightPointer light) { + _light = light; +} + + void LightStage::Shadow::setMaxDistance(float value) { // This overlaping factor isn't really used directly for blending of shadow cascades. It // just there to be sure the cascades do overlap. The blending width used is relative diff --git a/libraries/render-utils/src/LightStage.h b/libraries/render-utils/src/LightStage.h index be187d1d49..6c84859164 100644 --- a/libraries/render-utils/src/LightStage.h +++ b/libraries/render-utils/src/LightStage.h @@ -76,6 +76,8 @@ public: Shadow(graphics::LightPointer light, float maxDistance, unsigned int cascadeCount = 1); + void setLight(graphics::LightPointer light); + void setKeylightFrustum(const ViewFrustum& viewFrustum, float nearDepth = 1.0f, float farDepth = 1000.0f); void setKeylightCascadeFrustum(unsigned int cascadeIndex, const ViewFrustum& viewFrustum, diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index f3841e4d4c..78ad5fa2d3 100644 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -154,7 +154,7 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren const auto shadowTaskOutputs = inputs.get2(); // Shadow Stage Frame - const auto shadowFrame = shadowTaskOutputs.get1(); + const auto shadowFrame = shadowTaskOutputs[1]; fadeEffect->build(task, opaques); diff --git a/libraries/render-utils/src/RenderShadowTask.cpp b/libraries/render-utils/src/RenderShadowTask.cpp index 12dfecd855..31f5084589 100644 --- a/libraries/render-utils/src/RenderShadowTask.cpp +++ b/libraries/render-utils/src/RenderShadowTask.cpp @@ -63,6 +63,7 @@ void RenderShadowTask::build(JobModel& task, const render::Varying& input, rende const auto setupOutput = task.addJob("ShadowSetup", lightFrame); const auto queryResolution = setupOutput.getN(1); + const auto shadowFrame = setupOutput.getN(3); // Fetch and cull the items from the scene static const auto shadowCasterReceiverFilter = ItemFilter::Builder::visibleWorldItems().withTypeShape().withOpaque().withoutLayered().withTagBits(tagBits, tagMask); @@ -96,7 +97,7 @@ void RenderShadowTask::build(JobModel& task, const render::Varying& input, rende for (auto i = 0; i < SHADOW_CASCADE_MAX_COUNT; i++) { char jobName[64]; sprintf(jobName, "ShadowCascadeSetup%d", i); - const auto cascadeSetupOutput = task.addJob(jobName, lightFrame, i, tagBits, tagMask); + const auto cascadeSetupOutput = task.addJob(jobName, shadowFrame, i, tagBits, tagMask); const auto shadowFilter = cascadeSetupOutput.getN(0); auto antiFrustum = render::Varying(ViewFrustumPointer()); cascadeFrustums[i] = cascadeSetupOutput.getN(1); @@ -359,31 +360,30 @@ void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, c *_cameraFrustum = args->getViewFrustum(); output.edit2() = _cameraFrustum; - const auto globalShadow = lightStage->getCurrentKeyShadow(lightFrame); - if (globalShadow) { - globalShadow->setKeylightFrustum(args->getViewFrustum(), SHADOW_FRUSTUM_NEAR, SHADOW_FRUSTUM_FAR); + // Clear previous shadow frame + if (!_globalShadowObject) { + _globalShadowObject = std::make_shared(graphics::LightPointer(), 100.0f); + } + _shadowFrameCache->_objects.clear(); + + const auto theGlobalShadow = lightStage->getCurrentKeyShadow(lightFrame); + if (theGlobalShadow) { + _globalShadowObject->setLight(theGlobalShadow->getLight()); + _globalShadowObject->setKeylightFrustum(args->getViewFrustum(), SHADOW_FRUSTUM_NEAR, SHADOW_FRUSTUM_FAR); - auto& firstCascade = globalShadow->getCascade(0); + auto& firstCascade = _globalShadowObject->getCascade(0); auto& firstCascadeFrustum = firstCascade.getFrustum(); unsigned int cascadeIndex; // Adjust each cascade frustum - for (cascadeIndex = 0; cascadeIndex < globalShadow->getCascadeCount(); ++cascadeIndex) { + for (cascadeIndex = 0; cascadeIndex < _globalShadowObject->getCascadeCount(); ++cascadeIndex) { auto& bias = _bias[cascadeIndex]; - globalShadow->setKeylightCascadeFrustum(cascadeIndex, args->getViewFrustum(), + _globalShadowObject->setKeylightCascadeFrustum(cascadeIndex, args->getViewFrustum(), SHADOW_FRUSTUM_NEAR, SHADOW_FRUSTUM_FAR, bias._constant, bias._slope); } - // copy paste the values for the shadow params: - /* if (!_globalShadowObject) { - LightStage::Shadow::Schema schema; - _globalShadowObject = std::make_shared(sizeof(LightStage::Shadow::Schema), (const gpu::Byte*) &schema); - } - _globalShadowObject->getBuffersetData(globalShadow->getBuffer()._size, globalShadow->getBuffer()._buffer->getData()); - - - _shadowFrameCache->pushShadow(_globalShadowObject);*/ + _shadowFrameCache->pushShadow(_globalShadowObject); // Now adjust coarse frustum bounds auto frustumPosition = firstCascadeFrustum->getPosition(); @@ -397,8 +397,8 @@ void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, c auto near = firstCascadeFrustum->getNearClip(); auto far = firstCascadeFrustum->getFarClip(); - for (cascadeIndex = 1; cascadeIndex < globalShadow->getCascadeCount(); ++cascadeIndex) { - auto& cascadeFrustum = globalShadow->getCascade(cascadeIndex).getFrustum(); + for (cascadeIndex = 1; cascadeIndex < _globalShadowObject->getCascadeCount(); ++cascadeIndex) { + auto& cascadeFrustum = _globalShadowObject->getCascade(cascadeIndex).getFrustum(); farTopLeft = cascadeFrustum->getFarTopLeft() - frustumPosition; farBottomRight = cascadeFrustum->getFarBottomRight() - frustumPosition; @@ -439,36 +439,48 @@ void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, c } void RenderShadowCascadeSetup::run(const render::RenderContextPointer& renderContext, const Inputs& input, Outputs& output) { + const auto shadowFrame = input; + /* auto lightStage = renderContext->_scene->getStage(); const auto& lightFrame = *input; assert(lightStage); - +*/ // Cache old render args RenderArgs* args = renderContext->args; RenderShadowTask::CullFunctor cullFunctor; - const auto globalShadow = lightStage->getCurrentKeyShadow(lightFrame); - if (globalShadow && _cascadeIndex < globalShadow->getCascadeCount()) { - // Second item filter is to filter items to keep in shadow frustum computation (here we need to keep shadow receivers) - output.edit0() = ItemFilter::Builder::visibleWorldItems().withTypeShape().withOpaque().withoutLayered().withTagBits(_tagBits, _tagMask); + + if (shadowFrame && !shadowFrame->_objects.empty() && shadowFrame->_objects[0]) { + const auto globalShadow = shadowFrame->_objects[0]; //lightStage->getCurrentKeyShadow(lightFrame); - // Set the keylight render args - auto& cascade = globalShadow->getCascade(_cascadeIndex); - auto& cascadeFrustum = cascade.getFrustum(); - args->pushViewFrustum(*cascadeFrustum); - auto texelSize = glm::min(cascadeFrustum->getHeight(), cascadeFrustum->getWidth()) / cascade.framebuffer->getSize().x; - // Set the cull threshold to 24 shadow texels. This is totally arbitrary - const auto minTexelCount = 24.0f; - // TODO : maybe adapt that with LOD management system? - texelSize *= minTexelCount; - cullFunctor._minSquareSize = texelSize * texelSize; + if (globalShadow && _cascadeIndex < globalShadow->getCascadeCount()) { + // Second item filter is to filter items to keep in shadow frustum computation (here we need to keep shadow receivers) + output.edit0() = ItemFilter::Builder::visibleWorldItems().withTypeShape().withOpaque().withoutLayered().withTagBits(_tagBits, _tagMask); - output.edit1() = cascadeFrustum; - } else { + // Set the keylight render args + auto& cascade = globalShadow->getCascade(_cascadeIndex); + auto& cascadeFrustum = cascade.getFrustum(); + args->pushViewFrustum(*cascadeFrustum); + auto texelSize = glm::min(cascadeFrustum->getHeight(), cascadeFrustum->getWidth()) / cascade.framebuffer->getSize().x; + // Set the cull threshold to 24 shadow texels. This is totally arbitrary + const auto minTexelCount = 24.0f; + // TODO : maybe adapt that with LOD management system? + texelSize *= minTexelCount; + cullFunctor._minSquareSize = texelSize * texelSize; + + output.edit1() = cascadeFrustum; + + } else { + output.edit0() = ItemFilter::Builder::nothing(); + output.edit1() = ViewFrustumPointer(); + } + } + else { output.edit0() = ItemFilter::Builder::nothing(); output.edit1() = ViewFrustumPointer(); } + output.edit2() = cullFunctor; } diff --git a/libraries/render-utils/src/RenderShadowTask.h b/libraries/render-utils/src/RenderShadowTask.h index f01f9ddd15..1ac5f27087 100644 --- a/libraries/render-utils/src/RenderShadowTask.h +++ b/libraries/render-utils/src/RenderShadowTask.h @@ -127,7 +127,7 @@ private: class RenderShadowCascadeSetup { public: - using Inputs = LightStage::FramePointer; + using Inputs = LightStage::ShadowFramePointer; using Outputs = render::VaryingSet3; using JobModel = render::Job::ModelIO;