From 304304e6bcb9215e32c860d49bab437027d4dcfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wilhelm=20Bj=C3=B6rkstr=C3=B6m?= <143391787+Grantallkotten@users.noreply.github.com> Date: Tue, 25 Mar 2025 14:28:31 +0100 Subject: [PATCH] Star colours, and translation Co-Authored-By: Emil Wallberg <49481622+EmilWallberg@users.noreply.github.com> --- data/assets/blackholes/schwarzchild.asset | 10 ++++- modules/blackhole/rendering/kdtree.cpp | 25 ++++++----- modules/blackhole/rendering/kdtree.h | 2 +- .../rendering/renderableblackhole.cpp | 42 ++++++++++++++++--- .../blackhole/rendering/renderableblackhole.h | 7 +++- modules/blackhole/shaders/blackhole_fs.glsl | 19 ++++++++- 6 files changed, 83 insertions(+), 22 deletions(-) diff --git a/data/assets/blackholes/schwarzchild.asset b/data/assets/blackholes/schwarzchild.asset index dd40ae3ba4..87631c5c39 100644 --- a/data/assets/blackholes/schwarzchild.asset +++ b/data/assets/blackholes/schwarzchild.asset @@ -2,6 +2,13 @@ local lightyear = 9.4607304725808E15 local lightday = 9.4607304725808E15 / 365 local _MBlackHole = 4.297E6; +local colormaps = asset.resource({ + Name = "Stars Color Table", + Type = "HttpSynchronization", + Identifier = "stars_colormap", + Version = 3 +}) + local Node = { Identifier = "Blackhole_Example", InteractionSphere = 0.8 * lightday, @@ -14,7 +21,8 @@ local Node = { }, Renderable = { Type = "RenderableBlackHole", - SolarMass = 4.297e6 + SolarMass = 4.297e6, + ColorMap = colormaps .. "colorbv.cmap", }, GUI = { Name = "Schwarzchild Blackhole", diff --git a/modules/blackhole/rendering/kdtree.cpp b/modules/blackhole/rendering/kdtree.cpp index fa19efb928..713d0f73fa 100644 --- a/modules/blackhole/rendering/kdtree.cpp +++ b/modules/blackhole/rendering/kdtree.cpp @@ -15,10 +15,19 @@ namespace { } } namespace openspace { - void KDTree::build(const std::string& filePath, const glm::vec3& localWorldCenter) { + void KDTree::build(std::string const& filePath, glm::vec3 const& origin) { const std::filesystem::path file{ absPath(filePath) }; dataloader::Dataset dataset = dataloader::data::loadFileWithCache(file); - size_t numberOfStars = dataset.entries.size(); + + + +#pragma omp parallel for + for (size_t i = 0; i < dataset.entries.size(); ++i) { + dataset.entries[i].position = cartesianToSpherical(dataset.entries[i].position - origin); + } + + + size_t numberOfStars = dataset.entries.size(); tree.resize(numberOfStars); struct NodeInfo { size_t index; @@ -27,11 +36,6 @@ namespace openspace { size_t end; }; - #pragma omp parallel for - for (auto& entry : dataset.entries) { - entry.position = cartesianToSpherical(entry.position - localWorldCenter); - } - std::queue q; q.emplace(0, 0, 0, numberOfStars); while (!q.empty()) { @@ -57,9 +61,9 @@ namespace openspace { dataloader::Dataset::Entry const& entry{ dataset.entries[medianIndex] }; glm::vec3 const& position{ entry.position }; - float const color{ entry.data[0]}; - float const lum{ entry.data[1]}; - float const absMag{ entry.data[2]}; + float const color{ entry.data[0] }; + float const lum{ entry.data[1] }; + float const absMag{ entry.data[2] }; if (node.index >= tree.size()) { tree.resize(std::max(tree.size() * 2, node.index + 1)); @@ -69,6 +73,7 @@ namespace openspace { tree.begin() + node.index, position, color, lum, absMag ); + // Enqueue left and right children q.emplace(2 * node.index + 1, node.depth + 1, node.start, medianIndex); q.emplace(2 * node.index + 2, node.depth + 1, medianIndex + 1, node.end); diff --git a/modules/blackhole/rendering/kdtree.h b/modules/blackhole/rendering/kdtree.h index b335edbf25..eb41cadbf2 100644 --- a/modules/blackhole/rendering/kdtree.h +++ b/modules/blackhole/rendering/kdtree.h @@ -12,7 +12,7 @@ namespace openspace { size_t size() { return tree.size() * 6; }; - void build(const std::string& filePath, const glm::vec3& localWorldCenter); + void build(std::string const& filePath, glm::vec3 const & origin); std::vector flatTree() const; diff --git a/modules/blackhole/rendering/renderableblackhole.cpp b/modules/blackhole/rendering/renderableblackhole.cpp index 77866f881f..f9c9ba2e18 100644 --- a/modules/blackhole/rendering/renderableblackhole.cpp +++ b/modules/blackhole/rendering/renderableblackhole.cpp @@ -45,32 +45,40 @@ namespace { openspace::properties::Property::Visibility::User }; + constexpr openspace::properties::Property::PropertyInfo ColorTextureInfo = { + "ColorMap", + "Color Texture", + "The path to the texture that is used to convert from the magnitude of the star " + "to its color. The texture is used as a one dimensional lookup function.", + openspace::properties::Property::Visibility::AdvancedUser + }; + struct [[codegen::Dictionary(RenderableModel)]] Parameters { std::optional SolarMass; + std::string colorMap; }; + #include "renderableblackhole_codegen.cpp" } namespace openspace { RenderableBlackHole::RenderableBlackHole(const ghoul::Dictionary& dictionary) - : Renderable(dictionary, { .automaticallyUpdateRenderBin = false }), _solarMass(SolarMassInfo, 4.297e6f) { + : Renderable(dictionary, { .automaticallyUpdateRenderBin = false }), _solarMass(SolarMassInfo, 4.297e6f), _colorBVMapTexturePath(ColorTextureInfo) { const Parameters p = codegen::bake(dictionary); _solarMass = p.SolarMass.value_or(_solarMass); _rs = 2.0f * G * _solarMass; + + _colorBVMapTexturePath = absPath(p.colorMap).string(); } RenderableBlackHole::~RenderableBlackHole() {} void RenderableBlackHole::initialize() { _schwarzschildWarpTable = std::vector(_rayCount * 2, 0.f); - - _starKDTree.build("${BASE}/sync/http/stars_du/6/stars.speck", glm::vec3(0)); - - flatDataStar = _starKDTree.flatTree(); } void RenderableBlackHole::initializeGL() { @@ -103,7 +111,13 @@ namespace openspace { return _program != nullptr; } - void RenderableBlackHole::update(const UpdateData&) { + void RenderableBlackHole::update(const UpdateData& data) { + if (data.modelTransform.translation != _lastTranslation) { + _starKDTree.build("${BASE}/sync/http/stars_du/6/stars.speck", data.modelTransform.translation); + flatDataStar = _starKDTree.flatTree(); + _lastTranslation = data.modelTransform.translation; + } + glm::vec3 cameraPosition = global::navigationHandler->camera()->positionVec3(); glm::vec3 anchorNodePosition = global::navigationHandler->anchorNode()->position(); float distanceToAnchor = (float)glm::distance(cameraPosition, anchorNodePosition) / distanceconstants::LightYear; @@ -131,6 +145,11 @@ namespace openspace { LWARNING("UniformCache is missing 'viewGrid'"); } + ghoul::opengl::TextureUnit colorBVMapUnit; + if (!bindTexture(_uniformCache.colorBVMap, colorBVMapUnit, _colorBVMapTexture)) { + LWARNING("UniformCache is missing 'colorBVMap'"); + } + SendSchwarzchildTableToShader(); SendStarKDTreeToShader(); @@ -235,6 +254,17 @@ namespace openspace { else { LWARNING(std::format("Failed to load environment texture from path '{}'", absPath(texturePath).string())); } + + _colorBVMapTexture = ghoul::io::TextureReader::ref().loadTexture(absPath(_colorBVMapTexturePath), 1); + + + if (_colorBVMapTexture) { + _colorBVMapTexture->uploadTexture(); + } + else { + LWARNING(std::format("Failed to load environment texture from path '{}'", absPath(_colorBVMapTexturePath).string())); + } + } void RenderableBlackHole::bindFramebuffer() { diff --git a/modules/blackhole/rendering/renderableblackhole.h b/modules/blackhole/rendering/renderableblackhole.h index 6ab7bc2c1c..009479f7c9 100644 --- a/modules/blackhole/rendering/renderableblackhole.h +++ b/modules/blackhole/rendering/renderableblackhole.h @@ -43,12 +43,14 @@ namespace openspace { void loadEnvironmentTexture(); ghoul::opengl::ProgramObject* _program = nullptr; - + glm::dvec3 _lastTranslation{}; size_t _rayCount = 1000; size_t _stepsCount = 50000; float _stepLength = 0.001f; properties::FloatProperty _solarMass; + properties::StringProperty _colorBVMapTexturePath; + float _rs = 1.0f; float _rEnvmap = 60.0f; @@ -72,10 +74,11 @@ namespace openspace { GLuint _ssboSchwarzschildWarpTable = 0; GLuint _ssboStarKDTree = 0; - UniformCache(environmentTexture, viewGrid, worldRotationMatrix, cameraRotationMatrix) _uniformCache; + UniformCache(environmentTexture, viewGrid, worldRotationMatrix, cameraRotationMatrix, colorBVMap) _uniformCache; std::unique_ptr _warpTableTex; std::unique_ptr _environmentTexture; + std::unique_ptr _colorBVMapTexture; }; } // openspace namespace diff --git a/modules/blackhole/shaders/blackhole_fs.glsl b/modules/blackhole/shaders/blackhole_fs.glsl index 156a5e68f4..fe36799d44 100644 --- a/modules/blackhole/shaders/blackhole_fs.glsl +++ b/modules/blackhole/shaders/blackhole_fs.glsl @@ -7,6 +7,7 @@ in vec2 TexCoord; uniform sampler2D environmentTexture; uniform sampler2D viewGrid; +uniform sampler1D colorBVMap; uniform mat4 cameraRotationMatrix; uniform mat4 worldRotationMatrix; @@ -22,6 +23,7 @@ layout (std430) buffer ssbo_star_map { const float PI = 3.1415926535897932384626433832795f; const float VIEWGRIDZ = -1.0f; const float INF = 1.0f/0.0f; +const float LUM_LOWER_CAP = 0.01; /********************************************************** @@ -148,6 +150,13 @@ vec2 applyBlackHoleWarp(vec2 cameraOutSphereCoords){ Star Map ***********************************************************/ +vec3 BVIndex2rgb(float color) { + // BV is [-0.4, 2.0] + float st = (color + 0.4) / (2.0 + 0.4); + + return texture(colorBVMap, st).rgb; +} + float angularDist(vec2 a, vec2 b) { float dTheta = a.x - b.x; float dPhi = a.y - b.y; @@ -163,8 +172,14 @@ vec4 searchNearestStar(vec3 sphericalCoords) { int axis = -1; while(index < SIZE && starKDTree[nodeIndex] > 0.0f){ - if (angularDist(sphericalCoords.yz, vec2(starKDTree[nodeIndex + 1], starKDTree[nodeIndex + 2])) < 0.001f){ - return vec4(0.9f, 0.9f, 0.8f, 0.2f); + if (angularDist(sphericalCoords.yz, vec2(starKDTree[nodeIndex + 1], starKDTree[nodeIndex + 2])) < 0.002f){ + float luminosity = pow(10.0, 1.89 - 0.4 * starKDTree[nodeIndex + 4]); + + // If luminosity is really really small then set it to a static low number. + if (luminosity < LUM_LOWER_CAP) { + luminosity = LUM_LOWER_CAP; + } + return vec4(BVIndex2rgb(starKDTree[nodeIndex + 3]), 1.0f); } axis = depth % 2 + 1;