Skip to content
Merged
55 changes: 48 additions & 7 deletions src/Features/SkySync.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
#include "SkySync.h"
#include "SkySync.h"

NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(
SkySync::Settings,
Enabled,
UseAlternateSunPath,
MoonLightSource,
SunPath,
CustomAngle)
CustomAngle,
SunriseBeginOffset,
SunriseEndOffset,
SunsetBeginOffset,
SunsetEndOffset,
MinShadowElevation)

void SkySync::DrawSettings()
{
Expand All @@ -25,13 +30,33 @@ void SkySync::DrawSettings()
}

ImGui::SliderInt("Moon light source", &settings.MoonLightSource, 0, static_cast<uint8_t>(MoonLightSource::Count) - 1, MoonLightSourceNames[settings.MoonLightSource], ImGuiSliderFlags_AlwaysClamp);
ImGui::SliderFloat("Min Shadow Elevation", &settings.MinShadowElevation, 0.0f, 45.0f, "%.1f deg", ImGuiSliderFlags_AlwaysClamp);
if (auto _tt = Util::HoverTooltipWrapper()) {
ImGui::Text("The minimum angle sunlight will set to. Caps shadow length. Higher = shorter shadows at sunset/sunrise.");
}
ImGui::Spacing();
ImGui::Spacing();
if (ImGui::TreeNodeEx("Sun Position Offsets", ImGuiTreeNodeFlags_DefaultOpen)) {
ImGui::TextWrapped("Moves sun height during sunrise/sunset. Reset weather to see changes.");
ImGui::SliderFloat("Sunrise Begin (Hours)", &settings.SunriseBeginOffset, -5.0f, 5.0f, "%.1f", ImGuiSliderFlags_AlwaysClamp);
ImGui::SliderFloat("Sunrise End (Hours)", &settings.SunriseEndOffset, -5.0f, 5.0f, "%.1f", ImGuiSliderFlags_AlwaysClamp);
ImGui::SliderFloat("Sunset Begin (Hours)", &settings.SunsetBeginOffset, -5.0f, 5.0f, "%.1f", ImGuiSliderFlags_AlwaysClamp);
ImGui::SliderFloat("Sunset End (Hours)", &settings.SunsetEndOffset, -5.0f, 5.0f, "%.1f", ImGuiSliderFlags_AlwaysClamp);
ImGui::TreePop();
}
}

void SkySync::LoadSettings(json& o_json)
{
settings = o_json;
settings.MoonLightSource = std::clamp(settings.MoonLightSource, static_cast<int32_t>(MoonLightSource::Brightest), static_cast<int32_t>(MoonLightSource::Secunda));
settings.SunPath = std::clamp(settings.SunPath, static_cast<int32_t>(SunPath::Southern), static_cast<int32_t>(SunPath::Custom));
settings.CustomAngle = std::clamp(settings.CustomAngle, -90.0f, 90.0f);
settings.SunriseBeginOffset = std::clamp(settings.SunriseBeginOffset, -5.0f, 5.0f);
settings.SunriseEndOffset = std::clamp(settings.SunriseEndOffset, -5.0f, 5.0f);
settings.SunsetBeginOffset = std::clamp(settings.SunsetBeginOffset, -5.0f, 5.0f);
settings.SunsetEndOffset = std::clamp(settings.SunsetEndOffset, -5.0f, 5.0f);
settings.MinShadowElevation = std::clamp(settings.MinShadowElevation, 0.0f, 45.0f);
SetSunAngle();
}

Expand Down Expand Up @@ -394,7 +419,8 @@ void SkySync::ShadowFader::SetLighting(const RE::Sun* sun, RE::NiPoint3 dir, flo

inline void SkySync::ShadowFader::ClampDirection(RE::NiPoint3& dir)
{
constexpr float minElev = DirectX::XMConvertToRadians(MinElevation);
const float minDegrees = globals::features::skySync.settings.MinShadowElevation;
const float minElev = DirectX::XMConvertToRadians(minDegrees);
const float elev = DirectX::XMScalarASinEst(dir.z);
if (elev >= minElev)
return;
Expand All @@ -419,10 +445,25 @@ SkySync::VolumetricLightingDescriptor* SkySync::ApplyVolumetricLighting_Volumetr

void SkySync::ClimateTimings::Update(const RE::TESClimate* climate)
{
sunriseBegin = climate->timing.sunrise.begin / 6.0f;
sunriseEnd = climate->timing.sunrise.end / 6.0f;
sunsetBegin = climate->timing.sunset.begin / 6.0f;
sunsetEnd = climate->timing.sunset.end / 6.0f;
const float SunriseBeginOffset = globals::features::skySync.settings.SunriseBeginOffset;
const float SunriseEndOffset = globals::features::skySync.settings.SunriseEndOffset;
const float SunsetBeginOffset = globals::features::skySync.settings.SunsetBeginOffset;
const float SunsetEndOffset = globals::features::skySync.settings.SunsetEndOffset;

sunriseBegin = (climate->timing.sunrise.begin / 6.0f) + SunriseBeginOffset;
sunriseEnd = (climate->timing.sunrise.end / 6.0f) + SunriseEndOffset;
sunsetBegin = (climate->timing.sunset.begin / 6.0f) + SunsetBeginOffset;
sunsetEnd = (climate->timing.sunset.end / 6.0f) + SunsetEndOffset;
// Basic ordering guarantees (prevents divide-by-zero / negative duration paths).
constexpr float kMinGapHours = 0.1f;
if (sunriseEnd <= sunriseBegin)
sunriseEnd = sunriseBegin + kMinGapHours;
if (sunsetEnd <= sunsetBegin)
sunsetEnd = sunsetBegin + kMinGapHours;
if (sunsetBegin <= sunriseEnd)
sunsetBegin = sunriseEnd + kMinGapHours;
if (sunsetEnd <= sunsetBegin)
sunsetEnd = sunsetBegin + kMinGapHours;
sunrise = (sunriseBegin + sunriseEnd) * 0.5f - 0.25f;
sunset = (sunsetBegin + sunsetEnd) * 0.5f + 0.25f;
sunriseFadeOutMoonStart = sunriseBegin - 0.5f;
Expand Down
8 changes: 6 additions & 2 deletions src/Features/SkySync.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ struct SkySync : Feature
int32_t MoonLightSource = 0;
int32_t SunPath = 0;
float CustomAngle = -35.0f;
float SunriseBeginOffset = 0.0f;
float SunriseEndOffset = 0.0f;
float SunsetBeginOffset = 0.0f;
float SunsetEndOffset = 0.0f;
float MinShadowElevation = 0.25f;
};

Settings settings;
Expand Down Expand Up @@ -147,7 +152,6 @@ struct SkySync : Feature
static constexpr float SunHorizonDistance = 280.0f;
static constexpr float SunPeakDistance = 400.0f;
static constexpr float SunScaleFactor = 48.0f / 2048.0f;
static constexpr float MinElevation = 0.25f;

static constexpr float SouthernSunAngle = 90.0f - 35.0f;
static constexpr float NorthernSunAngle = 90.0f + 35.0f;
Expand Down Expand Up @@ -206,4 +210,4 @@ struct SkySync : Feature
static void SetSunBaseVisibility(const RE::Sun* sun, float visibility);

static float SmoothStep(float start, float end, float x);
};
};