From a34db5f26dcc802420dd849413d294f3679c012e Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Tue, 24 Oct 2017 11:09:36 +0200 Subject: [PATCH] Shadows are now cast by the current zone key light (sun) --- .../src/RenderableZoneEntityItem.cpp | 1 + .../src/RenderableZoneEntityItem.h | 1 + .../render-utils/src/DebugDeferredBuffer.cpp | 2 +- .../src/DeferredLightingEffect.cpp | 4 +-- libraries/render-utils/src/LightStage.cpp | 5 ++++ libraries/render-utils/src/LightStage.h | 24 ++++++++++++++++ .../render-utils/src/RenderShadowTask.cpp | 28 +++++++++---------- 7 files changed, 48 insertions(+), 17 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp index f0f5506f8c..0235f1b7a3 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp @@ -112,6 +112,7 @@ void ZoneEntityRenderer::doRender(RenderArgs* args) { // Do we need to allocate the light in the stage ? if (LightStage::isIndexInvalid(_sunIndex)) { _sunIndex = _stage->addLight(_sunLight); + _shadowIndex = _stage->addShadow(_sunIndex); } else { _stage->updateLightArrayBuffer(_sunIndex); } diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.h b/libraries/entities-renderer/src/RenderableZoneEntityItem.h index f39a2e6299..050a8a4386 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.h +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.h @@ -88,6 +88,7 @@ private: ComponentMode _hazeMode{ COMPONENT_MODE_INHERIT }; indexed_container::Index _sunIndex{ LightStage::INVALID_INDEX }; + indexed_container::Index _shadowIndex{ LightStage::INVALID_INDEX }; indexed_container::Index _ambientIndex{ LightStage::INVALID_INDEX }; BackgroundStagePointer _backgroundStage; diff --git a/libraries/render-utils/src/DebugDeferredBuffer.cpp b/libraries/render-utils/src/DebugDeferredBuffer.cpp index 44e2bd290b..d334a53fa1 100644 --- a/libraries/render-utils/src/DebugDeferredBuffer.cpp +++ b/libraries/render-utils/src/DebugDeferredBuffer.cpp @@ -435,7 +435,7 @@ void DebugDeferredBuffer::run(const RenderContextPointer& renderContext, const I auto lightStage = renderContext->_scene->getStage(); assert(lightStage); assert(lightStage->getNumLights() > 0); - auto lightAndShadow = lightStage->getLightAndShadow(0); + auto lightAndShadow = lightStage->getCurrentKeyLightAndShadow(); const auto& globalShadow = lightAndShadow.second; if (globalShadow) { batch.setResourceTexture(Shadow, globalShadow->map); diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index e6a33a9911..b6a91888a1 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -498,7 +498,7 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext, auto lightStage = renderContext->_scene->getStage(); assert(lightStage); assert(lightStage->getNumLights() > 0); - auto lightAndShadow = lightStage->getLightAndShadow(0); + auto lightAndShadow = lightStage->getCurrentKeyLightAndShadow(); const auto& globalShadow = lightAndShadow.second; // Bind the shadow buffer @@ -509,7 +509,7 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext, auto& program = deferredLightingEffect->_directionalSkyboxLight; LightLocationsPtr locations = deferredLightingEffect->_directionalSkyboxLightLocations; - auto keyLight = lightStage->getLight(0); + auto keyLight = lightAndShadow.first; // Setup the global directional pass pipeline { diff --git a/libraries/render-utils/src/LightStage.cpp b/libraries/render-utils/src/LightStage.cpp index d0e9f2467e..079c63f367 100644 --- a/libraries/render-utils/src/LightStage.cpp +++ b/libraries/render-utils/src/LightStage.cpp @@ -142,6 +142,11 @@ LightStage::LightPointer LightStage::removeLight(Index index) { LightPointer removed = _lights.freeElement(index); if (removed) { + auto shadowId = _descs[index].shadowId; + // Remove shadow if one exists for this light + if (shadowId != INVALID_INDEX) { + _shadows.freeElement(shadowId); + } _lightMap.erase(removed); _descs[index] = Desc(); } diff --git a/libraries/render-utils/src/LightStage.h b/libraries/render-utils/src/LightStage.h index f946cf699e..66d73c9a6e 100644 --- a/libraries/render-utils/src/LightStage.h +++ b/libraries/render-utils/src/LightStage.h @@ -116,6 +116,30 @@ public: return LightAndShadow(getLight(lightId), getShadow(lightId)); } + LightPointer getCurrentKeyLight() const { + Index keyLightId{ 0 }; + if (!_currentFrame._sunLights.empty()) { + keyLightId = _currentFrame._sunLights.front(); + } + return _lights.get(keyLightId); + } + + ShadowPointer getCurrentKeyShadow() const { + Index keyLightId{ 0 }; + if (!_currentFrame._sunLights.empty()) { + keyLightId = _currentFrame._sunLights.front(); + } + return getShadow(keyLightId); + } + + LightAndShadow getCurrentKeyLightAndShadow() const { + Index keyLightId{ 0 }; + if (!_currentFrame._sunLights.empty()) { + keyLightId = _currentFrame._sunLights.front(); + } + return LightAndShadow(getLight(keyLightId), getShadow(keyLightId)); + } + LightStage(); Lights _lights; LightMap _lightMap; diff --git a/libraries/render-utils/src/RenderShadowTask.cpp b/libraries/render-utils/src/RenderShadowTask.cpp index d32857bc65..7171543abc 100644 --- a/libraries/render-utils/src/RenderShadowTask.cpp +++ b/libraries/render-utils/src/RenderShadowTask.cpp @@ -33,10 +33,8 @@ void RenderShadowMap::run(const render::RenderContextPointer& renderContext, auto lightStage = renderContext->_scene->getStage(); assert(lightStage); - LightStage::Index globalLightIndex { 0 }; - const auto globalLight = lightStage->getLight(globalLightIndex); - const auto shadow = lightStage->getShadow(globalLightIndex); + const auto shadow = lightStage->getCurrentKeyShadow(); if (!shadow) return; const auto& fbo = shadow->framebuffer; @@ -128,20 +126,22 @@ void RenderShadowTask::configure(const Config& configuration) { void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, Output& output) { auto lightStage = renderContext->_scene->getStage(); assert(lightStage); - const auto globalShadow = lightStage->getShadow(0); - // Cache old render args - RenderArgs* args = renderContext->args; - output = args->_renderMode; + const auto globalShadow = lightStage->getCurrentKeyShadow(); + if (globalShadow) { + // Cache old render args + RenderArgs* args = renderContext->args; + output = args->_renderMode; - auto nearClip = args->getViewFrustum().getNearClip(); - float nearDepth = -args->_boomOffset.z; - const int SHADOW_FAR_DEPTH = 20; - globalShadow->setKeylightFrustum(args->getViewFrustum(), nearDepth, nearClip + SHADOW_FAR_DEPTH); + auto nearClip = args->getViewFrustum().getNearClip(); + float nearDepth = -args->_boomOffset.z; + const int SHADOW_FAR_DEPTH = 20; + globalShadow->setKeylightFrustum(args->getViewFrustum(), nearDepth, nearClip + SHADOW_FAR_DEPTH); - // Set the keylight render args - args->pushViewFrustum(*(globalShadow->getFrustum())); - args->_renderMode = RenderArgs::SHADOW_RENDER_MODE; + // Set the keylight render args + args->pushViewFrustum(*(globalShadow->getFrustum())); + args->_renderMode = RenderArgs::SHADOW_RENDER_MODE; + } } void RenderShadowTeardown::run(const render::RenderContextPointer& renderContext, const Input& input) {