Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions src/core/modules/Atmosphere.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,13 +109,33 @@ class Atmosphere
//! Get the light pollution luminance in cd/m^2
float getLightPollutionLuminance() const { return lightPollutionLuminance; }

//! Get the multiplier applied to averageLuminance when computing the
//! star-visibility adaptation luminance reported to StelSkyDrawer.
//! Each atmosphere model produces averageLuminance in a different scale,
//! so this multiplier must be tuned per model. The default (1000) is
//! calibrated for the Preetham/Schaefer model to reach full stellar
//! visibility at approximately -18 deg sun altitude (astronomical twilight).
//! ShowMySky uses the same value (see AtmosphereShowMySky.hpp).
virtual float getStarAdaptationMultiplier() const { return 1000.f; }

//! Store the natural sky adaptation luminance for atmosphere rendering.
//! This is the un-inflated value used by the atmosphere shader so that
//! the sky tone-maps correctly even when the star-visibility adaptation
//! luminance reported via StelSkyDrawer::reportLuminanceInFov() differs.
void setSkyAdaptationLuminance(float lum) { skyAdaptationLuminance = lum; }
//! Get the natural sky adaptation luminance stored for atmosphere rendering.
float getSkyAdaptationLuminance() const { return skyAdaptationLuminance; }

protected:
//! The average luminance of the atmosphere in cd/m2
float averageLuminance = 0;
bool overrideAverageLuminance = false; // if true, don't compute but keep value set via setAverageLuminance(float)
float eclipseFactor = 1;
LinearFader fader;
float lightPollutionLuminance = 0;
//! Natural sky adaptation luminance for atmosphere shader tone-mapping,
//! decoupled from the star-visibility adaptation luminance.
float skyAdaptationLuminance = 50.f;
};

#endif // ATMOSPHERE_HPP
9 changes: 9 additions & 0 deletions src/core/modules/AtmospherePreetham.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,12 @@ void AtmospherePreetham::draw(StelCore* core)

StelToneReproducer* eye = core->getToneReproducer();

// Temporarily set the natural sky adaptation luminance for the
// tone-mapping shader uniforms, in case the star-visibility
// adaptation luminance differs (see LandscapeMgr.cpp).
float savedLwa = eye->getWorldAdaptationLuminance();
eye->setWorldAdaptationLuminance(skyAdaptationLuminance);

StelPainter sPainter(core->getProjection2d());
sPainter.setBlending(true, GL_ONE, GL_ONE);

Expand All @@ -406,6 +412,9 @@ void AtmospherePreetham::draw(StelCore* core)
bool useTmGamma, sRGB;
eye->getShadersParams(a, b, c, d, useTmGamma, sRGB);

// Restore the star-visibility Lwa
eye->setWorldAdaptationLuminance(savedLwa);

GL(atmoShaderProgram->setUniformValue(shaderAttribLocations.alphaWaOverAlphaDa, a));
GL(atmoShaderProgram->setUniformValue(shaderAttribLocations.oneOverGamma, b));
GL(atmoShaderProgram->setUniformValue(shaderAttribLocations.term2TimesOneOverMaxdLpOneOverGamma, c));
Expand Down
11 changes: 11 additions & 0 deletions src/core/modules/AtmosphereShowMySky.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -809,12 +809,23 @@ void AtmosphereShowMySky::draw(StelCore* core)
if (!atm_intensity)
return;

// Temporarily set the natural (un-inflated) sky adaptation luminance
// for the tone-mapping shader uniforms. The global Lwa has been inflated
// (via a large star-adaptation multiplier) to suppress stars during
// twilight, but the sky must still tone-map with the real atmospheric
// luminance so it looks blue during the day.
float savedLwa = eye->getWorldAdaptationLuminance();
eye->setWorldAdaptationLuminance(skyAdaptationLuminance);

GL(luminanceToScreenProgram_->bind());

float a, b, c, d;
bool useTmGamma, sRGB;
eye->getShadersParams(a, b, c, d, useTmGamma, sRGB);

// Restore the inflated Lwa so star rendering continues to use it
eye->setWorldAdaptationLuminance(savedLwa);

GL(luminanceToScreenProgram_->setUniformValue(shaderAttribLocations.alphaWaOverAlphaDa, a));
GL(luminanceToScreenProgram_->setUniformValue(shaderAttribLocations.oneOverGamma, b));
GL(luminanceToScreenProgram_->setUniformValue(shaderAttribLocations.term2TimesOneOverMaxdLpOneOverGamma, c));
Expand Down
5 changes: 5 additions & 0 deletions src/core/modules/AtmosphereShowMySky.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ class AtmosphereShowMySky : public Atmosphere, public QObject
bool isReadyToRender() const override;
LoadingStatus stepDataLoading() override;

//! ShowMySky produces averageLuminance in a much smaller scale than
//! Preetham/Schaefer, so a larger multiplier is needed to correctly
//! suppress stars during twilight until astronomical twilight (-18°).
float getStarAdaptationMultiplier() const override { return 1000.f; }

private:
#ifdef ENABLE_SHOWMYSKY
QLibrary showMySkyLib;
Expand Down
14 changes: 13 additions & 1 deletion src/core/modules/LandscapeMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -539,7 +539,19 @@ void LandscapeMgr::update(double deltaTime)
resetToFallbackAtmosphere();
}

core->getSkyDrawer()->reportLuminanceInFov(3.75f+atmosphere->getAverageLuminance()*3.5f, true);
// Store the natural sky adaptation luminance for atmosphere shader
// tone-mapping, using the original Preetham-era multiplier (3.5).
// This keeps the sky rendering identical to the original code.
atmosphere->setSkyAdaptationLuminance(3.75f + atmosphere->getAverageLuminance() * 3.5f);

// Report the star-visibility adaptation luminance using a per-model
// multiplier. ShowMySky produces much smaller averageLuminance values
// than Preetham/Schaefer, so it needs a larger multiplier (~1000) to
// correctly suppress stars until astronomical twilight (-18 deg).
// Preetham uses ~12 (derived from the twilight brightness ratio between
// -8 deg and -18 deg applied to the original 3.5 multiplier).
const float starMult = atmosphere->getStarAdaptationMultiplier();
core->getSkyDrawer()->reportLuminanceInFov(3.6f + atmosphere->getAverageLuminance() * starMult, true);

// NOTE: Simple workaround for brightness of landscape when observing from the Sun.
if (currentPlanet->getID() == sun->getID())
Expand Down
2 changes: 1 addition & 1 deletion src/core/modules/MilkyWay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ void main(void)
const float nelm = StelCore::luminanceToNELM(drawer->getLightPollutionLuminance());
const float bortleIntensity = 1.f+(15.5f-2*nelm)*atmFadeIntensity; // smoothed Bortle index moderated by atmosphere fader.

const float lum = drawer->surfaceBrightnessToLuminance(12.f+0.15f*bortleIntensity); // was 11.5; Source? How to calibrate the new texture?
const float lum = drawer->surfaceBrightnessToLuminance(14.f+0.15f*bortleIntensity); // was 11.5; Source? How to calibrate the new texture?
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment first appeared in 282e148. Did you check the look in the moonlight?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only briefly after that commit. Does it look bad to you?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't tried this change at all, just looked through the code. I don't have much clear and unpolluted skies here to observe stars in twilight, so I can't check how well this change corresponds to reality.

Copy link
Copy Markdown
Contributor Author

@Atque Atque Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not really meant to be fully physically correct, only a better solution than what Stellarium currently provides.


// Get the luminance scaled between 0 and 1
float aLum =eye->adaptLuminanceScaled(lum*fader->getInterstate());
Expand Down
Loading