diff --git a/modules/base/CMakeLists.txt b/modules/base/CMakeLists.txt index fe79b952b8..a25f62e9f6 100644 --- a/modules/base/CMakeLists.txt +++ b/modules/base/CMakeLists.txt @@ -70,6 +70,7 @@ set(HEADER_FILES rendering/screenspaceframebuffer.h rendering/screenspaceimagelocal.h rendering/screenspaceimageonline.h + rendering/directionallightsource.h rotation/timelinerotation.h rotation/constantrotation.h rotation/fixedrotation.h @@ -134,6 +135,7 @@ set(SOURCE_FILES rendering/screenspaceframebuffer.cpp rendering/screenspaceimagelocal.cpp rendering/screenspaceimageonline.cpp + rendering/directionallightsource.cpp rotation/timelinerotation.cpp rotation/constantrotation.cpp rotation/fixedrotation.cpp diff --git a/modules/base/basemodule.cpp b/modules/base/basemodule.cpp index 73662afcf6..0160c3ceec 100644 --- a/modules/base/basemodule.cpp +++ b/modules/base/basemodule.cpp @@ -66,6 +66,7 @@ #include #include #include +#include #include #include #include @@ -135,6 +136,8 @@ void BaseModule::internalInitialize(const ghoul::Dictionary&) { FactoryManager::ref().factory(); ghoul_assert(fRenderable, "Renderable factory was not created"); + fRenderable->registerClass("DirectionalLightSource"); + fRenderable->registerClass("RenderableBoxGrid"); fRenderable->registerClass("RenderableCartesianAxes"); fRenderable->registerClass("RenderableDisc"); diff --git a/modules/base/rendering/directionallightsource.cpp b/modules/base/rendering/directionallightsource.cpp new file mode 100644 index 0000000000..e9a2b794fa --- /dev/null +++ b/modules/base/rendering/directionallightsource.cpp @@ -0,0 +1,222 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2024 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include + +namespace { + + constexpr std::string_view _loggerCat = "DirectionalLightsource"; + + struct [[codegen::Dictionary(DirectionalLightsource)]] Parameters { + + }; +#include "DirectionalLightsource_codegen.cpp" +} // namespace + +namespace openspace { + +documentation::Documentation DirectionalLightSource::Documentation() { + return codegen::doc("base_renderable_cartesianaxes"); +} + +DirectionalLightSource::DirectionalLightSource(const ghoul::Dictionary& dictionary) + : Renderable(dictionary) +{ + setRenderBin(Renderable::RenderBin::Background); +} + +bool DirectionalLightSource::isReady() const { + return true; +} + +void DirectionalLightSource::initialize() { + _depthMapResolution = global::renderEngine->renderingResolution() * 4; +} + +void DirectionalLightSource::initializeGL() { + _depthMapProgram = BaseModule::ProgramObjectManager.request( + "ModelDepthMapProgram", + [&]() -> std::unique_ptr { + std::filesystem::path vs = + absPath("${MODULE_BASE}/shaders/model_depth_vs.glsl"); + std::filesystem::path fs = + absPath("${MODULE_BASE}/shaders/model_depth_fs.glsl"); + + std::unique_ptr prog = + global::renderEngine->buildRenderProgram( + "ModelDepthMapProgram", + vs, + fs + ); + prog->setIgnoreAttributeLocationError( + ghoul::opengl::ProgramObject::IgnoreError::Yes + ); + prog->setIgnoreUniformLocationError( + ghoul::opengl::ProgramObject::IgnoreError::Yes + ); + return prog; + } + ); +} + +void DirectionalLightSource::deinitializeGL() { + for (const auto& [key, tex] : _depthMaps) { + glDeleteTextures(1, &tex); + } + + for (const auto& [key, fbo] : _FBOs) { + glDeleteFramebuffers(1, &fbo); + } +} + +void DirectionalLightSource::render(const RenderData& data, RendererTasks&){ + for (const auto& [key, casters] : _shadowGroups) { + if (!_depthMaps.contains(key)) { + GLint prevFbo; + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &prevFbo); + + GLuint tex; + glGenTextures(1, &tex); + glBindTexture(GL_TEXTURE_2D, tex); + glTexImage2D( + GL_TEXTURE_2D, + 0, + GL_DEPTH_COMPONENT, + _depthMapResolution.x, + _depthMapResolution.y, + 0, + GL_DEPTH_COMPONENT, + GL_FLOAT, + nullptr + ); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, glm::value_ptr(glm::vec4(1.f, 1.f, 1.f, 1.f))); + glBindTexture(GL_TEXTURE_2D, 0); + _depthMaps[key] = tex; + + GLuint fbo; + glGenFramebuffers(1, &fbo); + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, tex, 0); + glDrawBuffer(GL_NONE); + glReadBuffer(GL_NONE); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + _FBOs[key] = fbo; + + glBindFramebuffer(GL_FRAMEBUFFER, prevFbo); + } + + glm::dvec3 vmin(std::numeric_limits::max()), vmax(-std::numeric_limits::max()); + + std::vector torender; + for (const std::string& identifier : casters) { + SceneGraphNode* node = global::renderEngine->scene()->sceneGraphNode(identifier); + if (node != nullptr) { + RenderableModel* model = dynamic_cast(node->renderable()); + if (model != nullptr && model->isEnabled() && model->isCastingShadow() && model->isReady()) { + const double fsz = model->shadowFrustumSize(); + glm::dvec3 center = model->center(); + vmin = glm::min(vmin, center - fsz / 2); + vmax = glm::max(vmax, center + fsz / 2); + + torender.push_back(model); + } + } + } + + double sz = glm::length(vmax - vmin); + double d = sz * 500.; + glm::dvec3 center = vmin + (vmax - vmin) * 0.5; + glm::dvec3 light = parent()->modelTransform() * glm::dvec4(0.0, 0.0, 0.0, 1.0); + glm::dvec3 light_dir = glm::normalize(center - light); + glm::dvec3 right = glm::normalize(glm::cross(glm::dvec3(0, 1, 0), light_dir)); + glm::dvec3 eye = center - light_dir * d; + glm::dvec3 up = glm::cross(right, light_dir); + + glm::dmat4 view = glm::lookAt(eye, center, up); + glm::dmat4 projection = glm::ortho( + -sz, + sz, + -sz, + sz, + d - sz, + d + sz + ); + glm::dmat4 vp = projection * view; + + GLint prevProg; + glGetIntegerv(GL_CURRENT_PROGRAM, &prevProg); + + GLint prevFbo; + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &prevFbo); + + GLint prevVp[4]; + glGetIntegerv(GL_VIEWPORT, prevVp); + + glBindFramebuffer(GL_FRAMEBUFFER, _FBOs[key]); + glViewport(0, 0, _depthMapResolution.x, _depthMapResolution.y); + glClear(GL_DEPTH_BUFFER_BIT); + + for (const RenderableModel* model : torender) { + model->renderForDepthMap(vp); + } + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + _vps[key] = vp; + + glUseProgram(prevProg); + glBindFramebuffer(GL_FRAMEBUFFER, prevFbo); + glViewport(prevVp[0], prevVp[1], prevVp[2], prevVp[3]); + } +} + +void DirectionalLightSource::registerShadowCaster(const std::string& shadowgroup, const std::string& identifier) { + _shadowGroups[shadowgroup].push_back(identifier); +} + +const GLuint& DirectionalLightSource::depthMap(const std::string& shadowgroup) const { + return _depthMaps.at(shadowgroup); +} + +glm::dmat4 DirectionalLightSource::viewProjectionMatrix(const std::string& shadowgroup) const { + return _vps.at(shadowgroup); +} + +} // namespace openspace diff --git a/modules/base/rendering/directionallightsource.h b/modules/base/rendering/directionallightsource.h new file mode 100644 index 0000000000..add95f16ad --- /dev/null +++ b/modules/base/rendering/directionallightsource.h @@ -0,0 +1,84 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2024 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#ifndef __OPENSPACE_MODULE_BASE___DIRECTIONALLIGHTSOURCE___H__ +#define __OPENSPACE_MODULE_BASE___DIRECTIONALLIGHTSOURCE___H__ +#include +#include + +#include + +#include +#include +#include + +#include + +namespace ghoul::opengl { class ProgramObject; } + +namespace openspace::documentation { struct Documentation; } + +namespace openspace { + +class DirectionalLightSource : public Renderable { +public: + struct DepthMapData { + glm::dmat4 viewProjecion; + GLuint depthMap; + }; + + DirectionalLightSource(const ghoul::Dictionary& dictionary); + ~DirectionalLightSource() override = default; + + bool isReady() const override; + + virtual void initialize() override; + + virtual void initializeGL() override; + + virtual void deinitializeGL() override; + + void render(const RenderData& data, RendererTasks& rendererTask) override; + + void registerShadowCaster(const std::string& shadowgroup, const std::string& identifier); + + const GLuint& depthMap(const std::string& shadowgroup) const; + + glm::dmat4 viewProjectionMatrix(const std::string& shadowgroup) const; + + static documentation::Documentation Documentation(); + +private: + glm::ivec2 _depthMapResolution; + std::map> _shadowGroups; + std::map _depthMaps; + std::map _FBOs; + std::map _vps; + std::unique_ptr _lightSource; + ghoul::opengl::ProgramObject* _depthMapProgram = nullptr; +}; + +}// namespace openspace + +#endif // __OPENSPACE_MODULE_BASE___DIRECTIONALLIGHTSOURCE___H__ diff --git a/modules/base/rendering/renderablemodel.cpp b/modules/base/rendering/renderablemodel.cpp index 803297de75..a461ded8dc 100644 --- a/modules/base/rendering/renderablemodel.cpp +++ b/modules/base/rendering/renderablemodel.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -41,6 +42,7 @@ #include #include #include + #include #include #include @@ -347,6 +349,10 @@ namespace { // [[codegen::verbatim(CastShadowInfo.description)]] std::optional castShadow; + + std::optional lightSource; + + std::optional shadowGroup; }; #include "renderablemodel_codegen.cpp" } // namespace @@ -507,6 +513,8 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary) _useCache = p.useCache.value_or(_useCache); _castShadow = p.castShadow.value_or(_castShadow); + _lightSource = p.lightSource.value_or(""); + _shadowGroup = p.shadowGroup.value_or(""); addProperty(_enableAnimation); addPropertySubOwner(_lightSourcePropertyOwner); @@ -619,6 +627,24 @@ void RenderableModel::initialize() { for (const std::unique_ptr& ls : _lightSources) { ls->initialize(); + + if (_castShadow) { + SceneGraphLightSource* ptr = dynamic_cast(ls.get()); + if (ptr != nullptr) { + const auto parent = this->parent(); + ptr->registerShadowCaster(parent->identifier()); + } + } + } + + if (_lightSource.size() > 0) { + SceneGraphNode* node = global::renderEngine->scene()->sceneGraphNode(_lightSource); + if (node != nullptr) { + DirectionalLightSource* src = dynamic_cast(node->renderable()); + if (src != nullptr) { + src->registerShadowCaster(_shadowGroup, parent()->identifier()); + } + } } } @@ -876,37 +902,6 @@ void RenderableModel::createDepthMapResources() { return prog; } ); - - // Twice the res - _depthMapResolution = global::renderEngine->renderingResolution(); - - glGenFramebuffers(1, &_depthMapFBO); - - glGenTextures(1, &_depthMap); - glBindTexture(GL_TEXTURE_2D, _depthMap); - glTexImage2D( - GL_TEXTURE_2D, - 0, - GL_DEPTH_COMPONENT, - _depthMapResolution.x, - _depthMapResolution.y, - 0, - GL_DEPTH_COMPONENT, - GL_FLOAT, - nullptr - ); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); - glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, glm::value_ptr(glm::vec4(1.f, 1.f, 1.f, 1.f))); - glBindTexture(GL_TEXTURE_2D, 0); - - glBindFramebuffer(GL_FRAMEBUFFER, _depthMapFBO); - glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, _depthMap, 0); - glDrawBuffer(GL_NONE); - glReadBuffer(GL_NONE); - glBindFramebuffer(GL_FRAMEBUFFER, 0); } void RenderableModel::releaseDepthMapResources() { @@ -918,9 +913,6 @@ void RenderableModel::releaseDepthMapResources() { } ); } - - glDeleteFramebuffers(1, &_depthMapFBO); - glDeleteTextures(1, &_depthMap); } void RenderableModel::render(const RenderData& data, RendererTasks&) { @@ -1041,7 +1033,7 @@ void RenderableModel::render(const RenderData& data, RendererTasks&) { _program->setUniform("has_shadow_depth_map", _castShadow); if (_castShadow) { - _program->setUniform("model", modelTransform); + /*_program->setUniform("model", modelTransform); _program->setUniform("light_vp", _lightVP); _program->setUniform("inv_vp", glm::inverse(data.camera.combinedViewMatrix())); @@ -1050,7 +1042,29 @@ void RenderableModel::render(const RenderData& data, RendererTasks&) { glBindTexture( GL_TEXTURE_2D, _depthMap - ); + );*/ + + if (_lightSource.size() > 0) { + SceneGraphNode* node = global::renderEngine->scene()->sceneGraphNode(_lightSource); + if (node != nullptr) { + DirectionalLightSource* src = dynamic_cast(node->renderable()); + if (src != nullptr) { + GLuint depthMap = src->depthMap(_shadowGroup); + glm::dmat4 vp = src->viewProjectionMatrix(_shadowGroup); + + _program->setUniform("model", modelTransform); + _program->setUniform("light_vp", vp); + _program->setUniform("inv_vp", glm::inverse(data.camera.combinedViewMatrix())); + + _program->setUniform("shadow_depth_map", 13); + glActiveTexture(GL_TEXTURE13); + glBindTexture( + GL_TEXTURE_2D, + depthMap + ); + } + } + } } if (!_shouldRenderTwice) { @@ -1301,77 +1315,44 @@ const bool RenderableModel::isCastingShadow() const { return _castShadow; } -std::optional RenderableModel::renderDepthMap() const { - if (_lightSources.size() < 1) { - return std::nullopt; - } - - const openspace::SceneGraphLightSource* light = - dynamic_cast(_lightSources.front().get()); - - GLint prevProg; - glGetIntegerv(GL_CURRENT_PROGRAM, &prevProg); - - GLint prevFbo; - glGetIntegerv(GL_FRAMEBUFFER_BINDING, &prevFbo); - - GLint prevVp[4]; - glGetIntegerv(GL_VIEWPORT, prevVp); - +void RenderableModel::renderForDepthMap(const glm::dmat4& vp) const { _depthMapProgram->activate(); - const double frustumSize = static_cast(_frustumSize); - const double distance = frustumSize * 500.; - - // Model glm::dmat4 transform = glm::translate(glm::dmat4(1), glm::dvec3(_pivot.value())); transform *= glm::scale(_modelTransform.value(), glm::dvec3(_modelScale)); glm::dmat4 model = this->parent()->modelTransform() * transform; - // View - glm::dvec3 center; - if (_modelHasAnimation) { - center = model * glm::dvec4(_geometry->center(), 1.); - } - else { - center = dynamic_cast(this->owner())->worldPosition(); - } - - glm::dvec3 light_dir = glm::normalize(center - light->positionWorldSpace()); - glm::dvec3 right = glm::normalize(glm::cross(glm::dvec3(0, 1, 0), light_dir)); - glm::dvec3 eye = center - light_dir * distance; - glm::dvec3 up = glm::cross(right, light_dir); - glm::dmat4 view = glm::lookAt(eye, center, up); - - // Projection - glm::dmat4 projection = glm::ortho( - -frustumSize, - frustumSize, - -frustumSize, - frustumSize, - distance - frustumSize, - distance + frustumSize - ); - - _lightVP = projection * view; _depthMapProgram->setUniform("model", model); - _depthMapProgram->setUniform("light_vp", _lightVP); - - glBindFramebuffer(GL_FRAMEBUFFER, _depthMapFBO); - glViewport(0, 0, _depthMapResolution.x, _depthMapResolution.y); - glClear(GL_DEPTH_BUFFER_BIT); + _depthMapProgram->setUniform("light_vp", vp); glCullFace(GL_FRONT); if (isEnabled()) { _geometry->render(*_depthMapProgram, false, true); } glCullFace(GL_BACK); - - glUseProgram(prevProg); - glBindFramebuffer(GL_FRAMEBUFFER, prevFbo); - glViewport(prevVp[0], prevVp[1], prevVp[2], prevVp[3]); - - return std::optional({ _lightVP, _depthMap }); } +glm::dvec3 RenderableModel::center() const { + glm::dmat4 transform = glm::translate(glm::dmat4(1), glm::dvec3(_pivot.value())); + transform *= glm::scale(_modelTransform.value(), glm::dvec3(_modelScale)); + glm::dmat4 model = this->parent()->modelTransform() * transform; + if (_modelHasAnimation) { + return model * glm::dvec4(_geometry->center(), 1.); + } + + return model * glm::dvec4(0, 0, 0, 1); +} + +const std::string RenderableModel::lightsource() const { + return _lightSource; +} + +const std::string RenderableModel::shadowGroup() const { + return _shadowGroup; +} +const double RenderableModel::shadowFrustumSize() const { + return _frustumSize; +} + + } // namespace openspace diff --git a/modules/base/rendering/renderablemodel.h b/modules/base/rendering/renderablemodel.h index 1e16abcd0d..8dc052e3ce 100644 --- a/modules/base/rendering/renderablemodel.h +++ b/modules/base/rendering/renderablemodel.h @@ -56,10 +56,6 @@ namespace documentation { struct Documentation; } class RenderableModel : public Renderable { public: - struct DepthMapData { - glm::dmat4 viewProjecion; - GLuint depthMap; - }; RenderableModel(const ghoul::Dictionary& dictionary); ~RenderableModel() override = default; @@ -76,7 +72,14 @@ public: void update(const UpdateData& data) override; const bool isCastingShadow() const; - std::optional renderDepthMap() const; + + void renderForDepthMap(const glm::dmat4& vp) const; + + glm::dvec3 center() const; + + const std::string lightsource() const; + const std::string shadowGroup() const; + const double shadowFrustumSize() const; static documentation::Documentation Documentation(); @@ -119,6 +122,8 @@ private: properties::BoolProperty _useCache; properties::BoolProperty _castShadow; + std::string _lightSource; + std::string _shadowGroup; bool _autoSizeFrustum = false; @@ -156,10 +161,6 @@ private: // Store the original RenderBin Renderable::RenderBin _originalRenderBin; - GLuint _depthMapFBO = 0; - GLuint _depthMap = 0; - glm::ivec2 _depthMapResolution; - mutable glm::dmat4 _lightVP; ghoul::opengl::ProgramObject* _depthMapProgram = nullptr; }; diff --git a/modules/globebrowsing/src/renderableglobe.cpp b/modules/globebrowsing/src/renderableglobe.cpp index b34b9656ed..3d7aa4a91c 100644 --- a/modules/globebrowsing/src/renderableglobe.cpp +++ b/modules/globebrowsing/src/renderableglobe.cpp @@ -1030,6 +1030,11 @@ void RenderableGlobe::update(const UpdateData& data) { if (prevSize != _shadowers.size()) { _shadowersUpdated = true; _shadowersOk = false; + + _shadowSpec.clear(); + for (const auto model : _shadowers) { + _shadowSpec[model->lightsource()].push_back(model->shadowGroup()); + } } break; } @@ -1307,12 +1312,20 @@ void RenderableGlobe::renderChunks(const RenderData& data, RendererTasks&, _globalRenderer.program->setIgnoreUniformLocationError(IgnoreError::Yes); } - std::vector depthMapData; - for (const RenderableModel* model : _shadowers) { - if (model->isReady()) { - const std::optional data = model->renderDepthMap(); - if (data.has_value()) { - depthMapData.push_back(data.value()); + std::vector depthMapData; + for (const auto& [key, groups] : _shadowSpec) { + const auto node = global::renderEngine->scene()->sceneGraphNode(key); + if (node != nullptr) { + const auto src = dynamic_cast(node->renderable()); + if (src != nullptr) { + for (const auto& grp : groups) { + depthMapData.push_back( + { + .viewProjecion = src->viewProjectionMatrix(grp), + .depthMap = src->depthMap(grp) + } + ); + } } } } @@ -1512,7 +1525,7 @@ void RenderableGlobe::renderChunkGlobally(const Chunk& chunk, const RenderData& void RenderableGlobe::renderChunkLocally(const Chunk& chunk, const RenderData& data, const ShadowComponent::ShadowMapData& shadowData, bool renderGeomOnly, - std::vector depthMapData) + std::vector depthMapData) { ZoneScoped; TracyGpuZone("renderChunkLocally"); @@ -1638,7 +1651,7 @@ void RenderableGlobe::renderChunkLocally(const Chunk& chunk, const RenderData& d std::vector light_vps; std::vector> depthmapTextureUnits; - for (const RenderableModel::DepthMapData& data : depthMapData) { + for (const DirectionalLightSource::DepthMapData& data : depthMapData) { light_vps.push_back(data.viewProjecion); depthmapTextureUnits.emplace_back(ghoul::opengl::TextureUnit(), data.depthMap); } @@ -1937,7 +1950,12 @@ void RenderableGlobe::recompileShaders() { // Local shader uses depthmap shadows shaderDictionary.setValue("useDepthmapShadows", 1); - shaderDictionary.setValue("nDepthMaps", static_cast(_shadowers.size())); + int nmaps = 0; + for (const auto& [src, grps] : _shadowSpec) { + nmaps += static_cast(grps.size()); + } + + shaderDictionary.setValue("nDepthMaps", nmaps); // // Create local shader // diff --git a/modules/globebrowsing/src/renderableglobe.h b/modules/globebrowsing/src/renderableglobe.h index 7726475f48..30eb25c462 100644 --- a/modules/globebrowsing/src/renderableglobe.h +++ b/modules/globebrowsing/src/renderableglobe.h @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -223,7 +224,7 @@ private: */ void renderChunkLocally(const Chunk& chunk, const RenderData& data, const ShadowComponent::ShadowMapData& shadowData = {}, bool renderGeomOnly = false, - std::vector depthMapData = {} + std::vector depthMapData = {} ); void debugRenderChunk(const Chunk& chunk, const glm::dmat4& mvp, @@ -313,6 +314,8 @@ private: bool _shadowersUpdated = false; bool _shadowersOk = false; + std::map> _shadowSpec; + // Components std::unique_ptr _ringsComponent; std::unique_ptr _shadowComponent;