Merge pull request #2188 from OpenSpace/feature/atmosphere-stars-rendering

Fade out renderables in atmosphere
This commit is contained in:
sylvass
2022-07-21 15:01:57 -04:00
committed by GitHub
9 changed files with 135 additions and 5 deletions

View File

@@ -24,7 +24,8 @@ local sphere = {
RenderBinMode = "PreDeferredTransparent",
MirrorTexture = true,
FadeOutThreshold = 0.0015,
Background = true
Background = true,
DimInAtmosphere = true,
},
GUI = {
Name = "Milky Way Sphere",

View File

@@ -47,7 +47,8 @@ local stars = {
Vy = "vy",
Vz = "vz",
Speed = "speed"
}
},
DimInAtmosphere = true,
},
GUI = {
Name = "Stars",
@@ -84,7 +85,8 @@ local sunstar = {
Vy = "vy",
Vz = "vz",
Speed = "speed",
}
},
DimInAtmosphere = true,
},
GUI = {
Name = "Sun Star",

View File

@@ -74,6 +74,8 @@ public:
void setScaling(float scaling);
void setMaxFov(float fov);
void setParent(SceneGraphNode* parent);
// Atmosphere dimming factor determines how much an atmosphere dims objects
void setAtmosphereDimmingFactor(float atmosphereDimmingFactor);
// Relative mutators
void rotate(glm::dquat rotation);
@@ -93,6 +95,7 @@ public:
float sinMaxFov() const;
SceneGraphNode* parent() const;
float scaling() const;
float atmosphereDimmingFactor() const;
// @TODO this should simply be called viewMatrix!
// Or it needs to be changed so that it actually is combined. Right now it is
@@ -155,6 +158,8 @@ private:
SyncData<float> _scaling = 1.f;
SceneGraphNode* _parent = nullptr;
float _atmosphereDimmingFactor = 1.f;
// _focusPosition to be removed
glm::dvec3 _focusPosition = glm::dvec3(0.0);
float _maxFov = 0.f;

View File

@@ -107,6 +107,7 @@ protected:
properties::FloatProperty _opacity;
properties::FloatProperty _fade;
properties::StringProperty _renderableType;
properties::BoolProperty _dimInAtmosphere;
void setBoundingSphere(double boundingSphere);
void setInteractionSphere(double interactionSphere);

View File

@@ -25,13 +25,18 @@
#include <modules/atmosphere/rendering/renderableatmosphere.h>
#include <modules/atmosphere/rendering/atmospheredeferredcaster.h>
#include <openspace/camera/camera.h>
#include <openspace/documentation/documentation.h>
#include <openspace/documentation/verifier.h>
#include <openspace/engine/globals.h>
#include <openspace/navigation/navigationhandler.h>
#include <openspace/properties/property.h>
#include <openspace/rendering/deferredcastermanager.h>
#include <math.h>
namespace {
constexpr const float KM_TO_M = 1000.f;
constexpr openspace::properties::Property::PropertyInfo AtmosphereHeightInfo = {
"AtmosphereHeight",
"Atmosphere Height (KM)",
@@ -132,6 +137,18 @@ namespace {
"Enable/Disables hard shadows through the atmosphere"
};
constexpr openspace::properties::Property::PropertyInfo AtmosphereDimmingHeightInfo ={
"AtmosphereDimmingHeight",
"Atmosphere Dimming Height",
"Percentage of the atmosphere where other objects, such as the stars, are faded."
};
constexpr openspace::properties::Property::PropertyInfo SunsetAngleInfo = {
"AtmosphereDimmingSunsetAngle",
"Atmosphere Dimming Sunset Angle",
"The angle (degrees) between the Camera and the Sun where the sunset starts, and "
"the atmosphere starts to fade in objects such as the stars."
};
struct [[codegen::Dictionary(RenderableAtmosphere)]] Parameters {
struct ShadowGroup {
@@ -212,6 +229,12 @@ namespace {
std::optional<bool> saveCalculatedTextures;
};
std::optional<ATMDebug> debug;
// [[codegen::verbatim(AtmosphereDimmingHeightInfo.description)]]
std::optional<float> atmosphereDimmingHeight;
// [[codegen::verbatim(SunsetAngleInfo.description)]]
std::optional<glm::vec2> sunsetAngle;
};
#include "renderableatmosphere_codegen.cpp"
@@ -252,6 +275,10 @@ RenderableAtmosphere::RenderableAtmosphere(const ghoul::Dictionary& dictionary)
, _sunIntensity(SunIntensityInfo, 5.f, 0.1f, 1000.f)
, _sunFollowingCameraEnabled(EnableSunOnCameraPositionInfo, false)
, _hardShadowsEnabled(EclipseHardShadowsInfo, false)
, _atmosphereDimmingHeight(AtmosphereDimmingHeightInfo, 0.7f, 0.f, 1.f)
, _atmosphereDimmingSunsetAngle(SunsetAngleInfo,
glm::vec2(95.f, 100.f), glm::vec2(0.f), glm::vec2(180.f)
)
{
auto updateWithCalculation = [this]() {
_deferredCasterNeedsUpdate = true;
@@ -355,6 +382,17 @@ RenderableAtmosphere::RenderableAtmosphere(const ghoul::Dictionary& dictionary)
}
setBoundingSphere(_planetRadius * 1000.0);
_atmosphereDimmingHeight = p.atmosphereDimmingHeight.value_or(_atmosphereDimmingHeight);
addProperty(_atmosphereDimmingHeight);
_atmosphereDimmingSunsetAngle = p.sunsetAngle.value_or(
_atmosphereDimmingSunsetAngle
);
_atmosphereDimmingSunsetAngle.setViewOption(
properties::Property::ViewOptions::MinMaxRange
);
addProperty(_atmosphereDimmingSunsetAngle);
}
void RenderableAtmosphere::deinitializeGL() {
@@ -406,6 +444,55 @@ void RenderableAtmosphere::update(const UpdateData& data) {
glm::dmat4 modelTransform = computeModelTransformMatrix(data.modelTransform);
_deferredcaster->setModelTransform(modelTransform);
_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<float>(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<float>(
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
);
}
}
void RenderableAtmosphere::updateAtmosphereParameters() {

View File

@@ -31,6 +31,7 @@
#include <openspace/properties/scalar/boolproperty.h>
#include <openspace/properties/scalar/intproperty.h>
#include <openspace/properties/scalar/floatproperty.h>
#include <openspace/properties/vector/vec2property.h>
#include <openspace/properties/vector/vec3property.h>
#include <openspace/util/updatestructures.h>
#include <ghoul/opengl/textureunit.h>
@@ -95,6 +96,10 @@ private:
properties::BoolProperty _sunFollowingCameraEnabled;
properties::BoolProperty _hardShadowsEnabled;
// Atmosphere dimming
properties::FloatProperty _atmosphereDimmingHeight;
properties::Vec2Property _atmosphereDimmingSunsetAngle;
float _planetRadius = 0.f;
float _mieScattExtPropCoefProp = 1.f;

View File

@@ -156,6 +156,14 @@ float Camera::sinMaxFov() const {
return _cachedSinMaxFov.datum;
}
void Camera::setAtmosphereDimmingFactor(float atmosphereDimmingFactor) {
_atmosphereDimmingFactor = atmosphereDimmingFactor;
}
float Camera::atmosphereDimmingFactor() const {
return _atmosphereDimmingFactor;
}
SceneGraphNode* Camera::parent() const {
return _parent;
}

View File

@@ -24,11 +24,13 @@
#include <openspace/rendering/renderable.h>
#include <openspace/camera/camera.h>
#include <openspace/documentation/documentation.h>
#include <openspace/documentation/verifier.h>
#include <openspace/engine/globals.h>
#include <openspace/events/event.h>
#include <openspace/events/eventengine.h>
#include <openspace/navigation/navigationhandler.h>
#include <openspace/scene/scenegraphnode.h>
#include <openspace/util/factorymanager.h>
#include <openspace/util/memorymanager.h>
@@ -81,6 +83,14 @@ namespace {
openspace::properties::Property::Visibility::Developer
};
constexpr openspace::properties::Property::PropertyInfo DimInAtmosphereInfo = {
"DimInAtmosphere",
"Dim In Atmosphere",
"Enables/Disables if the object should be dimmed if the camera is in an "
"atmosphere.",
openspace::properties::Property::Visibility::Developer
};
struct [[codegen::Dictionary(Renderable)]] Parameters {
// [[codegen::verbatim(EnabledInfo.description)]]
std::optional<bool> enabled;
@@ -106,6 +116,9 @@ namespace {
// [[codegen::verbatim(RenderableRenderBinModeInfo.description)]]
std::optional<RenderBinMode> renderBinMode;
// [[codegen::verbatim(DimInAtmosphereInfo.description)]]
std::optional<bool> dimInAtmosphere;
};
#include "renderable_codegen.cpp"
} // namespace
@@ -146,6 +159,7 @@ Renderable::Renderable(const ghoul::Dictionary& dictionary)
, _opacity(OpacityInfo, 1.f, 0.f, 1.f)
, _fade(FadeInfo, 1.f, 0.f, 1.f)
, _renderableType(RenderableTypeInfo, "Renderable")
, _dimInAtmosphere(DimInAtmosphereInfo, false)
{
ZoneScoped
@@ -193,6 +207,9 @@ Renderable::Renderable(const ghoul::Dictionary& dictionary)
if (p.renderBinMode.has_value()) {
setRenderBin(codegen::map<Renderable::RenderBin>(*p.renderBinMode));
}
_dimInAtmosphere = p.dimInAtmosphere.value_or(_dimInAtmosphere);
addProperty(_dimInAtmosphere);
}
void Renderable::initialize() {}
@@ -292,7 +309,10 @@ void Renderable::registerUpdateRenderBinFromOpacity() {
}
float Renderable::opacity() const {
return _opacity * _fade;
// Rendering should depend on if camera is in the atmosphere and if camera is at the
// dark part of the globe
return _dimInAtmosphere ?
_opacity * _fade * global::navigationHandler->camera()->atmosphereDimmingFactor() :
_opacity * _fade;
}
} // namespace openspace

View File

@@ -334,6 +334,7 @@ void Scene::update(const UpdateData& data) {
if (_dirtyNodeRegistry) {
updateNodeRegistry();
}
_camera->setAtmosphereDimmingFactor(1.f);
for (SceneGraphNode* node : _topologicallySortedNodes) {
try {
node->update(data);