summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gfx/lightDirection.cpp19
-rw-r--r--gfx/lightDirection.h7
-rw-r--r--test/test-environment.cpp53
3 files changed, 65 insertions, 14 deletions
diff --git a/gfx/lightDirection.cpp b/gfx/lightDirection.cpp
index 3932872..5198bdf 100644
--- a/gfx/lightDirection.cpp
+++ b/gfx/lightDirection.cpp
@@ -1,12 +1,25 @@
#include "lightDirection.h"
#include "maths.h"
-constexpr auto ASTRONOMICAL_TWILIGHT = 18.0_degrees;
+constexpr auto TWILIGHT_START = .0_degrees;
+constexpr auto TWILIGHT_END = -18.0_degrees;
+constexpr auto TWILIGHT_RANGE = TWILIGHT_START - TWILIGHT_END;
+
constexpr auto SUN_ANGLUAR_SIZE = 0.5_degrees;
+constexpr auto SUN_ANGLUAR_RADIUS = SUN_ANGLUAR_SIZE / 2;
+constexpr auto SUN_ELEVATION_REFRACTION_OFFSET = 0.5_degrees;
+constexpr auto SUN_ANGLUAR_OFFSET = SUN_ANGLUAR_RADIUS + SUN_ELEVATION_REFRACTION_OFFSET;
+
+constexpr auto ATMOSPHERE_SCATTER_MIN = .4F;
+constexpr auto ATMOSPHERE_SCATTER_MAX = .7F;
+constexpr auto ATMOSPHERE_SCATTER_RANGE = ATMOSPHERE_SCATTER_MAX - ATMOSPHERE_SCATTER_MIN;
+
+constexpr auto NORM = 0.5F;
LightDirection::LightDirection(const Direction2D sunPos) :
pos {sunPos}, vec {glm::mat3 {rotate_yp(pi + sunPos.x, -sunPos.y)} * north},
- amb {glm::clamp(sunPos.y + ASTRONOMICAL_TWILIGHT, 0.F, 1.F)},
- dir {glm::clamp(sunPos.y + SUN_ANGLUAR_SIZE, 0.F, 1.F)}
+ amb {glm::clamp((sunPos.y - TWILIGHT_END) / TWILIGHT_RANGE, 0.F, 1.F)},
+ dir {(-std::cos(std::clamp((sunPos.y + SUN_ANGLUAR_OFFSET) / SUN_ANGLUAR_SIZE, 0.F, 1.F) * pi) * NORM) + NORM},
+ atmosScatter {((half_pi - sunPos.y) / half_pi * ATMOSPHERE_SCATTER_RANGE) + ATMOSPHERE_SCATTER_MIN}
{
}
diff --git a/gfx/lightDirection.h b/gfx/lightDirection.h
index 789830b..296f497 100644
--- a/gfx/lightDirection.h
+++ b/gfx/lightDirection.h
@@ -31,9 +31,16 @@ public:
return dir;
}
+ [[nodiscard]] float
+ atmosphericScattering() const noexcept
+ {
+ return atmosScatter;
+ }
+
private:
Direction2D pos;
Direction3D vec;
float amb;
float dir;
+ float atmosScatter;
};
diff --git a/test/test-environment.cpp b/test/test-environment.cpp
index a249192..4fb5d13 100644
--- a/test/test-environment.cpp
+++ b/test/test-environment.cpp
@@ -12,7 +12,8 @@
namespace {
using SunPosTestData = std::tuple<Direction2D, time_t, Direction2D>;
- using SunDirTestData = std::tuple<Direction2D, Direction3D, float, float>;
+ using SunDirTestData = std::tuple<Direction2D, Direction3D>;
+ using SunAmtTestData = std::tuple<float, float>;
constexpr Direction2D DONCASTER = {-1.1, 53.5};
constexpr Direction2D NEW_YORK = {74.0, 40.7};
constexpr Direction2D SYNDEY = {-151.2, -33.9};
@@ -41,24 +42,54 @@ BOOST_DATA_TEST_CASE(SunPosition,
BOOST_DATA_TEST_CASE(SunDirection,
boost::unit_test::data::make<SunDirTestData>({
- {{0.F, 0.F}, south, 0.314F, 0.0087F},
- {{90.F, 0.F}, west, 0.314F, 0.0087F},
- {{-90.F, 0.F}, east, 0.314F, 0.0087F},
+ {{0.F, 0.F}, south},
+ {{90.F, 0.F}, west},
+ {{-90.F, 0.F}, east},
// From above
// EqGM midnight, sun below horizon, shining upwards
- {{181.52F, -66.86F}, {-0.01F, 0.39F, 0.919F}, 0, 0.F},
+ {{181.52F, -66.86F}, {-0.01F, 0.39F, 0.919F}},
// EqGM just before sunrise, mostly west, north a bit, up a bit
- {{113.12F, -0.85F}, {-0.92F, 0.39F, 0.015F}, 0.299F, 0.F},
+ {{113.12F, -0.85F}, {-0.92F, 0.39F, 0.015F}},
// EqGM just after sunrise, mostly west, north a bit, down a bit
- {{113.12F, 6.05F}, {-0.92F, 0.39F, -0.015F}, 0.42F, 0.114F},
+ {{113.12F, 6.05F}, {-0.92F, 0.39F, -0.015F}},
// Doncaster noon, roughly from south to north, high in the sky, downward
- {{176.34F, 59.64F}, {-0.03F, 0.5F, -0.86F}, 1, 1},
+ {{176.34F, 59.64F}, {-0.03F, 0.5F, -0.86F}},
}),
- position, direction, amb, dir)
+ position, direction)
{
const LightDirection lightDir {position * degreesToRads};
BOOST_CHECK_CLOSE_VEC(lightDir.vector(), direction);
BOOST_CHECK_CLOSE(glm::length(lightDir.vector()), 1.F, 1);
- BOOST_CHECK_CLOSE(lightDir.ambient(), amb, 5);
- BOOST_CHECK_CLOSE(lightDir.directional(), dir, 5);
+}
+
+BOOST_DATA_TEST_CASE(SunDirectionalAmount,
+ boost::unit_test::data::make<SunAmtTestData>({
+ {5._degrees, 1.F},
+ {1._degrees, 1.F},
+ {0._degrees, 1.F},
+ {-0.25_degrees, 1.F},
+ {-0.5_degrees, 0.5F},
+ {-0.75_degrees, 0.F},
+ {-1._degrees, 0.F},
+ {-5._degrees, 0.F},
+ }),
+ elevation, amount)
+{
+ const LightDirection lightDir {{0, elevation}};
+ BOOST_CHECK_CLOSE(lightDir.directional(), amount, 1.F);
+}
+
+BOOST_DATA_TEST_CASE(SunAmbientAmount,
+ boost::unit_test::data::make<SunAmtTestData>({
+ {20._degrees, 1.F},
+ {1._degrees, 1.F},
+ {-9._degrees, 0.5F},
+ {-18._degrees, 0.F},
+ {-25._degrees, 0.F},
+ {-50._degrees, 0.F},
+ }),
+ elevation, amount)
+{
+ const LightDirection lightDir {{0, elevation}};
+ BOOST_CHECK_CLOSE(lightDir.ambient(), amount, 1.F);
}