diff --git a/data/assets/examples/celestial_globe.asset b/data/assets/examples/celestial_globe.asset index 79d704b0d2..c959473d1d 100644 --- a/data/assets/examples/celestial_globe.asset +++ b/data/assets/examples/celestial_globe.asset @@ -1,11 +1,12 @@ --- Model CC0 from https://sketchfab.com/3d-models/celestial-globe-341fa8a777e94883841409438756f747 - -local sun_transforms = asset.require("scene/solarsystem/sun/transforms") local mars = asset.require("scene/solarsystem/planets/mars/mars") local earth = asset.require("scene/solarsystem/planets/earth/earth") local moon = asset.require("scene/solarsystem/planets/earth/moon/moon") local sun = asset.require("scene/solarsystem/sun/sun") +local sun_transforms = asset.require("scene/solarsystem/sun/transforms") + + +-- Model CC0 from https://sketchfab.com/3d-models/celestial-globe-341fa8a777e94883841409438756f747 local celestial_globe_folder = asset.resource({ Name = "Celestial Globe", Type = "HttpSynchronization", @@ -13,66 +14,173 @@ local celestial_globe_folder = asset.resource({ Version = 1 }) -local globeModels = {} - -function createModel(longitude, latitude, scale, name, parent, group) - local model = { - Identifier = "celestial-globe-" .. name, - Parent = parent, - Transform = { - Translation = { - Type = "GlobeTranslation", - Globe = parent, - Longitude = longitude, - Latitude = latitude, - UseHeightmap = true, - Altitude = 0.0 - }, - Rotation = { - Type = "GlobeRotation", - Globe = parent, - Longitude = longitude, - Latitude = latitude, - Angle= 180 - }, - Scale = { - Type = "StaticScale", - Scale = scale - } +local ModelMars1 = { + Identifier = "celestial-globe-mars1", + Parent = mars.Mars.Identifier, + Transform = { + Translation = { + Type = "GlobeTranslation", + Globe = mars.Mars.Identifier, + Longitude = 3.63325, + Latitude = 26.13238, + UseHeightmap = true, + Altitude = 0.0 }, - Renderable = { - Type = "RenderableModel", - Enabled = true, - GeometryFile = celestial_globe_folder .. "celestial_globe.glb", - ModelScale = "Kilometer", - LightSources = { - sun_transforms.LightSource - }, - CastShadow = true, - LightSource = sun.LightSource.Identifier, - ShadowGroup = group - }, - GUI = { - Name = "Celestial Globe - " .. name, - Path = "/Shadow Casting Models/Celestial Globe - " .. name + Rotation = { + Type = "GlobeRotation", + Globe = mars.Mars.Identifier, + Longitude = 3.63325, + Latitude = 26.13238, + Angle= 180 } + }, + Renderable = { + Type = "RenderableModel", + Enabled = true, + GeometryFile = celestial_globe_folder .. "celestial_globe.glb", + ModelScale = "Kilometer", + LightSources = { + sun_transforms.LightSource + }, + CastShadow = true, + LightSource = sun.LightSource.Identifier, + ShadowGroup = "mars" + }, + GUI = { + Name = "Celestial Globe - Mars1", + Path = "/Shadow Casting Models/Celestial Globe" } - globeModels[#globeModels + 1] = model - return model -end +} + +local ModelMars2 = { + Identifier = "celestial-globe-mars2", + Parent = mars.Mars.Identifier, + Transform = { + Translation = { + Type = "GlobeTranslation", + Globe = mars.Mars.Identifier, + Longitude = 3.6, + Latitude = 26.15239, + UseHeightmap = true, + Altitude = 0.0 + }, + Rotation = { + Type = "GlobeRotation", + Globe = mars.Mars.Identifier, + Longitude = 3.6, + Latitude = 26.15239, + Angle= 180 + }, + Scale = { + Type = "StaticScale", + Scale = 5.0 + } + }, + Renderable = { + Type = "RenderableModel", + Enabled = true, + GeometryFile = celestial_globe_folder .. "celestial_globe.glb", + ModelScale = "Kilometer", + LightSources = { + sun_transforms.LightSource + }, + CastShadow = true, + LightSource = sun.LightSource.Identifier, + ShadowGroup = "mars" + }, + GUI = { + Name = "Celestial Globe - Mars2", + Path = "/Shadow Casting Models/Celestial Globe" + } +} + +local ModelEarth = { + Identifier = "celestial-globe-earth", + Parent = earth.Earth.Identifier, + Transform = { + Translation = { + Type = "GlobeTranslation", + Globe = earth.Earth.Identifier, + Longitude = -74.0060, + Latitude = 40.7128, + UseHeightmap = true, + Altitude = 0.0 + }, + Rotation = { + Type = "GlobeRotation", + Globe = earth.Earth.Identifier, + Longitude = -74.0060, + Latitude = 40.7128, + Angle= 180 + } + }, + Renderable = { + Type = "RenderableModel", + Enabled = true, + GeometryFile = celestial_globe_folder .. "celestial_globe.glb", + ModelScale = "Kilometer", + LightSources = { + sun_transforms.LightSource + }, + CastShadow = true, + LightSource = sun.LightSource.Identifier, + ShadowGroup = "earth" + }, + GUI = { + Name = "Celestial Globe - Earth", + Path = "/Shadow Casting Models/Celestial Globe" + } +} + +local ModelMoon = { + Identifier = "celestial-globe-moon", + Parent = moon.Moon.Identifier, + Transform = { + Translation = { + Type = "GlobeTranslation", + Globe = moon.Moon.Identifier, + Longitude = -0.1276, + Latitude = 51.5074, + UseHeightmap = true, + Altitude = 0.0 + }, + Rotation = { + Type = "GlobeRotation", + Globe = moon.Moon.Identifier, + Longitude = -0.1276, + Latitude = 51.5074, + Angle= 180 + } + }, + Renderable = { + Type = "RenderableModel", + Enabled = true, + GeometryFile = celestial_globe_folder .. "celestial_globe.glb", + ModelScale = "Kilometer", + LightSources = { + sun_transforms.LightSource + }, + CastShadow = true, + LightSource = sun.LightSource.Identifier, + ShadowGroup = "moon" + }, + GUI = { + Name = "Celestial Globe - Moon", + Path = "/Shadow Casting Models/Celestial Globe" + } +} + asset.onInitialize(function() - -- Two models in the same group will share a shadow map, - -- so only put them in the same group if they are near each other - openspace.addSceneGraphNode(createModel(3.63325, 26.13238, 1.0, "mars1", mars.Mars.Identifier, "mars")) - openspace.addSceneGraphNode(createModel(3.6, 26.15239, 5.0, "mars2", mars.Mars.Identifier, "mars")) - openspace.addSceneGraphNode(createModel(-74.0060, 40.7128, 1.0, "earth", earth.Earth.Identifier, "earth")) - openspace.addSceneGraphNode(createModel(-0.1276, 51.5074, 1.0, "moon", moon.Moon.Identifier, "moon")) + openspace.addSceneGraphNode(ModelMars1) + openspace.addSceneGraphNode(ModelMars2) + openspace.addSceneGraphNode(ModelEarth) + openspace.addSceneGraphNode(ModelMoon) end) asset.onDeinitialize(function() - -- Reverse order to deinitialize to avoid dependency issues between nodes - for i = #globeModels, 1, -1 do - openspace.removeSceneGraphNode(globeModels[i].Identifier) - end + openspace.removeSceneGraphNode(ModelMoon) + openspace.removeSceneGraphNode(ModelEarth) + openspace.removeSceneGraphNode(ModelMars2) + openspace.removeSceneGraphNode(ModelMars1) end) diff --git a/modules/base/rendering/directionallightsource.cpp b/modules/base/rendering/directionallightsource.cpp index 632ac7046d..8c0db323a2 100644 --- a/modules/base/rendering/directionallightsource.cpp +++ b/modules/base/rendering/directionallightsource.cpp @@ -95,12 +95,12 @@ void DirectionalLightSource::initializeGL() { } void DirectionalLightSource::deinitializeGL() { - for (const auto& [key, tex] : _depthMaps) { - glDeleteTextures(1, &tex); + for (const std::pair& p : _depthMaps) { + glDeleteTextures(1, &p.second); } - for (const auto& [key, fbo] : _FBOs) { - glDeleteFramebuffers(1, &fbo); + for (const std::pair& p : _fbos) { + glDeleteFramebuffers(1, &p.second); } } @@ -144,7 +144,7 @@ void DirectionalLightSource::render(const RenderData& data, RendererTasks&){ glDrawBuffer(GL_NONE); glReadBuffer(GL_NONE); glBindFramebuffer(GL_FRAMEBUFFER, 0); - _FBOs[key] = fbo; + _fbos[key] = fbo; glBindFramebuffer(GL_FRAMEBUFFER, prevFbo); } @@ -154,9 +154,9 @@ void DirectionalLightSource::render(const RenderData& data, RendererTasks&){ std::vector torender; for (const std::string& identifier : casters) { SceneGraphNode* node = global::renderEngine->scene()->sceneGraphNode(identifier); - if (node != nullptr) { + if (node) { RenderableModel* model = dynamic_cast(node->renderable()); - if (model != nullptr && model->isEnabled() && model->isCastingShadow() && model->isReady()) { + if (model && model->isEnabled() && model->isCastingShadow() && model->isReady()) { const double fsz = model->shadowFrustumSize(); glm::dvec3 center = model->center(); vmin = glm::min(vmin, center - fsz / 2); @@ -178,10 +178,10 @@ void DirectionalLightSource::render(const RenderData& data, RendererTasks&){ } glm::dvec3 light = parentNode->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::dvec3 lightDir = glm::normalize(center - light); + glm::dvec3 right = glm::normalize(glm::cross(glm::dvec3(0.0, 1.0, 0.0), lightDir)); + glm::dvec3 eye = center - lightDir * d; + glm::dvec3 up = glm::cross(right, lightDir); glm::dmat4 view = glm::lookAt(eye, center, up); glm::dmat4 projection = glm::ortho( @@ -203,7 +203,7 @@ void DirectionalLightSource::render(const RenderData& data, RendererTasks&){ GLint prevVp[4]; glGetIntegerv(GL_VIEWPORT, prevVp); - glBindFramebuffer(GL_FRAMEBUFFER, _FBOs[key]); + glBindFramebuffer(GL_FRAMEBUFFER, _fbos[key]); glViewport(0, 0, _depthMapResolution.x, _depthMapResolution.y); glClear(GL_DEPTH_BUFFER_BIT); @@ -213,7 +213,7 @@ void DirectionalLightSource::render(const RenderData& data, RendererTasks&){ glBindFramebuffer(GL_FRAMEBUFFER, 0); - _vps[key] = vp; + _viewports[key] = vp; glUseProgram(prevProg); glBindFramebuffer(GL_FRAMEBUFFER, prevFbo); @@ -230,7 +230,7 @@ const GLuint& DirectionalLightSource::depthMap(const std::string& shadowgroup) c } glm::dmat4 DirectionalLightSource::viewProjectionMatrix(const std::string& shadowgroup) const { - return _vps.at(shadowgroup); + return _viewports.at(shadowgroup); } } // namespace openspace diff --git a/modules/base/rendering/directionallightsource.h b/modules/base/rendering/directionallightsource.h index 0999d90b10..0ed2ddd065 100644 --- a/modules/base/rendering/directionallightsource.h +++ b/modules/base/rendering/directionallightsource.h @@ -24,19 +24,16 @@ #ifndef __OPENSPACE_MODULE_BASE___DIRECTIONALLIGHTSOURCE___H__ #define __OPENSPACE_MODULE_BASE___DIRECTIONALLIGHTSOURCE___H__ + #include #include - #include - -#include -#include +#include #include - -#include +#include +#include namespace ghoul::opengl { class ProgramObject; } - namespace openspace::documentation { struct Documentation; } namespace openspace { @@ -57,7 +54,7 @@ public: GLuint depthMap; }; - DirectionalLightSource(const ghoul::Dictionary& dictionary); + explicit DirectionalLightSource(const ghoul::Dictionary& dictionary); ~DirectionalLightSource() override = default; bool isReady() const override; @@ -82,8 +79,8 @@ private: glm::ivec2 _depthMapResolution; std::map> _shadowGroups; std::map _depthMaps; - std::map _FBOs; - std::map _vps; + std::map _fbos; + std::map _viewports; ghoul::opengl::ProgramObject* _depthMapProgram = nullptr; }; diff --git a/modules/base/rendering/renderablemodel.cpp b/modules/base/rendering/renderablemodel.cpp index 0b554a74f3..a0eb23e7bf 100644 --- a/modules/base/rendering/renderablemodel.cpp +++ b/modules/base/rendering/renderablemodel.cpp @@ -73,20 +73,6 @@ namespace { constexpr glm::vec4 PosBufferClearVal = glm::vec4(1e32, 1e32, 1e32, 1.f); - constexpr std::array UniformNames = { - "modelViewTransform", "projectionTransform", "normalTransform", "meshTransform", - "meshNormalTransform", "ambientIntensity", "diffuseIntensity", - "specularIntensity", "specularPower", "performShading", "use_forced_color", "has_texture_diffuse", - "has_texture_normal", "has_texture_specular", "has_color_specular", - "texture_diffuse", "texture_normal", "texture_specular", "color_diffuse", - "color_specular", "opacity", "nLightSources", "lightDirectionsViewSpace", - "lightIntensities", "performManualDepthTest", "gBufferDepthTexture", "resolution" - }; - - constexpr std::array UniformOpacityNames = { - "opacity", "colorTexture", "depthTexture", "viewport", "resolution" - }; - constexpr openspace::properties::Property::PropertyInfo EnableAnimationInfo = { "EnableAnimation", "Enable animation", @@ -119,7 +105,6 @@ namespace { "SpecularPower", "Specular Power", "Power factor for specular component, higher value gives narrower specularity", - // @VISIBILITY(2.4) openspace::properties::Property::Visibility::User }; @@ -193,24 +178,17 @@ namespace { openspace::properties::Property::Visibility::AdvancedUser }; - constexpr openspace::properties::Property::PropertyInfo UseCacheInfo = { - "UseCache", - "Enable model caching", - "Enable cache for the Model", - openspace::properties::Property::Visibility::AdvancedUser - }; - constexpr openspace::properties::Property::PropertyInfo CastShadowInfo = { "CastShadow", "Cast shadow", - "Enable model to cast shadow on its parent renderable", + "Enable model to cast shadow on its parent renderable.", }; constexpr openspace::properties::Property::PropertyInfo FrustumSizeInfo = { "FrustumSize", "Size of the depth-pass view frustum", - "Sets the width & height (effectively left/right & top/bottom)" - " of the depth-pass view frustum, z-near & z-far are calculated.", + "Sets the width & height (effectively left/right & top/bottom) of the depth-pass " + "view frustum, z-near & z-far are calculated.", openspace::properties::Property::Visibility::AdvancedUser }; @@ -340,9 +318,6 @@ namespace { // The path to a fragment shader program to use instead of the default shader. std::optional fragmentShader; - // [[codegen::verbatim(UseCacheInfo.description)]] - std::optional useCache; - // [[codegen::verbatim(CastShadowInfo.description)]] std::optional castShadow; @@ -402,7 +377,6 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary) , _blendingFuncOption(BlendingOptionInfo) , _renderWireframe(RenderWireframeInfo, false) , _frustumSize(FrustumSizeInfo, 1.f) - , _useCache(UseCacheInfo, true) , _castShadow(CastShadowInfo, false) , _lightSourcePropertyOwner({ "LightSources", "Light Sources" }) , _useOverrideColor(UseOverrideColorInfo, false) @@ -528,10 +502,9 @@ 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(""); + _lightSource = p.lightSource.value_or(_lightSource); + _shadowGroup = p.shadowGroup.value_or(_shadowGroup); _useOverrideColor = p.useOverrideColor.value_or(_useOverrideColor); _overrideColor = p.overrideColor.value_or(_overrideColor); @@ -550,7 +523,6 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary) addProperty(_modelTransform); addProperty(_pivot); addProperty(_rotationVec); - addProperty(_useCache); addProperty(_useOverrideColor); addProperty(_overrideColor); @@ -575,7 +547,7 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary) if (_autoSizeFrustum) { const float radius = _geometry->boundingRadius() * _modelScale; _frustumSize = radius; - _frustumSize.setMinValue(radius * .1f); + _frustumSize.setMinValue(radius * 0.1f); _frustumSize.setMaxValue(radius * 3.f); } }); @@ -617,7 +589,7 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary) } // To update list of shadowers for our parent - global::eventEngine->publishEvent("Cast Shadow Changed", "nada"); + global::eventEngine->publishEvent("Cast Shadow Changed"); }); if (p.rotationVector.has_value()) { @@ -840,7 +812,7 @@ void RenderableModel::initializeGL() { if (_autoSizeFrustum) { const float radius = _geometry->boundingRadius() * _modelScale; _frustumSize = radius; - _frustumSize.setMinValue(radius * .1f); + _frustumSize.setMinValue(radius * 0.1f); _frustumSize.setMaxValue(radius * 3.f); } @@ -1042,22 +1014,11 @@ void RenderableModel::render(const RenderData& data, RendererTasks&) { _program->setUniform("has_shadow_depth_map", _castShadow); if (_castShadow) { - /*_program->setUniform("model", modelTransform); - _program->setUniform("light_vp", _lightVP); - _program->setUniform("inv_vp", glm::inverse(data.camera.combinedViewMatrix())); - - _program->setUniform("shadow_depth_map", 13); - glActiveTexture(GL_TEXTURE13); - glBindTexture( - GL_TEXTURE_2D, - _depthMap - );*/ - - if (_lightSource.size() > 0) { + if (!_lightSource.empty()) { SceneGraphNode* node = global::renderEngine->scene()->sceneGraphNode(_lightSource); - if (node != nullptr) { + if (node) { DirectionalLightSource* src = dynamic_cast(node->renderable()); - if (src != nullptr) { + if (src) { GLuint depthMap = src->depthMap(_shadowGroup); glm::dmat4 vp = src->viewProjectionMatrix(_shadowGroup); @@ -1336,7 +1297,7 @@ bool RenderableModel::isCastingShadow() const { void RenderableModel::renderForDepthMap(const glm::dmat4& vp) const { _depthMapProgram->activate(); - glm::dmat4 transform = glm::translate(glm::dmat4(1), glm::dvec3(_pivot.value())); + glm::dmat4 transform = glm::translate(glm::dmat4(1.0), glm::dvec3(_pivot.value())); transform *= glm::scale(_modelTransform.value(), glm::dvec3(_modelScale)); glm::dmat4 model = this->parent()->modelTransform() * transform; @@ -1351,14 +1312,15 @@ void RenderableModel::renderForDepthMap(const glm::dmat4& vp) const { } glm::dvec3 RenderableModel::center() const { - glm::dmat4 transform = glm::translate(glm::dmat4(1), glm::dvec3(_pivot.value())); + glm::dmat4 transform = glm::translate(glm::dmat4(1.0), 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(0, 0, 0, 1.); + return model * glm::dvec4(0.0, 0.0, 0.0, 1.0); } - return model * glm::dvec4(0, 0, 0, 1); + return model * glm::dvec4(0.0, 0.0, 0.0, 1.0); } const std::string& RenderableModel::lightSource() const { @@ -1373,5 +1335,4 @@ double RenderableModel::shadowFrustumSize() const { return _frustumSize; } - } // namespace openspace diff --git a/modules/base/rendering/renderablemodel.h b/modules/base/rendering/renderablemodel.h index df4db089ad..09e328f88b 100644 --- a/modules/base/rendering/renderablemodel.h +++ b/modules/base/rendering/renderablemodel.h @@ -120,7 +120,6 @@ private: properties::BoolProperty _renderWireframe; properties::FloatProperty _frustumSize; - properties::BoolProperty _useCache; properties::BoolProperty _castShadow; std::string _lightSource; std::string _shadowGroup; diff --git a/modules/base/shaders/model_depth_fs.glsl b/modules/base/shaders/model_depth_fs.glsl index b74ca861cf..7e904d9aad 100644 --- a/modules/base/shaders/model_depth_fs.glsl +++ b/modules/base/shaders/model_depth_fs.glsl @@ -1,3 +1,27 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2025 * + * * + * 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 "fragment.glsl" Fragment getFragment() { diff --git a/modules/base/shaders/model_depth_vs.glsl b/modules/base/shaders/model_depth_vs.glsl index a597e5f4aa..b4afe526e3 100644 --- a/modules/base/shaders/model_depth_vs.glsl +++ b/modules/base/shaders/model_depth_vs.glsl @@ -1,3 +1,27 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2025 * + * * + * 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. * + ****************************************************************************************/ + #version __CONTEXT__ layout(location = 0) in vec4 in_position; diff --git a/modules/base/shaders/model_fs.glsl b/modules/base/shaders/model_fs.glsl index fb4c6269de..9cddf87837 100644 --- a/modules/base/shaders/model_fs.glsl +++ b/modules/base/shaders/model_fs.glsl @@ -201,7 +201,7 @@ Fragment getFragment() { totalLightColor *= ambientLightColor + (1.f - ambientLightColor) * shadowFactor; // Apply shadow to specular lighting (more aggressive - specular highlights should be sharply attenuated in shadows) totalSpecularColor *= shadowFactor; - + frag.color.rgb = totalLightColor + totalSpecularColor; } } @@ -215,6 +215,5 @@ Fragment getFragment() { frag.color = override_color; } - // frag.color = frag.color * 0.00000000000000000000001 + override_color ; return frag; } diff --git a/modules/globebrowsing/CMakeLists.txt b/modules/globebrowsing/CMakeLists.txt index 7a24b78a73..11fbeff462 100644 --- a/modules/globebrowsing/CMakeLists.txt +++ b/modules/globebrowsing/CMakeLists.txt @@ -69,8 +69,6 @@ set(HEADER_FILES src/tileprovider/spoutimageprovider.h src/tileprovider/temporaltileprovider.h src/tileprovider/texttileprovider.h - src/tileprovider/planetarytrailtileprovider.h - src/tileprovider/forcehighresolutiontileprovider.h src/tileprovider/tileindextileprovider.h src/tileprovider/tileprovider.h src/tileprovider/tileproviderbydate.h @@ -115,8 +113,6 @@ set(SOURCE_FILES src/tileprovider/spoutimageprovider.cpp src/tileprovider/temporaltileprovider.cpp src/tileprovider/texttileprovider.cpp - src/tileprovider/planetarytrailtileprovider.cpp - src/tileprovider/forcehighresolutiontileprovider.cpp src/tileprovider/tileindextileprovider.cpp src/tileprovider/tileprovider.cpp src/tileprovider/tileproviderbydate.cpp diff --git a/modules/globebrowsing/shaders/renderer_fs.glsl b/modules/globebrowsing/shaders/renderer_fs.glsl index c5713b2536..2f0bf0a35e 100644 --- a/modules/globebrowsing/shaders/renderer_fs.glsl +++ b/modules/globebrowsing/shaders/renderer_fs.glsl @@ -323,7 +323,7 @@ Fragment getFragment() { if (texCoord >= 0.0 && texCoord <= 1.0) { // Sample ring transparency texture float ringOpacity = texture(ringTextureTransparency, texCoord).r; - + // Increase the shadow darkness factor with low angle to simulate the light having // to pass through more material float angleFactor = clamp(abs(-dot(ringPlaneNormal, surfaceToSun)) / 2.0, 0.0, 0.3); @@ -341,29 +341,30 @@ Fragment getFragment() { #if USE_DEPTHMAP_SHADOWS && nDepthMaps > 0 const float bias = 0.005; const int sz = 3; - const float norm = pow(2.f * sz + 1, 2.f); - float shadowed = 0.f; - float accum = 1.f; - float ambience = .2f; - for (int idx = 0; idx < nDepthMaps; ++idx) { + const float norm = pow(2.0 * sz + 1, 2.0); + float shadowed = 0.0; + float accum = 1.0; + float ambience = 0.2; + for (int idx = 0; idx < nDepthMaps; idx++) { vec2 ssz = 1.f / textureSize(light_depth_maps[idx], 0); vec3 coords = 0.5 + 0.5 * positions_lightspace[idx].xyz / positions_lightspace[idx].w; - for (int x = -sz; x <= sz; ++x) { - for (int y = -sz; y <= sz; ++y) { + for (int x = -sz; x <= sz; x++) { + for (int y = -sz; y <= sz; y++) { float depth = texture(light_depth_maps[idx], coords.xy + vec2(x * ssz.x, y * ssz.y)).r; // inside of the far plane of the frustum if (coords.z < 1) { accum -= float(depth < coords.z - bias) / norm; - } else { + } + else { // outside of the far plane of the frustum, typically happens with long shadows // cast on the surface of a globe - accum -= float(depth < 1.) / norm; + accum -= float(depth < 1.0) / norm; } } } } - frag.color.xyz *= ambience + (1.f - ambience) * max(0.f, accum); + frag.color.xyz *= ambience + (1.f - ambience) * max(0.0, accum); #endif // USE_DEPTHMAP_SHADOWS && nDepthMaps > 0 frag.color.a *= opacity; diff --git a/modules/globebrowsing/src/renderableglobe.cpp b/modules/globebrowsing/src/renderableglobe.cpp index d8e790139f..3d48b68d03 100644 --- a/modules/globebrowsing/src/renderableglobe.cpp +++ b/modules/globebrowsing/src/renderableglobe.cpp @@ -23,6 +23,7 @@ ****************************************************************************************/ #include + #include #include #include @@ -52,7 +53,6 @@ #include #include #include -#include #include #include #include @@ -276,14 +276,6 @@ namespace { openspace::properties::Property::Visibility::User }; - constexpr openspace::properties::Property::PropertyInfo OverrideRenderModeInfo = { - "OverrideRenderMode", - "Override render mode", - "Override the automatic render mode selection to force either global or local " - "rendering mode. 'Default' uses the automatic selection based on distance.", - openspace::properties::Property::Visibility::AdvancedUser - }; - struct [[codegen::Dictionary(RenderableGlobe)]] Parameters { // The radii for this planet. If only one value is given, all three radii are // set to that value. @@ -350,6 +342,7 @@ namespace { // globe. std::optional shadowGroup; + // Details about the rings of the globe, if it has any. std::optional rings [[codegen::reference("globebrowsing_rings_component")]]; @@ -619,18 +612,21 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary) , _currentLodScaleFactor(CurrentLodScaleFactorInfo, 15.f, 1.f, 50.f) , _orenNayarRoughness(OrenNayarRoughnessInfo, 0.f, 0.f, 1.f) , _nActiveLayers(NActiveLayersInfo, 0, 0, OpenGLCap.maxTextureUnits() / 3) - , _showChunkEdges(ShowChunkEdgeInfo, false) - , _levelByProjectedAreaElseDistance(LevelProjectedAreaInfo, true) - , _resetTileProviders(ResetTileProviderInfo, false) - , _performFrustumCulling(PerformFrustumCullingInfo, true) - , _performHorizonCulling(PerformHorizonCullingInfo, true) - , _modelSpaceRenderingCutoffLevel(ModelSpaceRenderingInfo, 14, 1, 22) - , _dynamicLodIterationCount(DynamicLodIterationCountInfo, 16, 4, 128) - , _overrideRenderMode(OverrideRenderModeInfo) - , _shadowMapping(ShadowMappingInfo, true) - , _zFightingPercentage(ZFightingPercentageInfo, 0.995f, 0.000001f, 1.f) - , _nShadowSamples(NumberShadowSamplesInfo, 4, 1, 256) + , _debugProperties({ + BoolProperty(ShowChunkEdgeInfo, false), + BoolProperty(LevelProjectedAreaInfo, true), + TriggerProperty(ResetTileProviderInfo), + BoolProperty(PerformFrustumCullingInfo, true), + BoolProperty(PerformHorizonCullingInfo, true), + IntProperty(ModelSpaceRenderingInfo, 14, 1, 22), + IntProperty(DynamicLodIterationCountInfo, 16, 4, 128) + }) , _debugPropertyOwner({ "Debug" }) + , _shadowMappingProperties({ + BoolProperty(ShadowMappingInfo, false), + FloatProperty(ZFightingPercentageInfo, 0.995f, 0.000001f, 1.f), + IntProperty(NumberShadowSamplesInfo, 5, 1, 7) + }) , _shadowMappingPropertyOwner({ "ShadowMapping", "Shadow Mapping" }) , _grid(DefaultSkirtedGridSegments, DefaultSkirtedGridSegments) , _leftRoot(Chunk(LeftHemisphereIndex)) @@ -720,10 +716,10 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary) addProperty(_eclipseHardShadows); } - _shadowMappingPropertyOwner.addProperty(_shadowMapping); - _shadowMappingPropertyOwner.addProperty(_zFightingPercentage); - _shadowMappingPropertyOwner.addProperty(_nShadowSamples); - _nShadowSamples.onChange([this]() { + _shadowMappingPropertyOwner.addProperty(_shadowMappingProperties.shadowMapping); + _shadowMappingPropertyOwner.addProperty(_shadowMappingProperties.zFightingPercentage); + _shadowMappingPropertyOwner.addProperty(_shadowMappingProperties.nShadowSamples); + _shadowMappingProperties.nShadowSamples.onChange([this]() { _shadersNeedRecompilation = true; }); addPropertySubOwner(_shadowMappingPropertyOwner); @@ -743,25 +739,18 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary) _nActiveLayers.setReadOnly(true); addProperty(_nActiveLayers); - _overrideRenderMode.addOptions({ - { 0, "Default" }, - { 1, "Force Global Rendering" }, - { 2, "Force Local Rendering" } - }); - _overrideRenderMode = 0; + _debugPropertyOwner.addProperty(_debugProperties.showChunkEdges); + _debugPropertyOwner.addProperty(_debugProperties.levelByProjectedAreaElseDistance); + _debugProperties.resetTileProviders.onChange([&]() { _resetTileProviders = true; }); + _debugPropertyOwner.addProperty(_debugProperties.resetTileProviders); + _debugPropertyOwner.addProperty(_debugProperties.performFrustumCulling); + _debugPropertyOwner.addProperty(_debugProperties.modelSpaceRenderingCutoffLevel); + _debugPropertyOwner.addProperty(_debugProperties.dynamicLodIterationCount); - _modelSpaceRenderingCutoffLevel = - p.modelSpaceRenderingCutoffLevel.value_or(_modelSpaceRenderingCutoffLevel); - addProperty(_modelSpaceRenderingCutoffLevel); + _debugProperties.modelSpaceRenderingCutoffLevel = + p.modelSpaceRenderingCutoffLevel.value_or(_debugProperties.modelSpaceRenderingCutoffLevel); + addProperty(_debugProperties.modelSpaceRenderingCutoffLevel); - _debugPropertyOwner.addProperty(_showChunkEdges); - _debugPropertyOwner.addProperty(_levelByProjectedAreaElseDistance); - _resetTileProviders.onChange([&]() { _resetTileProviders = true; }); - _debugPropertyOwner.addProperty(_resetTileProviders); - _debugPropertyOwner.addProperty(_performFrustumCulling); - _debugPropertyOwner.addProperty(_performHorizonCulling); - _debugPropertyOwner.addProperty(_dynamicLodIterationCount); - _debugPropertyOwner.addProperty(_overrideRenderMode); addPropertySubOwner(_debugPropertyOwner); auto notifyShaderRecompilation = [this]() { @@ -771,8 +760,8 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary) _eclipseShadowsEnabled.onChange(notifyShaderRecompilation); _eclipseHardShadows.onChange(notifyShaderRecompilation); _performShading.onChange(notifyShaderRecompilation); - _showChunkEdges.onChange(notifyShaderRecompilation); - _shadowMapping.onChange(notifyShaderRecompilation); + _debugProperties.showChunkEdges.onChange(notifyShaderRecompilation); + _shadowMappingProperties.shadowMapping.onChange(notifyShaderRecompilation); _layerManager.onChange([this](Layer* l) { _shadersNeedRecompilation = true; @@ -821,7 +810,7 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary) _shadowComponent = std::make_unique(*p.shadows); _shadowComponent->initialize(); addPropertySubOwner(_shadowComponent.get()); - _shadowMapping = true; + _shadowMappingProperties.shadowMapping = true; } // Use a secondary renderbin for labels, and other things that we want to be able to @@ -1064,13 +1053,9 @@ void RenderableGlobe::update(const UpdateData& data) { const events::Event* e = global::eventEngine->firstEvent(); while (e) { switch (e->type) { - case events::Event::Type::PropertyTreeUpdated: - case events::Event::Type::PropertyTreePruned: - case events::Event::Type::RenderableDisabled: - case events::Event::Type::RenderableEnabled: case events::Event::Type::Custom: size_t prevSize = _shadowers.size(); - _shadowers = getShadowers(this->parent()); + _shadowers = getShadowers(parent()); if (prevSize != _shadowers.size()) { _shadowersUpdated = true; _shadowersOk = false; @@ -1371,18 +1356,16 @@ void RenderableGlobe::renderChunks(const RenderData& data, bool renderGeomOnly) } std::vector depthMapData; - for (const auto& [key, groups] : _shadowSpec) { - const auto node = global::renderEngine->scene()->sceneGraphNode(key); - if (node != nullptr) { + for (const std::pair>& p : _shadowSpec) { + const auto node = global::renderEngine->scene()->sceneGraphNode(p.first); + if (node) { const auto src = dynamic_cast(node->renderable()); - if (src != nullptr) { - for (const auto& grp : groups) { - depthMapData.push_back( - { + if (src) { + for (const std::string& grp : p.second) { + depthMapData.push_back({ .viewProjection = src->viewProjectionMatrix(grp), .depthMap = src->depthMap(grp) - } - ); + }); } } } @@ -1391,7 +1374,7 @@ void RenderableGlobe::renderChunks(const RenderData& data, bool renderGeomOnly) int globalCount = 0; int localCount = 0; - auto traversal = [this](const Chunk& node, std::vector& global, + auto traversal = [](const Chunk& node, std::vector& global, int& iGlobal, std::vector& local, int& iLocal, int cutoff, std::vector& traversalMemory) { @@ -1406,21 +1389,7 @@ void RenderableGlobe::renderChunks(const RenderData& data, bool renderGeomOnly) traversalMemory.erase(traversalMemory.begin()); if (isLeaf(*n) && n->isVisible) { - bool useGlobalRendering; - - switch (_overrideRenderMode.value()) { - case 1: // Force Global Rendering - useGlobalRendering = true; - break; - case 2: // Force Local Rendering - useGlobalRendering = false; - break; - case 0: // Default - default: - useGlobalRendering = n->tileIndex.level < cutoff; - break; - } - + const bool useGlobalRendering = n->tileIndex.level < cutoff; if (useGlobalRendering) { global[iGlobal] = n; iGlobal++; @@ -1446,7 +1415,7 @@ void RenderableGlobe::renderChunks(const RenderData& data, bool renderGeomOnly) globalCount, _localChunkBuffer, localCount, - _modelSpaceRenderingCutoffLevel, + _debugProperties.modelSpaceRenderingCutoffLevel, _traversalMemory ); traversal( @@ -1455,7 +1424,7 @@ void RenderableGlobe::renderChunks(const RenderData& data, bool renderGeomOnly) globalCount, _localChunkBuffer, localCount, - _modelSpaceRenderingCutoffLevel, + _debugProperties.modelSpaceRenderingCutoffLevel, _traversalMemory ); @@ -1480,7 +1449,7 @@ void RenderableGlobe::renderChunks(const RenderData& data, bool renderGeomOnly) // dynamically to not keep rendering frames with unavailable data // After certain number of iterations(_debugProperties.dynamicLodIterationCount) // of unavailable/available data in a row, we assume that a change could be made. - const int iterCount = _dynamicLodIterationCount; + const int iterCount = _debugProperties.dynamicLodIterationCount; const bool exceededIterations = static_cast(_iterationsOfUnavailableData) > iterCount; const float clf = _currentLodScaleFactor; @@ -1532,7 +1501,7 @@ void RenderableGlobe::renderChunkGlobally(const Chunk& chunk, const RenderData& bound_units.push_back(unit); } - if (_shadowers.size() > 0 && _shadowersOk) { + if (!_shadowers.empty() && _shadowersOk) { program.setUniform("inv_vp", glm::inverse(data.camera.combinedViewMatrix())); program.setUniform("light_depth_maps", bound_units); GLint loc = glGetUniformLocation(program, "light_vps"); @@ -1582,7 +1551,7 @@ void RenderableGlobe::renderChunkGlobally(const Chunk& chunk, const RenderData& } // Shadow Mapping - if (_shadowMapping && _performShading) { + if (_shadowMappingProperties.shadowMapping && _performShading) { // Bind ring textures for direct projection when rings component is available if (_ringsComponent && _ringsComponent->isEnabled()) { ghoul::opengl::TextureUnit ringTextureColorUnit; @@ -1718,7 +1687,7 @@ void RenderableGlobe::renderChunkLocally(const Chunk& chunk, const RenderData& d } // Shadow Mapping - if (_shadowMapping) { + if (_shadowMappingProperties.shadowMapping) { // Bind ring textures for direct projection when rings component is available if (_ringsComponent && _ringsComponent->isEnabled()) { ghoul::opengl::TextureUnit ringTextureColorUnit; @@ -1935,14 +1904,14 @@ void RenderableGlobe::recompileShaders() { pairs.emplace_back("useEclipseHardShadows", std::to_string(_eclipseHardShadows)); pairs.emplace_back( "enableShadowMapping", - std::to_string(_shadowMapping && _shadowComponent) + std::to_string(_shadowMappingProperties.shadowMapping&& _shadowComponent) ); pairs.emplace_back( "useRingShadows", - std::to_string(_shadowMapping && _ringsComponent && + std::to_string(_shadowMappingProperties.shadowMapping&& _ringsComponent && _ringsComponent->isEnabled()) ); - pairs.emplace_back("showChunkEdges", std::to_string(_showChunkEdges)); + pairs.emplace_back("showChunkEdges", std::to_string(_debugProperties.showChunkEdges)); pairs.emplace_back("showHeightResolution", "0"); pairs.emplace_back("showHeightIntensities", "0"); pairs.emplace_back("defaultHeight", std::to_string(DefaultHeight)); @@ -2036,7 +2005,7 @@ void RenderableGlobe::recompileShaders() { // Shadow Mapping Samples shaderDictionary.setValue( "nShadowSamples", - _nShadowSamples - 1 + _shadowMappingProperties.nShadowSamples - 1 ); // Exclise Shadow Samples @@ -2073,6 +2042,7 @@ void RenderableGlobe::recompileShaders() { _localRenderer.uniformCache ); + // // Create global shader // @@ -2140,8 +2110,8 @@ bool RenderableGlobe::testIfCullable(const Chunk& chunk, { ZoneScoped; - return (_performHorizonCulling && isCullableByHorizon(chunk, renderData, heights)) || - (_performFrustumCulling && isCullableByFrustum(chunk, renderData, mvp)); + return (_debugProperties.performHorizonCulling && isCullableByHorizon(chunk, renderData, heights)) || + (_debugProperties.performFrustumCulling && isCullableByFrustum(chunk, renderData, mvp)); } int RenderableGlobe::desiredLevel(const Chunk& chunk, const RenderData& renderData, @@ -2149,7 +2119,7 @@ int RenderableGlobe::desiredLevel(const Chunk& chunk, const RenderData& renderDa { ZoneScoped; - const int desiredLevel = _levelByProjectedAreaElseDistance ? + const int desiredLevel = _debugProperties.levelByProjectedAreaElseDistance ? desiredLevelByProjectedArea(chunk, renderData, heights) : desiredLevelByDistance(chunk, renderData, heights); const int levelByAvailableData = desiredLevelByAvailableTileData(chunk); @@ -2595,17 +2565,15 @@ int RenderableGlobe::desiredLevelByAvailableTileData(const Chunk& chunk) const { const int currLevel = chunk.tileIndex.level; for (const layers::Group& gi : layers::Groups) { - if (gi.id != layers::Group::ID::Overlays) { - const std::vector& lyrs = _layerManager.layerGroup(gi.id).activeLayers(); - for (Layer* layer : lyrs) { - const Tile::Status status = layer->tileStatus(chunk.tileIndex); - // Ensure that the current tile is OK and that the tileprovider for the - // current layer has enough data to support an additional level. - if (status == Tile::Status::OK && - layer->tileProvider()->maxLevel() > currLevel + 1) - { - return UnknownDesiredLevel; - } + const std::vector& lyrs = _layerManager.layerGroup(gi.id).activeLayers(); + for (Layer* layer : lyrs) { + const Tile::Status status = layer->tileStatus(chunk.tileIndex); + // Ensure that the current tile is OK and that the tileprovider for the + // current layer has enough data to support an additional level. + if (status == Tile::Status::OK && + layer->tileProvider()->maxLevel() > currLevel + 1) + { + return UnknownDesiredLevel; } } } diff --git a/modules/globebrowsing/src/renderableglobe.h b/modules/globebrowsing/src/renderableglobe.h index 68d7cbf1ca..28f29144b7 100644 --- a/modules/globebrowsing/src/renderableglobe.h +++ b/modules/globebrowsing/src/renderableglobe.h @@ -135,18 +135,24 @@ private: static constexpr int MinSplitDepth = 2; static constexpr int MaxSplitDepth = 22; - properties::BoolProperty _showChunkEdges; - properties::BoolProperty _levelByProjectedAreaElseDistance; - properties::BoolProperty _resetTileProviders; - properties::BoolProperty _performFrustumCulling; - properties::BoolProperty _performHorizonCulling; - properties::IntProperty _modelSpaceRenderingCutoffLevel; - properties::IntProperty _dynamicLodIterationCount; - properties::OptionProperty _overrideRenderMode; - + struct { + properties::BoolProperty showChunkEdges; + properties::BoolProperty levelByProjectedAreaElseDistance; + properties::TriggerProperty resetTileProviders; + properties::BoolProperty performFrustumCulling; + properties::BoolProperty performHorizonCulling; + properties::IntProperty modelSpaceRenderingCutoffLevel; + properties::IntProperty dynamicLodIterationCount; + } _debugProperties; properties::PropertyOwner _debugPropertyOwner; + struct { + properties::BoolProperty shadowMapping; + properties::FloatProperty zFightingPercentage; + properties::IntProperty nShadowSamples; + } _shadowMappingProperties; + properties::PropertyOwner _shadowMappingPropertyOwner; /** @@ -255,10 +261,6 @@ private: properties::FloatProperty _orenNayarRoughness; properties::IntProperty _nActiveLayers; - properties::BoolProperty _shadowMapping; - properties::FloatProperty _zFightingPercentage; - properties::IntProperty _nShadowSamples; - Ellipsoid _ellipsoid; SkirtedGrid _grid; LayerManager _layerManager; @@ -303,6 +305,7 @@ private: bool _nLayersIsDirty = true; bool _allChunksAvailable = true; bool _layerManagerDirty = true; + bool _resetTileProviders = false; size_t _iterationsOfAvailableData = 0; size_t _iterationsOfUnavailableData = 0; Layer* _lastChangedLayer = nullptr;