diff --git a/data/assets/scene/milkyway/exoplanets/exoplanets_textures.asset b/data/assets/scene/milkyway/exoplanets/exoplanets_textures.asset index c2898923b3..e86d14c73d 100644 --- a/data/assets/scene/milkyway/exoplanets/exoplanets_textures.asset +++ b/data/assets/scene/milkyway/exoplanets/exoplanets_textures.asset @@ -1,6 +1,8 @@ local habitableZoneTextures = asset.require('./../habitable_zones/habitable_zone_textures').TexturesPath +local sunTextures = asset.require('scene/solarsystem/sun/sun_textures').TexturesPath + local TexturesPath = asset.syncedResource({ Name = "Exoplanet Textures", Type = "HttpSynchronization", @@ -13,27 +15,34 @@ asset.onInitialize(function () local noDataTexture = TexturesPath .. "/grid-32.png" local discTexture = TexturesPath .. "/disc_bw_texture.png" + local starGlareTexture = sunTextures .. "/halo.png" + local hzTexture = habitableZoneTextures .. "/hot_to_cold_faded.png" -- Set the default textures used for the exoplanet system creation -- (Check if already set, to not override value in config file) local p = "Modules.Exoplanets.StarTexture"; - if(openspace.getPropertyValue(p) == "") then + if (openspace.getPropertyValue(p) == "") then openspace.setPropertyValueSingle(p, starTexture) end + local p = "Modules.Exoplanets.StarGlareTexture"; + if (openspace.getPropertyValue(p) == "") then + openspace.setPropertyValueSingle(p, starGlareTexture) + end + p = "Modules.Exoplanets.NoDataTexture"; - if(openspace.getPropertyValue(p) == "") then + if (openspace.getPropertyValue(p) == "") then openspace.setPropertyValueSingle(p, noDataTexture) end p = "Modules.Exoplanets.OrbitDiscTexture"; - if(openspace.getPropertyValue(p) == "") then + if (openspace.getPropertyValue(p) == "") then openspace.setPropertyValueSingle(p, discTexture) end p = "Modules.Exoplanets.HabitableZoneTexture"; - if(openspace.getPropertyValue(p) == "") then + if (openspace.getPropertyValue(p) == "") then openspace.setPropertyValueSingle(p, hzTexture) end end) diff --git a/modules/base/rendering/renderableplane.cpp b/modules/base/rendering/renderableplane.cpp index 5254b1f8b4..0e10ee8f2a 100644 --- a/modules/base/rendering/renderableplane.cpp +++ b/modules/base/rendering/renderableplane.cpp @@ -70,6 +70,13 @@ namespace { "This determines the blending mode that is applied to this plane." }; + constexpr openspace::properties::Property::PropertyInfo MultiplyColorInfo = { + "MultiplyColor", + "Multiply Color", + "If set, the plane's texture is multiplied with this color. " + "Useful for applying a color grayscale images." + }; + struct [[codegen::Dictionary(RenderablePlane)]] Parameters { // [[codegen::verbatim(BillboardInfo.description)]] std::optional billboard; @@ -83,6 +90,9 @@ namespace { }; // [[codegen::verbatim(BlendModeInfo.description)]] std::optional blendMode; + + // [[codegen::verbatim(BlendModeInfo.description)]] + std::optional multiplyColor [[codegen::color()]]; }; #include "renderableplane_codegen.cpp" } // namespace @@ -100,6 +110,7 @@ RenderablePlane::RenderablePlane(const ghoul::Dictionary& dictionary) , _blendMode(BlendModeInfo, properties::OptionProperty::DisplayType::Dropdown) , _billboard(BillboardInfo, false) , _size(SizeInfo, 10.f, 0.f, 1e25f) + , _multiplyColor(MultiplyColorInfo, glm::vec3(1.f), glm::vec3(0.f), glm::vec3(1.f)) { Parameters p = codegen::bake(dictionary); @@ -141,11 +152,15 @@ RenderablePlane::RenderablePlane(const ghoul::Dictionary& dictionary) } } + _multiplyColor = p.multiplyColor.value_or(_multiplyColor); + addProperty(_billboard); addProperty(_size); _size.onChange([this](){ _planeIsDirty = true; }); + addProperty(_multiplyColor); + setBoundingSphere(_size); } @@ -238,6 +253,8 @@ void RenderablePlane::render(const RenderData& data, RendererTasks&) { _shader->setUniform("texture1", unit); + _shader->setUniform("multiplyColor", _multiplyColor); + bool usingFramebufferRenderer = global::renderEngine->rendererImplementation() == RenderEngine::RendererImplementation::Framebuffer; diff --git a/modules/base/rendering/renderableplane.h b/modules/base/rendering/renderableplane.h index 12d9d50ab1..a83f2f80bd 100644 --- a/modules/base/rendering/renderableplane.h +++ b/modules/base/rendering/renderableplane.h @@ -31,6 +31,7 @@ #include #include #include +#include #include namespace ghoul::filesystem { class File; } @@ -75,6 +76,7 @@ private: properties::BoolProperty _billboard; properties::FloatProperty _size; + properties::Vec3Property _multiplyColor; ghoul::opengl::ProgramObject* _shader = nullptr; diff --git a/modules/base/shaders/plane_fs.glsl b/modules/base/shaders/plane_fs.glsl index f739d6ac32..b11a3da7bc 100644 --- a/modules/base/shaders/plane_fs.glsl +++ b/modules/base/shaders/plane_fs.glsl @@ -32,7 +32,7 @@ in vec3 vs_gNormal; uniform sampler2D texture1; uniform bool additiveBlending; uniform float opacity = 1.0; - +uniform vec3 multiplyColor; Fragment getFragment() { Fragment frag; @@ -43,6 +43,8 @@ Fragment getFragment() { frag.color = texture(texture1, vec2(1 - vs_st.s, vs_st.t)); } + frag.color.rgb *= multiplyColor; + frag.color.a *= opacity; if (frag.color.a == 0.0) { discard; @@ -54,9 +56,9 @@ Fragment getFragment() { frag.blend = BLEND_MODE_ADDITIVE; } - // G-Buffer + // G-Buffer frag.gPosition = vs_gPosition; frag.gNormal = vec4(vs_gNormal, 1.0); - + return frag; } diff --git a/modules/exoplanets/exoplanetshelper.cpp b/modules/exoplanets/exoplanetshelper.cpp index 17bf9b5fe8..580dd7b5cd 100644 --- a/modules/exoplanets/exoplanetshelper.cpp +++ b/modules/exoplanets/exoplanetshelper.cpp @@ -56,7 +56,7 @@ bool hasSufficientData(const ExoplanetDataEntry& p) { return validStarPosition && hasSemiMajorAxis && hasOrbitalPeriod; } -glm::vec3 starColor(float bv) { +glm::vec3 computeStarColor(float bv) { std::ifstream colorMap(absPath(BvColormapPath), std::ios::in); if (!colorMap.good()) { diff --git a/modules/exoplanets/exoplanetshelper.h b/modules/exoplanets/exoplanetshelper.h index 527bdf4b01..233c16443d 100644 --- a/modules/exoplanets/exoplanetshelper.h +++ b/modules/exoplanets/exoplanetshelper.h @@ -99,7 +99,7 @@ bool isValidPosition(const glm::vec3& pos); bool hasSufficientData(const ExoplanetDataEntry& p); // Compute star color in RGB from b-v color index -glm::vec3 starColor(float bv); +glm::vec3 computeStarColor(float bv); glm::dmat4 computeOrbitPlaneRotationMatrix(float i, float bigom = 180.f, float omega = 90.f); diff --git a/modules/exoplanets/exoplanetsmodule.cpp b/modules/exoplanets/exoplanetsmodule.cpp index 80909f7e86..6b2c4258be 100644 --- a/modules/exoplanets/exoplanetsmodule.cpp +++ b/modules/exoplanets/exoplanetsmodule.cpp @@ -50,6 +50,13 @@ namespace { "The path to a grayscale image that is used for the host star surfaces" }; + constexpr const openspace::properties::Property::PropertyInfo StarGlareTextureInfo = { + "StarGlareTexture", + "Star Glare Texture", + "The path to a grayscale image that is used for the glare effect of the " + "host stars" + }; + constexpr const openspace::properties::Property::PropertyInfo NoDataTextureInfo = { "NoDataTexture", "No Data Star Texture", @@ -119,6 +126,9 @@ namespace { // [[codegen::verbatim(StarTextureInfo.description)]] std::optional starTexture; + // [[codegen::verbatim(StarGlareTextureInfo.description)]] + std::optional starGlareTexture; + // [[codegen::verbatim(NoDataTextureInfo.description)]] std::optional noDataTexture; @@ -151,6 +161,7 @@ ExoplanetsModule::ExoplanetsModule() : OpenSpaceModule(Name) , _exoplanetsDataFolder(DataFolderInfo) , _starTexturePath(StarTextureInfo) + , _starGlareTexturePath(StarGlareTextureInfo) , _noDataTexturePath(NoDataTextureInfo) , _orbitDiscTexturePath(OrbitDiscTextureInfo) , _habitableZoneTexturePath(HabitableZoneTextureInfo) @@ -163,12 +174,15 @@ ExoplanetsModule::ExoplanetsModule() addProperty(_exoplanetsDataFolder); addProperty(_starTexturePath); + addProperty(_starGlareTexturePath); addProperty(_noDataTexturePath); addProperty(_orbitDiscTexturePath); addProperty(_habitableZoneTexturePath); + addProperty(_showComparisonCircle); addProperty(_showHabitableZone); addProperty(_useOptimisticZone); + addProperty(_habitableZoneOpacity); } @@ -188,6 +202,10 @@ std::string ExoplanetsModule::starTexturePath() const { return _starTexturePath; } +std::string ExoplanetsModule::starGlareTexturePath() const { + return _starGlareTexturePath; +} + std::string ExoplanetsModule::noDataTexturePath() const { return _noDataTexturePath; } @@ -257,6 +275,7 @@ scripting::LuaLibrary ExoplanetsModule::luaLibrary() const { void ExoplanetsModule::internalInitialize(const ghoul::Dictionary& dict) { const Parameters p = codegen::bake(dict); + if (p.dataFolder.has_value()) { _exoplanetsDataFolder = p.dataFolder.value().string(); } @@ -265,6 +284,10 @@ void ExoplanetsModule::internalInitialize(const ghoul::Dictionary& dict) { _starTexturePath = p.starTexture.value().string(); } + if (p.starGlareTexture.has_value()) { + _starGlareTexturePath = p.starGlareTexture.value().string(); + } + if (p.noDataTexture.has_value()) { _noDataTexturePath = p.noDataTexture.value().string(); } diff --git a/modules/exoplanets/exoplanetsmodule.h b/modules/exoplanets/exoplanetsmodule.h index 3ff564d581..fd2ef956f1 100644 --- a/modules/exoplanets/exoplanetsmodule.h +++ b/modules/exoplanets/exoplanetsmodule.h @@ -44,6 +44,7 @@ public: std::string exoplanetsDataPath() const; std::string lookUpTablePath() const; std::string starTexturePath() const; + std::string starGlareTexturePath() const; std::string noDataTexturePath() const; std::string orbitDiscTexturePath() const; std::string habitableZoneTexturePath() const; @@ -60,12 +61,15 @@ protected: properties::StringProperty _exoplanetsDataFolder; properties::StringProperty _starTexturePath; + properties::StringProperty _starGlareTexturePath; properties::StringProperty _noDataTexturePath; properties::StringProperty _orbitDiscTexturePath; properties::StringProperty _habitableZoneTexturePath; + properties::BoolProperty _showComparisonCircle; properties::BoolProperty _showHabitableZone; properties::BoolProperty _useOptimisticZone; + properties::FloatProperty _habitableZoneOpacity; }; diff --git a/modules/exoplanets/exoplanetsmodule_lua.inl b/modules/exoplanets/exoplanetsmodule_lua.inl index 950981ece1..26d40cde45 100644 --- a/modules/exoplanets/exoplanetsmodule_lua.inl +++ b/modules/exoplanets/exoplanetsmodule_lua.inl @@ -176,16 +176,17 @@ void createExoplanetSystem(const std::string& starName) { } std::string colorLayers; + std::optional starColor = std::nullopt; const float bv = system.starData.bv; if (!std::isnan(bv)) { - const glm::vec3 color = starColor(bv); + starColor = computeStarColor(bv); const std::string starTexture = module->starTexturePath(); colorLayers = "{" "Identifier = 'StarColor'," "Type = 'SolidColor'," - "Color = " + ghoul::to_string(color) + "," + "Color = " + ghoul::to_string(*starColor) + "," "BlendMode = 'Normal'," "Enabled = true" "}," @@ -502,6 +503,48 @@ void createExoplanetSystem(const std::string& starName) { "openspace.addSceneGraphNode(" + zoneDiscNode + ");", scripting::ScriptEngine::RemoteScripting::Yes ); + + // Star glare + if (starColor.has_value()) { + // This is a little magic to make the size of the glare dependent on the + // size and the temperature of the star. It's kind of based on the fact that + // the luminosity of a star is proportional to: (radius^2)*(temperature^4) + // Maybe a better option would be to compute the size based on the aboslute + // magnitude or star luminosity, but for now this looks good enough. + float size = 59.f * radiusInMeter; + if (hasTeff) { + constexpr const float sunTeff = 5780.f; + size *= std::pow(system.starData.teff / sunTeff, 2.0); + } + + const std::string glareTexture = module->starGlareTexturePath(); + + const std::string starGlare = "{" + "Identifier = '" + starIdentifier + "_Glare'," + "Parent = '" + starIdentifier + "'," + "Renderable = {" + "Type = 'RenderablePlaneImageLocal'," + "Size = " + ghoul::to_string(size) + "," + "Origin = 'Center'," + "Billboard = true," + "Texture = openspace.absPath('" + + formatPathToLua(glareTexture) + + "')," + "BlendMode = 'Additive'," + "Opacity = 0.65," + "MultiplyColor = " + ghoul::to_string(*starColor) + "" + "}," + "GUI = {" + "Name = '" + sanitizedStarName + " Glare'," + "Path = '" + guiPath + "'" + "}" + "}"; + + openspace::global::scriptEngine->queueScript( + "openspace.addSceneGraphNode(" + starGlare + ");", + scripting::ScriptEngine::RemoteScripting::Yes + ); + } } }