Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cast a reddish tint over the landscape when sun is low. #3858

Merged
merged 12 commits into from
Sep 8, 2024
48 changes: 19 additions & 29 deletions plugins/Scenery3d/src/S3DRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -969,29 +969,17 @@ void S3DRenderer::calculateLighting()
//specular factor is calculated from other values for now
float specular = std::min(ambientBrightness*directionalBrightness*5.0f,1.0f);

//if the night vision mode is on, use red-tinted lighting
bool red=StelApp::getInstance().getVisionModeNight();

float torchDiff = shaderParameters.torchLight ? torchBrightness : 0.0f;
lightInfo.torchAttenuation = 1.0f / (torchRange * torchRange);

if(red)
{
lightInfo.ambient = QVector3D(ambientBrightness,0, 0);
lightInfo.directional = QVector3D(directionalBrightness,0,0);
lightInfo.emissive = QVector3D(emissiveFactor,0,0);
lightInfo.specular = QVector3D(specular,0,0);
lightInfo.torchDiffuse = QVector3D(torchDiff,0,0);
}
else
{
//for now, lighting is only white
lightInfo.ambient = QVector3D(ambientBrightness,ambientBrightness, ambientBrightness);
lightInfo.directional = QVector3D(directionalBrightness,directionalBrightness,directionalBrightness);
lightInfo.emissive = QVector3D(emissiveFactor,emissiveFactor,emissiveFactor);
lightInfo.specular = QVector3D(specular,specular,specular);
lightInfo.torchDiffuse = QVector3D(torchDiff,torchDiff,torchDiff);
}
static LandscapeMgr *lmgr=GETSTELMODULE(LandscapeMgr);
QVector3D solarTint=lmgr->getLandscapeTint().toQVector();
//ambient tries to neutralize sunrise reddening a bit to model collecting light more of the blue sky. Directional and specular are tinted with possibly reddened sun.
lightInfo.ambient = ambientBrightness*(QVector3D(0.4,0.4,0.4)+0.6*solarTint);
lightInfo.directional = directionalBrightness*QVector3D(powf(solarTint[0],2.5f), powf(solarTint[1], 2.5f), powf(solarTint[2], 2.5f));
lightInfo.emissive = QVector3D(emissiveFactor,emissiveFactor,emissiveFactor);
lightInfo.specular = specular*solarTint;
lightInfo.torchDiffuse = QVector3D(torchDiff,torchDiff,torchDiff);
}

void S3DRenderer::calcCubeMVP(const Vec3d translation)
Expand Down Expand Up @@ -1497,10 +1485,12 @@ void S3DRenderer::drawDebug()
Q_ASSERT(lightInfo.directionalSource<=LightParameters::DS_Venus_Ambient);
directionalSourceString = directionalSourceStrings.at(lightInfo.directionalSource);

const QString lightMessage=QString("Ambient: %1 Directional: %2. Shadows cast by: %3 from %4/%5/%6")
.arg(lightInfo.ambient[0], 6, 'f', 4).arg(lightInfo.directional[0], 6, 'f', 4)
.arg(shadowCasterName).arg(lightInfo.lightDirectionV3f.v[0], 6, 'f', 4)
.arg(lightInfo.lightDirectionV3f.v[1], 6, 'f', 4).arg(lightInfo.lightDirectionV3f.v[2], 6, 'f', 4);
QString lightMessage=QString("Ambient: %1/%2/%3 Directional: %4/%5/%6. Shadows cast by: %7")
.arg(QString::number(lightInfo.ambient[0], 'f', 1), QString::number(lightInfo.ambient[1], 'f', 1), QString::number(lightInfo.ambient[2], 'f', 1),
QString::number(lightInfo.directional[0], 'f', 4), QString::number(lightInfo.directional[1], 'f', 4), QString::number(lightInfo.directional[2], 'f', 4))
.arg(shadowCasterName);
if (lightInfo.shadowCaster>LightParameters::SC_None)
lightMessage.append(QString(" from %1/%2/%3").arg(QString::number(lightInfo.lightDirectionV3f.v[0],'f', 4), QString::number(lightInfo.lightDirectionV3f.v[1], 'f', 4), QString::number(lightInfo.lightDirectionV3f.v[2],'f', 4)));
const QString lightMessage2=QString("Contributions: Ambient Sun: %1, Moon: %2, Background+^L: %3")
.arg(lightInfo.sunAmbient, 6, 'f', 4).arg(lightInfo.moonAmbient, 6, 'f', 4).arg(lightInfo.backgroundAmbient, 6, 'f', 4);
const QString lightMessage3=QString(" Directional %1 by: %2, emissive factor: %3, landscape opacity: %4")
Expand All @@ -1510,15 +1500,15 @@ void S3DRenderer::drawDebug()
painter.setFont(debugTextFont);
painter.setColor(1.f,0.f,1.f,1.f);
// For now, these messages print light mixture values.
painter.drawText(20, 160, lightMessage);
painter.drawText(20, 145, lightMessage2);
painter.drawText(20, 130, lightMessage3);
painter.drawText(20, 115, QString("Torch range %1, brightness %2/%3/%4").arg(torchRange).arg(lightInfo.torchDiffuse[0]).arg(lightInfo.torchDiffuse[1]).arg(lightInfo.torchDiffuse[2]));
painter.drawText(70, 160, lightMessage);
painter.drawText(70, 145, lightMessage2);
painter.drawText(70, 130, lightMessage3);
painter.drawText(70, 115, QString("Torch range %1, brightness %2/%3/%4").arg(torchRange).arg(lightInfo.torchDiffuse[0]).arg(lightInfo.torchDiffuse[1]).arg(lightInfo.torchDiffuse[2]));

const AABBox& bbox = currentScene->getSceneAABB();
QString str = QString("BB: %1/%2/%3 %4/%5/%6").arg(bbox.min.v[0], 7, 'f', 2).arg(bbox.min.v[1], 7, 'f', 2).arg(bbox.min.v[2], 7, 'f', 2)
.arg(bbox.max.v[0], 7, 'f', 2).arg(bbox.max.v[1], 7, 'f', 2).arg(bbox.max.v[2], 7, 'f', 2);
painter.drawText(10, 100, str);
painter.drawText(70, 100, str);
// PRINT OTHER MESSAGES HERE:

float screen_x = altAzProjector->getViewportWidth() - 500.0f;
Expand Down
8 changes: 4 additions & 4 deletions plugins/Scenery3d/src/S3DRenderer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,10 +251,10 @@ class S3DRenderer : public QObject, protected QOpenGLFunctions
Vec3f lightDirectionV3f;
//same as lightDirectionV3f, but as QVector3D
QVector3D lightDirectionWorld;
QVector3D ambient;
QVector3D directional;
QVector3D specular;
QVector3D emissive;
QVector3D ambient; // color [0...1]
QVector3D directional; // color [0...1]
QVector3D specular; // color [0...1]
QVector3D emissive; // color [0...1]

QVector3D torchDiffuse;
float torchAttenuation;
Expand Down
40 changes: 26 additions & 14 deletions src/core/modules/Landscape.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1110,11 +1110,13 @@ void LandscapeOldStyle::drawDecor(StelCore*const core, const int firstFreeTexSam
(1.f-landscapeTransparency)*landFader.getInterstate());
}
else
{
renderProgram->setUniformValue(shaderVars.brightness,
landscapeBrightness, landscapeBrightness, landscapeBrightness,
(1.f-landscapeTransparency)*landFader.getInterstate());
}
{
renderProgram->setUniformValue(shaderVars.brightness,
landscapeBrightness*landscapeTint[0],
landscapeBrightness*landscapeTint[1],
landscapeBrightness*landscapeTint[2],
(1.f-landscapeTransparency)*landFader.getInterstate());
}

renderProgram->setUniformValue(shaderVars.tanMode, tanMode);
renderProgram->setUniformValue(shaderVars.calibrated, calibrated);
Expand Down Expand Up @@ -1209,7 +1211,9 @@ void LandscapeOldStyle::drawGround(StelCore*const core, const int firstFreeTexSa
renderProgram->setUniformValue(shaderVars.vshift, vshift);
renderProgram->setUniformValue(shaderVars.projectionMatrixInverse, prj->getProjectionMatrix().toQMatrix().inverted());
renderProgram->setUniformValue(shaderVars.brightness,
landscapeBrightness, landscapeBrightness, landscapeBrightness,
landscapeBrightness*landscapeTint[0],
landscapeBrightness*landscapeTint[1],
landscapeBrightness*landscapeTint[2],
(1.f-landscapeTransparency)*landFader.getInterstate());
prj->setUnProjectUniforms(*renderProgram);
gl.glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
Expand Down Expand Up @@ -1479,8 +1483,12 @@ void LandscapePolygonal::draw(StelCore* core, bool onlyPolygon)
sPainter.setCullFace(true);

if (!onlyPolygon) // The only useful application of the onlyPolygon is a demo which does not fill the polygon
{
sPainter.setColor(landscapeBrightness*groundColor, (1.f-landscapeTransparency)*landFader.getInterstate());
{
sPainter.setColor(
landscapeBrightness*groundColor[0]*landscapeTint[0],
landscapeBrightness*groundColor[1]*landscapeTint[1],
landscapeBrightness*groundColor[2]*landscapeTint[2],
(1.f-landscapeTransparency)*landFader.getInterstate());
#ifdef GL_MULTISAMPLE
const auto gl = sPainter.glFuncs();
if (multisamplingEnabled_)
Expand Down Expand Up @@ -1686,9 +1694,11 @@ void main(void)
if (!onlyPolygon || !horizonPolygon) // Make sure to draw the regular pano when there is no polygon
{
renderProgram->bind();
renderProgram->setUniformValue(shaderVars.brightness,
landscapeBrightness, landscapeBrightness,
landscapeBrightness, landFader.getInterstate());
renderProgram->setUniformValue(shaderVars.brightness,
landscapeBrightness*landscapeTint[0],
landscapeBrightness*landscapeTint[1],
landscapeBrightness*landscapeTint[2],
landFader.getInterstate());
const int mainTexSampler = 0;
mapTex->bind(mainTexSampler);
renderProgram->setUniformValue(shaderVars.mapTex, mainTexSampler);
Expand Down Expand Up @@ -2045,9 +2055,11 @@ void main(void)
landscapeBrightness*bottomCapColor[2],
bottomCapColor[0] < 0 ? 0 : landFader.getInterstate());

renderProgram->setUniformValue(shaderVars.brightness,
landscapeBrightness, landscapeBrightness,
landscapeBrightness, (1.f-landscapeTransparency)*landFader.getInterstate());
renderProgram->setUniformValue(shaderVars.brightness,
landscapeBrightness*landscapeTint[0],
landscapeBrightness*landscapeTint[1],
landscapeBrightness*landscapeTint[2],
(1.f-landscapeTransparency)*landFader.getInterstate());
const int mainTexSampler = 0;
mapTex->bind(mainTexSampler);
renderProgram->setUniformValue(shaderVars.mapTex, mainTexSampler);
Expand Down
4 changes: 4 additions & 0 deletions src/core/modules/Landscape.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ class Landscape
//! This is called in each draw().
void setBrightness(const double b, const double pollutionBrightness=0.0) {landscapeBrightness = static_cast<float>(b); lightScapeBrightness=static_cast<float>(pollutionBrightness); }

//! Set a tint to render the landscape. Useful for low-sun scenes
void setTint(Vec3f color){landscapeTint=color;}

//! Returns the current brightness level
double getBrightness() const { return static_cast<double>(landscapeBrightness); }
//! Returns the lightscape brightness
Expand Down Expand Up @@ -241,6 +244,7 @@ class Landscape

float minBrightness; //! Read from landscape.ini:[landscape]minimal_brightness. Allows minimum visibility that cannot be underpowered.
float landscapeBrightness; //! brightness [0..1] to draw the landscape. Computed by the LandscapeMgr.
Vec3f landscapeTint; //! color tint to draw the landscape (daylight texture only). Nice for sunrise/sunset.
float lightScapeBrightness; //! can be used to draw nightscape texture (e.g. city light pollution), if available. Computed by the LandscapeMgr.
bool validLandscape; //! was a landscape loaded properly?
LinearFader landFader; //! Used to slowly fade in/out landscape painting.
Expand Down
5 changes: 5 additions & 0 deletions src/core/modules/LandscapeMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@ LandscapeMgr::LandscapeMgr()
, flagEnvironmentAutoEnabling(false)
, flagLandscapeUseTransparency(false)
, landscapeTransparency(0.)
, landscapeTint(1.f, 1.f, 1.f)
{
setObjectName("LandscapeMgr"); // should be done by StelModule's constructor.

Expand Down Expand Up @@ -542,6 +543,7 @@ void LandscapeMgr::update(double deltaTime)
if (currentPlanet->getID() == sun->getID())
{
landscape->setBrightness(1.0, 1.0);
landscape->setTint(Vec3f(1.f));
return;
}

Expand Down Expand Up @@ -653,6 +655,9 @@ void LandscapeMgr::update(double deltaTime)
}
landscape->setBrightness(landscapeBrightness, lightscapeBrightness);

// extra colorful sunrise/sunset management.
landscape->setTint(landscapeTint);

messageFader.update(static_cast<int>(deltaTime*1000));
}

Expand Down
8 changes: 7 additions & 1 deletion src/core/modules/LandscapeMgr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,10 @@ public slots:
}
}

//! Set a discoloration to simulate sunrise/sunset colors.
void setLandscapeTint(const Vec3f &c){landscapeTint=c;}
Vec3f getLandscapeTint() const {return landscapeTint;}

/*
//This method has been removed, use StelSkyDrawer::getBortleScaleIndex instead, or StelMainScriptAPI::getBortleScaleIndex in scripts
//Also, if required, please use StelSkyDrawer::setBortleScaleIndex or StelMainScriptAPI::setBortleScaleIndex instead of LandscapeMgr::setAtmosphereBortleLightPollution
Expand Down Expand Up @@ -836,8 +840,10 @@ private slots:

//! Indicate use of the default transparency value specified in config.ini.
bool flagLandscapeUseTransparency;
//! A transparency value
//! A user-configurable transparency value to make landscape partially see-through and let objects below the horizon be visible
double landscapeTransparency;
//! Color tint to draw the landscape in. Can be useful for sunrise/sunset scenes.
Vec3f landscapeTint;

//! The ID of the currently loaded landscape
QString currentLandscapeID;
Expand Down
37 changes: 36 additions & 1 deletion src/core/modules/Planet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2846,6 +2846,41 @@ void Planet::draw(StelCore* core, float maxMagLabels, const QFont& planetNameFon
return;
}

static SolarSystem* ssm = GETSTELMODULE(SolarSystem);
const bool isSun = this==ssm->getSun();
const bool currentLocationIsEarth = core->getCurrentLocation().planetName == "Earth";
if (isSun && currentLocationIsEarth)
{
static LandscapeMgr* lmgr = GETSTELMODULE(LandscapeMgr);
Vec3f posAltAz = getAltAzPosAuto(core).toVec3f();
posAltAz.normalize();

// If sun is higher than -3 degrees, tint the landscape.
// Down to 0 degree, this tint is derived from the halo color.
// Below that, we must find a smooth transition (adapted cosine). Below -3 degrees,
// it is assumed the reddish tint should have dissipated, and the blue sky is illuminating the landscape in a neutral tone.
if (posAltAz[2]<sinf(-3.f*M_PI_180f))
lmgr->setLandscapeTint(Vec3f(1.f));
else
{
const float sunAlt=asinf(posAltAz[2]);
const float angleFactor=sunAlt>0 ? 1.f : 0.5f*(cosf(60.f*sunAlt)+1.f);

// Find extinction settings to change colors. The method is rather ad-hoc.
const float extinctedMag=getVMagnitudeWithExtinction(core)-getVMagnitude(core); // this is net value of extinction, in mag.
//Vec3f color(haloColor[0], powf(0.75f, extinctedMag) * haloColor[1], powf(0.42f, 0.9f*extinctedMag) * haloColor[2]);
Vec3f color(haloColor[0], powf(0.75f, extinctedMag) * haloColor[1], powf(0.25f, extinctedMag) * haloColor[2]);

Vec3f fullTint(0.25f*Vec3f(3.f+sqrtf(color[0]), 3.f+sqrtf(color[1]), 3.f+sqrtf(color[2])));

//lmgr->setLandscapeTint(color);
//lmgr->setLandscapeTint(Vec3f(sqrtf(color[0]), sqrtf(color[1]), sqrtf(color[2]))); // weaker tint
//lmgr->setLandscapeTint(0.5f*Vec3f(1.f+sqrtf(color[0]), 1.f+sqrtf(color[1]), 1.f+sqrtf(color[2]))); // even weaker tint
//lmgr->setLandscapeTint(0.25f*Vec3f(4.f, 3.f+sqrtf(magFactorGreen), 3.f+sqrtf(magFactorBlue))); // even weaker tint
lmgr->setLandscapeTint(angleFactor*fullTint + (1.f-angleFactor)*Vec3f(1.f)); // final tint
}
}

// Try to improve speed for minor planets: test if visible at all.
// For a full catalog of NEAs (11000 objects), with this and resetting deltaJD according to distance, rendering time went 4.5fps->12fps.
// TBD: Note that taking away the asteroids at this stage breaks dim-asteroid occultation of stars!
Expand Down Expand Up @@ -3447,7 +3482,7 @@ void Planet::draw3dModel(StelCore* core, StelProjector::ModelViewTranformP trans
rotationAngle -= q0*static_cast<float>(180.0/M_PI);

StelPainter sPainter(core->getProjection(StelCore::FrameJ2000));
const auto pos = getJ2000EquatorialPos(core).toVec3f();
const Vec3f pos = getJ2000EquatorialPos(core).toVec3f();

// Find new extincted color for halo. The method is again rather ad-hoc, but does not look too bad.
// For the sun, we have again to use the stronger extinction to avoid color mismatch.
Expand Down
Loading