Add the ability to specifiy local Sun position for the RenderableGlobe and RenderableAtmosphere (#3137)

* Add the ability to specifiy local Sun position for the RenderableGlobe and RenderableAtmosphere

Note that for planets with atmospheres, the SunNode has to be specified for _both_ the globe and the atmosphere separately

 - Closes #1745
 - Closes #2243
This commit is contained in:
Alexander Bock
2024-04-04 16:16:01 +02:00
committed by GitHub
parent a82af895d7
commit 9558f2bcbb
7 changed files with 113 additions and 13 deletions
@@ -382,7 +382,9 @@ void AtmosphereDeferredcaster::preRaycast(const RenderData& data, const Deferred
invModelMatrix * glm::dvec4(data.camera.eyePositionVec3(), 1.0);
program.setUniform(_uniformCache.camPosObj, glm::dvec3(camPosObjCoords));
SceneGraphNode* node = sceneGraph()->sceneGraphNode("Sun");
// For the lighting we use the provided node, or the Sun
SceneGraphNode* node =
_lightSourceNode ? _lightSourceNode : sceneGraph()->sceneGraphNode("Sun");
const glm::dvec3 sunPosWorld = node ? node->worldPosition() : glm::dvec3(0.0);
glm::dvec3 sunPosObj;
@@ -574,7 +576,8 @@ void AtmosphereDeferredcaster::setParameters(float atmosphereRadius, float plane
glm::vec3 ozoneExtinctionCoefficients,
glm::vec3 mieScatteringCoefficients,
glm::vec3 mieExtinctionCoefficients,
bool sunFollowing, float sunAngularSize)
bool sunFollowing, float sunAngularSize,
SceneGraphNode* lightSourceNode)
{
_atmosphereRadius = atmosphereRadius;
_atmospherePlanetRadius = planetRadius;
@@ -592,6 +595,8 @@ void AtmosphereDeferredcaster::setParameters(float atmosphereRadius, float plane
_mieExtinctionCoeff = std::move(mieExtinctionCoefficients);
_sunFollowingCameraEnabled = sunFollowing;
_sunAngularSize = sunAngularSize;
// The light source may be nullptr which we interpret to mean a position of (0,0,0)
_lightSourceNode = lightSourceNode;
}
void AtmosphereDeferredcaster::setHardShadows(bool enabled) {
@@ -88,7 +88,7 @@ public:
float mieHeightScale, float miePhaseConstant, float sunRadiance,
glm::vec3 rayScatteringCoefficients, glm::vec3 ozoneExtinctionCoefficients,
glm::vec3 mieScatteringCoefficients, glm::vec3 mieExtinctionCoefficients,
bool sunFollowing, float sunAngularSize);
bool sunFollowing, float sunAngularSize, SceneGraphNode* lightSourceNode);
void setHardShadows(bool enabled);
@@ -142,6 +142,7 @@ private:
float _miePhaseConstant = 0.f;
float _sunRadianceIntensity = 5.f;
float _sunAngularSize = 0.3f;
SceneGraphNode* _lightSourceNode = nullptr;
glm::vec3 _rayleighScatteringCoeff = glm::vec3(0.f);
glm::vec3 _ozoneExtinctionCoeff = glm::vec3(0.f);
@@ -30,6 +30,7 @@
#include <openspace/documentation/verifier.h>
#include <openspace/engine/globals.h>
#include <openspace/navigation/navigationhandler.h>
#include <openspace/query/query.h>
#include <ghoul/misc/profiling.h>
#include <openspace/properties/property.h>
#include <openspace/rendering/deferredcastermanager.h>
@@ -182,6 +183,15 @@ namespace {
openspace::properties::Property::Visibility::AdvancedUser
};
constexpr openspace::properties::Property::PropertyInfo LightSourceNodeInfo = {
"LightSourceNode",
"Name of the light source",
"This value is the name of a scene graph node that should be used as the source "
"of illumination for the atmosphere. If this value is not specified, the solar "
"system's Sun is used instead",
openspace::properties::Property::Visibility::AdvancedUser
};
struct [[codegen::Dictionary(RenderableAtmosphere)]] Parameters {
struct ShadowGroup {
// Individual light sources
@@ -270,6 +280,9 @@ namespace {
// [[codegen::verbatim(SunAngularSize.description)]]
std::optional<float> sunAngularSize [[codegen::inrange(0.0, 180.0)]];
// [[codegen::verbatim(LightSourceNodeInfo.description)]]
std::optional<std::string> lightSourceNode;
};
#include "renderableatmosphere_codegen.cpp"
@@ -311,6 +324,7 @@ RenderableAtmosphere::RenderableAtmosphere(const ghoul::Dictionary& dictionary)
, _sunFollowingCameraEnabled(EnableSunOnCameraPositionInfo, false)
, _hardShadowsEnabled(EclipseHardShadowsInfo, false)
, _sunAngularSize(SunAngularSize, 0.3f, 0.f, 180.f)
, _lightSourceNodeName(LightSourceNodeInfo)
, _atmosphereDimmingHeight(AtmosphereDimmingHeightInfo, 0.7f, 0.f, 1.f)
, _atmosphereDimmingSunsetAngle(
SunsetAngleInfo,
@@ -435,6 +449,30 @@ RenderableAtmosphere::RenderableAtmosphere(const ghoul::Dictionary& dictionary)
_sunAngularSize = p.sunAngularSize.value_or(_sunAngularSize);
_sunAngularSize.onChange(updateWithoutCalculation);
addProperty(_sunAngularSize);
_lightSourceNodeName.onChange([this]() {
if (_lightSourceNodeName.value().empty()) {
_lightSourceNode = nullptr;
return;
}
SceneGraphNode* n = sceneGraphNode(_lightSourceNodeName);
if (!n) {
LERRORC(
"RenderabeAtmosphere",
std::format(
"Could not find node '{}' as illumination for '{}'",
_lightSourceNodeName.value(), identifier()
)
);
}
else {
_lightSourceNode = n;
_deferredCasterNeedsUpdate = true;
}
});
_lightSourceNodeName = p.lightSourceNode.value_or("");
addProperty(_lightSourceNodeName);
}
void RenderableAtmosphere::deinitializeGL() {
@@ -510,7 +548,8 @@ void RenderableAtmosphere::updateAtmosphereParameters() {
_mieScatteringCoeff,
_mieExtinctionCoeff,
_sunFollowingCameraEnabled,
_sunAngularSize
_sunAngularSize,
_lightSourceNode
);
_deferredcaster->setHardShadows(_hardShadowsEnabled);
}
@@ -97,6 +97,8 @@ private:
properties::BoolProperty _sunFollowingCameraEnabled;
properties::BoolProperty _hardShadowsEnabled;
properties::FloatProperty _sunAngularSize;
SceneGraphNode* _lightSourceNode = nullptr;
properties::StringProperty _lightSourceNodeName;
// Atmosphere dimming
properties::FloatProperty _atmosphereDimmingHeight;
+3 -2
View File
@@ -295,8 +295,9 @@ void createExoplanetSystem(const std::string& starName,
"Enabled = " + enabled + ","
"Radii = " + std::to_string(planetRadius) + "," // in meters
"SegmentsPerPatch = 64,"
"PerformShading = false,"
"Layers = {}"
"PerformShading = true,"
"Layers = {},"
"LightSourceNode = '" + starIdentifier + "'"
"},"
"Transform = { "
"Translation = " + planetKeplerTranslation + ""
+54 -6
View File
@@ -34,6 +34,7 @@
#include <openspace/documentation/verifier.h>
#include <openspace/engine/globals.h>
#include <openspace/interaction/sessionrecording.h>
#include <openspace/query/query.h>
#include <openspace/rendering/renderengine.h>
#include <openspace/scene/scenegraphnode.h>
#include <openspace/scene/scene.h>
@@ -180,6 +181,15 @@ namespace {
openspace::properties::Property::Visibility::AdvancedUser
};
constexpr openspace::properties::Property::PropertyInfo LightSourceNodeInfo = {
"LightSourceNode",
"Name of the light source",
"This value is the name of a scene graph node that should be used as the source "
"of illumination for the globe. If this value is not specified, the solar "
"system's Sun is used instead",
openspace::properties::Property::Visibility::AdvancedUser
};
constexpr openspace::properties::Property::PropertyInfo EclipseInfo = {
"Eclipse",
"Eclipse",
@@ -310,6 +320,9 @@ namespace {
std::optional<ghoul::Dictionary> shadows
[[codegen::reference("globebrowsing_shadows_component")]];
// [[codegen::verbatim(LightSourceNodeInfo.description)]]
std::optional<std::string> lightSourceNode;
};
#include "renderableglobe_codegen.cpp"
} // namespace
@@ -531,6 +544,24 @@ bool intersects(const AABB3& bb, const AABB3& o) {
&& (bb.min.z <= o.max.z) && (o.min.z <= bb.max.z);
}
/**
* Calculates the direction towards the local light source. If \p illumination is a
* `nullptr`, it is interpreted to be (0,0,0)
*/
glm::dvec3 directionToLightSource(const glm::dvec3& pos, SceneGraphNode* lightSource) {
// For the lighting we use the provided node, or the Sun
SceneGraphNode* node =
lightSource ? lightSource : sceneGraph()->sceneGraphNode("Sun");
if (lightSource) {
return lightSource->worldPosition() - pos;
}
else {
const glm::dvec3 dir = length(pos) > 0.0 ? glm::normalize(-pos) : glm::dvec3(0.0);
return dir;
}
}
} // namespace
Chunk::Chunk(const TileIndex& ti)
@@ -573,6 +604,7 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
, _grid(DefaultSkirtedGridSegments, DefaultSkirtedGridSegments)
, _leftRoot(Chunk(LeftHemisphereIndex))
, _rightRoot(Chunk(RightHemisphereIndex))
, _lightSourceNodeName(LightSourceNodeInfo)
{
const Parameters p = codegen::bake<Parameters>(dictionary);
@@ -615,6 +647,26 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
addProperty(_generalProperties.useAccurateNormals);
addProperty(_generalProperties.renderAtDistance);
_lightSourceNodeName.onChange([this]() {
if (_lightSourceNodeName.value().empty()) {
_lightSourceNode = nullptr;
return;
}
SceneGraphNode* n = sceneGraphNode(_lightSourceNodeName);
if (!n) {
LERROR(std::format(
"Could not find node '{}' as illumination for '{}'",
_lightSourceNodeName.value(), identifier()
));
}
else {
_lightSourceNode = n;
}
});
_lightSourceNodeName = p.lightSourceNode.value_or("");
addProperty(_lightSourceNodeName);
if (p.shadowGroup.has_value()) {
std::vector<Ellipsoid::ShadowConfiguration> shadowConfArray;
for (const Parameters::ShadowGroup::Source& source : p.shadowGroup->sources) {
@@ -1165,9 +1217,7 @@ void RenderableGlobe::renderChunks(const RenderData& data, RendererTasks&,
if (nightLayersActive || waterLayersActive || _generalProperties.performShading) {
const glm::dvec3 directionToSunWorldSpace =
length(data.modelTransform.translation) > 0.0 ?
glm::normalize(-data.modelTransform.translation) :
glm::dvec3(0.0);
directionToLightSource(data.modelTransform.translation, _lightSourceNode);
const glm::vec3 directionToSunCameraSpace = glm::vec3(viewTransform *
glm::dvec4(directionToSunWorldSpace, 0));
@@ -1193,9 +1243,7 @@ void RenderableGlobe::renderChunks(const RenderData& data, RendererTasks&,
if (nightLayersActive || waterLayersActive || _generalProperties.performShading) {
const glm::dvec3 directionToSunWorldSpace =
length(data.modelTransform.translation) > 0.0 ?
glm::normalize(-data.modelTransform.translation) :
glm::dvec3(0.0);
directionToLightSource(data.modelTransform.translation, _lightSourceNode);
const glm::vec3 directionToSunCameraSpace = glm::vec3(viewTransform *
glm::dvec4(directionToSunWorldSpace, 0));
+5 -1
View File
@@ -37,9 +37,10 @@
#include <modules/globebrowsing/src/shadowcomponent.h>
#include <modules/globebrowsing/src/skirtedgrid.h>
#include <modules/globebrowsing/src/tileindex.h>
#include <openspace/properties/scalar/boolproperty.h>
#include <openspace/properties/scalar/floatproperty.h>
#include <openspace/properties/scalar/intproperty.h>
#include <openspace/properties/scalar/boolproperty.h>
#include <openspace/properties/stringproperty.h>
#include <ghoul/misc/memorypool.h>
#include <ghoul/opengl/uniformcache.h>
#include <cstddef>
@@ -288,6 +289,9 @@ private:
std::array<GPULayerGroup, LayerManager::NumLayerGroups> gpuLayerGroups;
} _localRenderer;
SceneGraphNode* _lightSourceNode = nullptr;
properties::StringProperty _lightSourceNodeName;
bool _shadersNeedRecompilation = true;
bool _lodScaleFactorDirty = true;
bool _chunkCornersDirty = true;