First cleanup pass

This commit is contained in:
Alexander Bock
2025-10-27 17:47:48 +01:00
parent dca62314b2
commit 85557bc233
12 changed files with 345 additions and 265 deletions

View File

@@ -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)

View File

@@ -95,12 +95,12 @@ void DirectionalLightSource::initializeGL() {
}
void DirectionalLightSource::deinitializeGL() {
for (const auto& [key, tex] : _depthMaps) {
glDeleteTextures(1, &tex);
for (const std::pair<std::string, GLuint>& p : _depthMaps) {
glDeleteTextures(1, &p.second);
}
for (const auto& [key, fbo] : _FBOs) {
glDeleteFramebuffers(1, &fbo);
for (const std::pair<std::string, GLuint>& 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<RenderableModel*> torender;
for (const std::string& identifier : casters) {
SceneGraphNode* node = global::renderEngine->scene()->sceneGraphNode(identifier);
if (node != nullptr) {
if (node) {
RenderableModel* model = dynamic_cast<RenderableModel*>(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

View File

@@ -24,19 +24,16 @@
#ifndef __OPENSPACE_MODULE_BASE___DIRECTIONALLIGHTSOURCE___H__
#define __OPENSPACE_MODULE_BASE___DIRECTIONALLIGHTSOURCE___H__
#include <openspace/rendering/renderable.h>
#include <openspace/scene/lightsource.h>
#include <ghoul/opengl/programobject.h>
#include <vector>
#include <string>
#include <ghoul/glm.h>
#include <map>
#include <glm/glm.hpp>
#include <string>
#include <vector>
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<std::string, std::vector<std::string>> _shadowGroups;
std::map<std::string, GLuint> _depthMaps;
std::map<std::string, GLuint> _FBOs;
std::map<std::string, glm::dmat4> _vps;
std::map<std::string, GLuint> _fbos;
std::map<std::string, glm::dmat4> _viewports;
ghoul::opengl::ProgramObject* _depthMapProgram = nullptr;
};

View File

@@ -73,20 +73,6 @@ namespace {
constexpr glm::vec4 PosBufferClearVal = glm::vec4(1e32, 1e32, 1e32, 1.f);
constexpr std::array<const char*, 27> 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<const char*, 5> 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<std::filesystem::path> fragmentShader;
// [[codegen::verbatim(UseCacheInfo.description)]]
std::optional<bool> useCache;
// [[codegen::verbatim(CastShadowInfo.description)]]
std::optional<bool> 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<events::CustomEvent>("Cast Shadow Changed", "nada");
global::eventEngine->publishEvent<events::CustomEvent>("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<DirectionalLightSource*>(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

View File

@@ -120,7 +120,6 @@ private:
properties::BoolProperty _renderWireframe;
properties::FloatProperty _frustumSize;
properties::BoolProperty _useCache;
properties::BoolProperty _castShadow;
std::string _lightSource;
std::string _shadowGroup;

View File

@@ -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() {

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;

View File

@@ -23,6 +23,7 @@
****************************************************************************************/
#include <modules/globebrowsing/src/renderableglobe.h>
#include <modules/debugging/rendering/debugrenderer.h>
#include <modules/globebrowsing/src/basictypes.h>
#include <modules/globebrowsing/src/gpulayergroup.h>
@@ -52,7 +53,6 @@
#include <ghoul/opengl/openglstatecache.h>
#include <ghoul/opengl/programobject.h>
#include <ghoul/systemcapabilities/openglcapabilitiescomponent.h>
#include <ghoul/io/model/modelgeometry.h>
#include <numeric>
#include <queue>
#include <vector>
@@ -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> shadowGroup;
// Details about the rings of the globe, if it has any.
std::optional<ghoul::Dictionary> 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<ShadowComponent>(*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<DirectionalLightSource::DepthMapData> depthMapData;
for (const auto& [key, groups] : _shadowSpec) {
const auto node = global::renderEngine->scene()->sceneGraphNode(key);
if (node != nullptr) {
for (const std::pair<std::string, std::vector<std::string>>& p : _shadowSpec) {
const auto node = global::renderEngine->scene()->sceneGraphNode(p.first);
if (node) {
const auto src = dynamic_cast<DirectionalLightSource*>(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<const Chunk*>& global,
auto traversal = [](const Chunk& node, std::vector<const Chunk*>& global,
int& iGlobal, std::vector<const Chunk*>& local, int& iLocal, int cutoff,
std::vector<const Chunk*>& 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<int>(_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<Layer*>& 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<Layer*>& 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;
}
}
}

View File

@@ -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;