summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2024-10-24 03:10:08 +0100
committerDan Goodliffe <dan@randomdan.homeip.net>2024-10-24 03:10:10 +0100
commit0889f3f6d7b96c6f6d186ca8fa7f4e9e0ec9c701 (patch)
tree987c196297c9be79dfc78875952965c4af2ebc28
parentMerge branch 'billboard-shadows' (diff)
downloadilt-0889f3f6d7b96c6f6d186ca8fa7f4e9e0ec9c701.tar.bz2
ilt-0889f3f6d7b96c6f6d186ca8fa7f4e9e0ec9c701.tar.xz
ilt-0889f3f6d7b96c6f6d186ca8fa7f4e9e0ec9c701.zip
Improve sun illumination based on angular size and astronomical twilight
-rw-r--r--game/environment.cpp4
-rw-r--r--gfx/lightDirection.cpp6
-rw-r--r--gfx/lightDirection.h13
-rw-r--r--lib/maths.h6
-rw-r--r--test/test-environment.cpp21
5 files changed, 34 insertions, 16 deletions
diff --git a/game/environment.cpp b/game/environment.cpp
index 5aa1f09..acb4f21 100644
--- a/game/environment.cpp
+++ b/game/environment.cpp
@@ -18,8 +18,8 @@ Environment::render(const SceneRenderer & renderer, const SceneProvider & scene)
constexpr RGB relativeAmbient {0.3F, 0.3F, 0.4F}, relativeDirectional {0.6F, 0.6F, 0.5F};
const LightDirection sunPos = getSunPos({}, worldTime);
- const auto ambient = baseAmbient + relativeAmbient * sunPos.vertical();
- const auto directional = baseDirectional + relativeDirectional * sunPos.vertical();
+ const auto ambient = baseAmbient + relativeAmbient * sunPos.ambient();
+ const auto directional = baseDirectional + relativeDirectional * sunPos.directional();
renderer.setAmbientLight(ambient);
renderer.setDirectionalLight(directional, sunPos, scene);
diff --git a/gfx/lightDirection.cpp b/gfx/lightDirection.cpp
index 6d7d1ea..3932872 100644
--- a/gfx/lightDirection.cpp
+++ b/gfx/lightDirection.cpp
@@ -1,8 +1,12 @@
#include "lightDirection.h"
#include "maths.h"
+constexpr auto ASTRONOMICAL_TWILIGHT = 18.0_degrees;
+constexpr auto SUN_ANGLUAR_SIZE = 0.5_degrees;
+
LightDirection::LightDirection(const Direction2D sunPos) :
pos {sunPos}, vec {glm::mat3 {rotate_yp(pi + sunPos.x, -sunPos.y)} * north},
- vert {-glm::clamp(-1.F, 0.F, vec.z - 0.1F)}
+ amb {glm::clamp(sunPos.y + ASTRONOMICAL_TWILIGHT, 0.F, 1.F)},
+ dir {glm::clamp(sunPos.y + SUN_ANGLUAR_SIZE, 0.F, 1.F)}
{
}
diff --git a/gfx/lightDirection.h b/gfx/lightDirection.h
index f1e1cc4..789830b 100644
--- a/gfx/lightDirection.h
+++ b/gfx/lightDirection.h
@@ -20,13 +20,20 @@ public:
}
[[nodiscard]] float
- vertical() const noexcept
+ ambient() const noexcept
{
- return vert;
+ return amb;
+ }
+
+ [[nodiscard]] float
+ directional() const noexcept
+ {
+ return dir;
}
private:
Direction2D pos;
Direction3D vec;
- float vert;
+ float amb;
+ float dir;
};
diff --git a/lib/maths.h b/lib/maths.h
index 90ddb69..14a29d1 100644
--- a/lib/maths.h
+++ b/lib/maths.h
@@ -422,3 +422,9 @@ kph_to_ms(T v)
// ... literals are handy for now, probably go away when we load stuff externally
float operator"" _mph(const long double v);
float operator"" _kph(const long double v);
+
+constexpr float
+operator"" _degrees(long double degrees)
+{
+ return static_cast<float>(degrees) * degreesToRads;
+}
diff --git a/test/test-environment.cpp b/test/test-environment.cpp
index 76144a4..8bd64be 100644
--- a/test/test-environment.cpp
+++ b/test/test-environment.cpp
@@ -12,7 +12,7 @@
#include <maths.h>
using sunPosTestData = std::tuple<Direction2D, time_t, Direction2D>;
-using sunDirTestData = std::tuple<Direction2D, Direction3D, float>;
+using sunDirTestData = std::tuple<Direction2D, Direction3D, float, float>;
constexpr Direction2D Doncaster = {-1.1, 53.5};
constexpr Direction2D NewYork = {74.0, 40.7};
constexpr Direction2D Syndey = {-151.2, -33.9};
@@ -40,23 +40,24 @@ BOOST_DATA_TEST_CASE(sun_position,
BOOST_DATA_TEST_CASE(sun_direction,
boost::unit_test::data::make<sunDirTestData>({
- {{0.F, 0.F}, south, 0.1F},
- {{90.F, 0.F}, west, 0.1F},
- {{-90.F, 0.F}, east, 0.1F},
+ {{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},
// From above
// EqGM midnight, sun below horizon, shining upwards
- {{181.52F, -66.86F}, {-0.01F, 0.39F, 0.919F}, 0},
+ {{181.52F, -66.86F}, {-0.01F, 0.39F, 0.919F}, 0, 0.F},
// EqGM just before sunrise, mostly west, north a bit, up a bit
- {{113.12F, -0.85F}, {-0.92F, 0.39F, 0.015F}, 0.085F},
+ {{113.12F, -0.85F}, {-0.92F, 0.39F, 0.015F}, 0.299F, 0.F},
// EqGM just after sunrise, mostly west, north a bit, down a bit
- {{113.12F, 6.05F}, {-0.92F, 0.39F, -0.015F}, 0.205F},
+ {{113.12F, 6.05F}, {-0.92F, 0.39F, -0.015F}, 0.42F, 0.114F},
// Doncaster noon, roughly from south to north, high in the sky, downward
- {{176.34F, 59.64F}, {-0.03F, 0.5F, -0.86F}, 0.96F},
+ {{176.34F, 59.64F}, {-0.03F, 0.5F, -0.86F}, 1, 1},
}),
- position, direction, vert)
+ position, direction, amb, dir)
{
const LightDirection ld {position * degreesToRads};
BOOST_CHECK_CLOSE_VEC(ld.vector(), direction);
BOOST_CHECK_CLOSE(glm::length(ld.vector()), 1.F, 1);
- BOOST_CHECK_CLOSE(ld.vertical(), vert, 5);
+ BOOST_CHECK_CLOSE(ld.ambient(), amb, 5);
+ BOOST_CHECK_CLOSE(ld.directional(), dir, 5);
}