From 52e316b03de37d0733b84a192b865e6955674b65 Mon Sep 17 00:00:00 2001 From: Ylva Selling Date: Fri, 9 Jun 2023 16:21:12 -0400 Subject: [PATCH] Move calculate dimming coefficient to a function and also include calculations for eclipse shadows --- .../rendering/renderableatmosphere.cpp | 125 +++++++++++------- .../rendering/renderableatmosphere.h | 1 + 2 files changed, 77 insertions(+), 49 deletions(-) diff --git a/modules/atmosphere/rendering/renderableatmosphere.cpp b/modules/atmosphere/rendering/renderableatmosphere.cpp index 7894d814de..0458e8cd6d 100644 --- a/modules/atmosphere/rendering/renderableatmosphere.cpp +++ b/modules/atmosphere/rendering/renderableatmosphere.cpp @@ -34,6 +34,7 @@ #include #include #include +#include namespace { constexpr float KM_TO_M = 1000.f; @@ -471,55 +472,7 @@ void RenderableAtmosphere::update(const UpdateData& data) { _deferredcaster->setModelTransform(modelTransform); _deferredcaster->setOpacity(opacity()); _deferredcaster->update(data); - - // Calculate atmosphere dimming coefficient - // Calculate if the camera is in the atmosphere and if it is in the fading region - float atmosphereDimming = 1.f; - glm::dvec3 cameraPos = global::navigationHandler->camera()->positionVec3(); - glm::dvec3 planetPos = glm::dvec3(modelTransform * glm::dvec4(0.0, 0.0, 0.0, 1.0)); - float cameraDistance = static_cast(glm::distance(planetPos, cameraPos)); - // Atmosphere height is in KM - float atmosphereEdge = KM_TO_M * (_planetRadius + _atmosphereHeight); - // Height of the atmosphere where the objects will be faded - float atmosphereFadingHeight = KM_TO_M * _atmosphereDimmingHeight * _atmosphereHeight; - float atmosphereInnerEdge = atmosphereEdge - atmosphereFadingHeight; - bool cameraIsInAtmosphere = cameraDistance < atmosphereEdge; - bool cameraIsInFadingRegion = cameraDistance > atmosphereInnerEdge; - - // Check if camera is in sunset - glm::dvec3 normalUnderCamera = glm::normalize(cameraPos - planetPos); - glm::dvec3 vecToSun = glm::normalize(-planetPos); - float cameraSunAngle = glm::degrees(static_cast( - glm::acos(glm::dot(vecToSun, normalUnderCamera)) - )); - float sunsetStart = _atmosphereDimmingSunsetAngle.value().x; - float sunsetEnd = _atmosphereDimmingSunsetAngle.value().y; - // If cameraSunAngle is more than 90 degrees, we are in shaded part of globe - bool cameraIsInSun = cameraSunAngle <= sunsetEnd; - bool cameraIsInSunset = cameraSunAngle > sunsetStart && cameraIsInSun; - - // Fade if camera is inside the atmosphere - if (cameraIsInAtmosphere && cameraIsInSun) { - // If camera is in fading part of the atmosphere - // Fade with regards to altitude - if (cameraIsInFadingRegion) { - // Fading - linear interpolation - atmosphereDimming = (cameraDistance - atmosphereInnerEdge) / - atmosphereFadingHeight; - } - else { - // Camera is below fading region - atmosphere dims objects completely - atmosphereDimming = 0.0; - } - if (cameraIsInSunset) { - // Fading - linear interpolation - atmosphereDimming = (cameraSunAngle - sunsetStart) / - (sunsetEnd - sunsetStart); - } - global::navigationHandler->camera()->setAtmosphereDimmingFactor( - atmosphereDimming - ); - } + setDimmingCoefficient(computeModelTransformMatrix(data.modelTransform)); } void RenderableAtmosphere::updateAtmosphereParameters() { @@ -546,4 +499,78 @@ void RenderableAtmosphere::updateAtmosphereParameters() { _deferredcaster->setHardShadows(_hardShadowsEnabled); } +// Calculate atmosphere dimming coefficient +void RenderableAtmosphere::setDimmingCoefficient(const glm::dmat4& modelTransform) { + // Calculate if the camera is in the atmosphere and if it is in the sunny region + glm::dvec3 cameraPos = global::navigationHandler->camera()->positionVec3(); + glm::dvec3 planetPos = glm::dvec3(modelTransform * glm::dvec4(0.0, 0.0, 0.0, 1.0)); + float cameraDistance = static_cast(glm::distance(planetPos, cameraPos)); + glm::dvec3 normalUnderCamera = glm::normalize(cameraPos - planetPos); + glm::dvec3 vecToSun = glm::normalize(-planetPos); + + float cameraSunAngle = glm::degrees(static_cast( + glm::acos(glm::dot(vecToSun, normalUnderCamera)) + )); + float sunsetEnd = _atmosphereDimmingSunsetAngle.value().y; + + // If cameraSunAngle is more than 90 degrees, we are in shaded part of globe + bool cameraIsInSun = cameraSunAngle <= sunsetEnd; + // Atmosphere height is in KM + float atmosphereEdge = KM_TO_M * (_planetRadius + _atmosphereHeight); + bool cameraIsInAtmosphere = cameraDistance < atmosphereEdge; + + // Don't fade if camera is not in the sunny part of an atmosphere + if (!(cameraIsInAtmosphere && cameraIsInSun)) { + return; + } + // Else we need to fade the objects + // Height of the atmosphere where the objects will be faded + float atmosphereFadingHeight = KM_TO_M * _atmosphereDimmingHeight * _atmosphereHeight; + float atmosphereInnerEdge = atmosphereEdge - atmosphereFadingHeight; + bool cameraIsInFadingRegion = cameraDistance > atmosphereInnerEdge; + + // Check if camera is in sunset + float sunsetStart = _atmosphereDimmingSunsetAngle.value().x; + bool cameraIsInSunset = cameraSunAngle > sunsetStart && cameraIsInSun; + + // See if we are inside of an eclipse shadow + float eclipseShadow = _deferredcaster->eclipseShadow(cameraPos, false); + bool cameraIsInEclipse = std::abs(eclipseShadow - 1.0f) > glm::epsilon(); + // Invert shadow and multiply with itself to make it more narrow + eclipseShadow = std::pow(1.0f - eclipseShadow, 2.0f); + float atmosphereDimming = 0.f; + + if (cameraIsInSunset) { + // Fading - linear interpolation + atmosphereDimming = (cameraSunAngle - sunsetStart) / + (sunsetEnd - sunsetStart); + } + else if (cameraIsInFadingRegion && cameraIsInEclipse) { + // Fade with regards to altitude & eclipse shadow + // Fading - linear interpolation + float fading = (cameraDistance - atmosphereInnerEdge) / + atmosphereFadingHeight; + atmosphereDimming = std::clamp(eclipseShadow + fading, 0.0f, 1.0f); + } + else if (cameraIsInFadingRegion) { + // Fade with regards to altitude + // Fading - linear interpolation + atmosphereDimming = (cameraDistance - atmosphereInnerEdge) / + atmosphereFadingHeight; + } + else if (cameraIsInEclipse) { + atmosphereDimming = eclipseShadow; + } + else { + // Camera is below fading region - atmosphere dims objects completely + atmosphereDimming = 0.0f; + + } + // Calculate dimming coefficient for stars, labels etc that are dimmed in the + // atmosphere + global::navigationHandler->camera()->setAtmosphereDimmingFactor( + atmosphereDimming + ); +} + } // namespace openspace diff --git a/modules/atmosphere/rendering/renderableatmosphere.h b/modules/atmosphere/rendering/renderableatmosphere.h index acee718216..66843f16f1 100644 --- a/modules/atmosphere/rendering/renderableatmosphere.h +++ b/modules/atmosphere/rendering/renderableatmosphere.h @@ -79,6 +79,7 @@ public: private: glm::dmat4 computeModelTransformMatrix(const openspace::TransformData& data); void updateAtmosphereParameters(); + void dimmingCoefficient(const glm::dmat4& modelTransform); properties::FloatProperty _atmosphereHeight; properties::FloatProperty _groundAverageReflectance;