diff --git a/src/color/acescg.hpp b/src/color/acescg.hpp
new file mode 100644
index 0000000..71c8ec3
--- /dev/null
+++ b/src/color/acescg.hpp
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2021 Christopher J. Howard
+ *
+ * This file is part of Antkeeper source code.
+ *
+ * Antkeeper source code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Antkeeper source code is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Antkeeper source code. If not, see .
+ */
+
+#ifndef ANTKEEPER_COLOR_ACESCG_HPP
+#define ANTKEEPER_COLOR_ACESCG_HPP
+
+#include "math/math.hpp"
+
+namespace color {
+
+/// Functions which operate in the ACEScg colorspace.
+namespace acescg {
+
+/**
+ * Calculates the luminance of an ACEScg color.
+ *
+ * @param x ACEScg color.
+ * @return return Luminance of @p x.
+ */
+template
+T luminance(const math::vector3& x);
+
+/**
+ * Transforms an ACEScg color into the linear sRGB colorspace using the Bradford chromatic adaption transform.
+ *
+ * @param x ACEScg color.
+ * @return return Linear sRGB color.
+ *
+ * @see https://www.colour-science.org/apps/
+ */
+template
+math::vector3 to_srgb(const math::vector3& x);
+
+/**
+ * Transforms an ACEScg color into the CIE XYZ colorspace.
+ *
+ * @param x ACEScg color.
+ * @return return CIE XYZ color.
+ */
+template
+math::vector3 to_xyz(const math::vector3& x);
+
+template
+T luminance(const math::vector3& x)
+{
+ static const math::vector3 luma = {0.272228716780914, 0.674081765811148, 0.053689517407937};
+ return math::dot(x, luma);
+}
+
+template
+math::vector3 to_srgb(const math::vector3& x)
+{
+ static const math::matrix3 acescg_to_srgb
+ {{
+ { 1.704858676289160, -0.130076824208823, -0.023964072927574},
+ {-0.621716021885330, 1.140735774822504, -0.128975508299318},
+ {-0.083299371729058, -0.010559801677511, 1.153014018916862}
+ }};
+
+ return acescg_to_srgb * x;
+}
+
+template
+math::vector3 to_xyz(const math::vector3& x)
+{
+ static const math::matrix3 acescg_to_xyz
+ {{
+ {0.662454181108505, 0.272228716780914, -0.005574649490394},
+ {0.134004206456433, 0.674081765811148, 0.004060733528983},
+ {0.156187687004908, 0.053689517407937, 1.010339100312997}
+ }};
+
+ return acescg_to_xyz * x;
+}
+
+} // namespace acescg
+} // namespace color
+
+#endif // ANTKEEPER_COLOR_ACESCG_HPP
diff --git a/src/utility/gamma.hpp b/src/color/color.hpp
similarity index 62%
rename from src/utility/gamma.hpp
rename to src/color/color.hpp
index a42e512..82f83d6 100644
--- a/src/utility/gamma.hpp
+++ b/src/color/color.hpp
@@ -17,32 +17,14 @@
* along with Antkeeper source code. If not, see .
*/
-#ifndef ANTKEEPER_GAMMA_HPP
-#define ANTKEEPER_GAMMA_HPP
+#ifndef ANTKEEPER_COLOR_HPP
+#define ANTKEEPER_COLOR_HPP
-#include "math/vector-type.hpp"
-#include
+/// Color manipulation functions.
+namespace color {}
-template
-T srgb_to_linear(const T& x)
-{
- if (x <= T(0.04045))
- {
- return x / T(12.92);
- }
-
- return std::pow((x + T(0.055)) / T(1.055), T(2.4));
-}
+#include "acescg.hpp"
+#include "srgb.hpp"
+#include "xyz.hpp"
-template
-T linear_to_srgb(const T& x)
-{
- if (x <= T(0.0031308))
- {
- return x * T(12.92);
- }
-
- return std::pow(x, T(1.0 / 2.4)) * T(1.055) - T(0.055);
-}
-
-#endif // ANTKEEPER_GAMMA_HPP
+#endif // ANTKEEPER_COLOR_HPP
diff --git a/src/color/srgb.hpp b/src/color/srgb.hpp
new file mode 100644
index 0000000..98ac149
--- /dev/null
+++ b/src/color/srgb.hpp
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2021 Christopher J. Howard
+ *
+ * This file is part of Antkeeper source code.
+ *
+ * Antkeeper source code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Antkeeper source code is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Antkeeper source code. If not, see .
+ */
+
+#ifndef ANTKEEPER_COLOR_SRGB_HPP
+#define ANTKEEPER_COLOR_SRGB_HPP
+
+#include "math/math.hpp"
+#include
+
+namespace color {
+
+/// Functions which operate in the sRGB colorspace.
+namespace srgb {
+
+/**
+ * Performs the sRGB Electro-Optical Transfer Function (EOTF), also known as the sRGB decoding function.
+ *
+ * @param v sRGB electrical signal (gamma-encoded sRGB).
+ * @return Corresponding luminance of the signal (linear sRGB).
+ */
+/// @{
+float eotf(float v);
+double eotf(double v);
+template
+math::vector3 eotf(const math::vector3& v);
+/// @}
+
+/**
+ * Performs the sRGB inverse Electro-Optical Transfer Function (EOTF), also known as the sRGB encoding function.
+ *
+ * @param l sRGB luminance (linear sRGB).
+ * @return Corresponding electrical signal (gamma-encoded sRGB).
+ */
+/// @{
+float eotf_inverse(float v);
+double eotf_inverse(double v);
+template
+math::vector3 eotf_inverse(const math::vector3& l);
+/// @}
+
+/**
+ * Calculates the luminance of a linear sRGB color.
+ *
+ * @param x Linear sRGB color.
+ * @return return Luminance of @p x.
+ */
+template
+T luminance(const math::vector3& x);
+
+/**
+ * Transforms a linear sRGB color into the ACEScg colorspace using the Bradford chromatic adaption transform.
+ *
+ * @param x Linear sRGB color.
+ * @return ACEScg color.
+ *
+ * @see https://www.colour-science.org/apps/
+ */
+template
+math::vector3 to_acescg(const math::vector3& x);
+
+/**
+ * Transforms a linear sRGB color into the CIE XYZ colorspace.
+ *
+ * @param x Linear sRGB color.
+ * @return CIE XYZ color.
+ */
+template
+math::vector3 to_xyz(const math::vector3& x);
+
+inline float eotf(float v)
+{
+ return (v < 0.04045f) ? (v / 12.92f) : std::pow((v + 0.055f) / 1.055f, 2.4f);
+}
+
+inline double eotf(double v)
+{
+ return (v < 0.04045) ? (v / 12.92) : std::pow((v + 0.055) / 1.055, 2.4);
+}
+
+template
+math::vector3 eotf(const math::vector3& v)
+{
+ return math::vector3
+ {
+ eotf(v[0]),
+ eotf(v[1]),
+ eotf(v[2])
+ };
+}
+
+inline float eotf_inverse(float l)
+{
+ return (l <= 0.0031308f) ? (l * 12.92f) : (std::pow(l, 1.0f / 2.4f) * 1.055f - 0.055f);
+}
+
+inline double eotf_inverse(double l)
+{
+ return (l <= 0.0031308) ? (l * 12.92) : (std::pow(l, 1.0 / 2.4) * 1.055 - 0.055);
+}
+
+template
+math::vector3 eotf_inverse(const math::vector3& l)
+{
+ return math::vector3
+ {
+ eotf_inverse(l[0]),
+ eotf_inverse(l[1]),
+ eotf_inverse(l[2])
+ };
+}
+
+template
+T luminance(const math::vector3& x)
+{
+ static const math::vector3 luma = {0.212639005871510, 0.715168678767756, 0.072192315360734};
+ return math::dot(x, luma);
+}
+
+template
+math::vector3 to_acescg(const math::vector3& x)
+{
+ static const math::matrix3 srgb_to_acescg
+ {{
+ {0.613132422390542, 0.070124380833917, 0.020587657528185},
+ {0.339538015799666, 0.916394011313573, 0.109574571610682},
+ {0.047416696048269, 0.013451523958235, 0.869785404035327}
+ }};
+
+ return srgb_to_acescg * x;
+}
+
+template
+math::vector3 to_xyz(const math::vector3& x)
+{
+ static const math::matrix3 srgb_to_xyz
+ {{
+ {0.412390799265959, 0.212639005871510, 0.019330818715592},
+ {0.357584339383878, 0.715168678767756, 0.119194779794626},
+ {0.180480788401834, 0.072192315360734, 0.950532152249661}
+ }};
+
+ return srgb_to_xyz * x;
+}
+
+} // namespace srgb
+} // namespace color
+
+#endif // ANTKEEPER_COLOR_SRGB_HPP
diff --git a/src/color/xyz.hpp b/src/color/xyz.hpp
new file mode 100644
index 0000000..1c79531
--- /dev/null
+++ b/src/color/xyz.hpp
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2021 Christopher J. Howard
+ *
+ * This file is part of Antkeeper source code.
+ *
+ * Antkeeper source code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Antkeeper source code is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Antkeeper source code. If not, see .
+ */
+
+#ifndef ANTKEEPER_COLOR_XYZ_HPP
+#define ANTKEEPER_COLOR_XYZ_HPP
+
+#include "math/math.hpp"
+
+namespace color {
+
+/// Functions which operate in the CIE XYZ colorspace.
+namespace xyz {
+
+/**
+ * Returns the luminance of a CIE XYZ color.
+ *
+ * @param x CIE XYZ color.
+ * @return return Luminance of @p x.
+ */
+template
+T luminance(const math::vector3& x);
+
+/**
+ * Transforms a CIE XYZ color into the ACEScg colorspace.
+ *
+ * @param x CIE XYZ color.
+ * @return ACEScg color.
+ */
+template
+math::vector3 to_acescg(const math::vector3& x);
+
+/**
+ * Transforms a CIE XYZ color into the linear sRGB colorspace.
+ *
+ * @param x CIE XYZ color.
+ * @return Linear sRGB color.
+ */
+template
+math::vector3 to_srgb(const math::vector3& x);
+
+template
+inline T luminance(const math::vector3& x)
+{
+ return x[1];
+}
+
+template
+math::vector3 to_acescg(const math::vector3& x)
+{
+ static const math::matrix3 xyz_to_acescg
+ {{
+ { 1.641023379694326 -0.663662858722983 0.011721894328375},
+ {-0.324803294184790 1.615331591657338 -0.008284441996237},
+ {-0.236424695237612, 0.016756347685530, 0.988394858539022}
+ }};
+
+ return xyz_to_acescg * x;
+}
+
+template
+math::vector3 to_srgb(const math::vector3& x)
+{
+ static const math::matrix3 xyz_to_srgb
+ {{
+ { 3.240969941904523, -0.969243636280880, 0.055630079696994},
+ {-1.537383177570094, 1.875967501507721, -0.203976958888977},
+ {-0.498610760293003, 0.041555057407176, 1.056971514242879}
+ }};
+
+ return xyz_to_srgb * x;
+}
+
+} // namespace xyz
+} // namespace color
+
+#endif // ANTKEEPER_COLOR_XYZ_HPP
diff --git a/src/ecs/systems/astronomy-system.cpp b/src/ecs/systems/astronomy-system.cpp
index 0788572..4faff90 100644
--- a/src/ecs/systems/astronomy-system.cpp
+++ b/src/ecs/systems/astronomy-system.cpp
@@ -24,7 +24,7 @@
#include "ecs/components/transform-component.hpp"
#include "renderer/passes/sky-pass.hpp"
#include "astro/blackbody.hpp"
-#include "utility/aces.hpp"
+#include "color/color.hpp"
#include
namespace ecs {
@@ -89,7 +89,7 @@ void astronomy_system::update(double t, double dt)
// Set sun color
float correlated_temperature = 3000.0f + std::sin(spherical.y) * 5000.0f;
- float3 correlated_color = math::type_cast(srgb_to_acescg(astro::blackbody(correlated_temperature)));
+ float3 correlated_color = math::type_cast(color::srgb::to_acescg(astro::blackbody(correlated_temperature)));
sun_light->set_color(correlated_color);
// Set sun intensity (in lux)
diff --git a/src/ecs/systems/weather-system.cpp b/src/ecs/systems/weather-system.cpp
index 6447f48..0cf1729 100644
--- a/src/ecs/systems/weather-system.cpp
+++ b/src/ecs/systems/weather-system.cpp
@@ -23,10 +23,6 @@
#include "renderer/passes/sky-pass.hpp"
#include "renderer/passes/shadow-map-pass.hpp"
#include "renderer/passes/material-pass.hpp"
-#include "utility/gamma.hpp"
-#include "resources/image.hpp"
-#include "astro/coordinates.hpp"
-#include "astro/orbit.hpp"
#include
namespace ecs {
diff --git a/src/game/states/play-state.cpp b/src/game/states/play-state.cpp
index 0f62e69..2c3b7ee 100644
--- a/src/game/states/play-state.cpp
+++ b/src/game/states/play-state.cpp
@@ -61,7 +61,6 @@
#include "ecs/systems/astronomy-system.hpp"
#include "game/biome.hpp"
#include "utility/fundamental-types.hpp"
-#include "utility/gamma.hpp"
#include "astro/blackbody.hpp"
#include "utility/bit-math.hpp"
diff --git a/src/math/matrix-type.hpp b/src/math/matrix-type.hpp
index 9f8a469..d60d1f1 100644
--- a/src/math/matrix-type.hpp
+++ b/src/math/matrix-type.hpp
@@ -43,6 +43,18 @@ struct matrix
inline constexpr const row_type& operator[](std::size_t i) const noexcept { return columns[i]; }
};
+/// 2x2 matrix.
+template
+using matrix2 = matrix;
+
+/// 3x3 matrix.
+template
+using matrix3 = matrix;
+
+/// 4x4 matrix.
+template
+using matrix4 = matrix;
+
} // namespace math
#endif // ANTKEEPER_MATH_MATRIX_TYPE_HPP
diff --git a/src/math/vector-type.hpp b/src/math/vector-type.hpp
index 80aa108..6ea755d 100644
--- a/src/math/vector-type.hpp
+++ b/src/math/vector-type.hpp
@@ -118,6 +118,18 @@ struct vector
inline constexpr std::size_t size() const noexcept { return 4; };
};
+/// 2D vector.
+template
+using vector2 = vector;
+
+/// 3D vector.
+template
+using vector3 = vector;
+
+/// 4D vector.
+template
+using vector4 = vector;
+
} // namespace math
#endif // ANTKEEPER_MATH_VECTOR_TYPE_HPP
diff --git a/src/renderer/passes/sky-pass.cpp b/src/renderer/passes/sky-pass.cpp
index 42820a7..b5c4e69 100644
--- a/src/renderer/passes/sky-pass.cpp
+++ b/src/renderer/passes/sky-pass.cpp
@@ -37,7 +37,7 @@
#include "renderer/material.hpp"
#include "scene/camera.hpp"
#include "utility/fundamental-types.hpp"
-#include "utility/aces.hpp"
+#include "color/color.hpp"
#include "math/interpolation.hpp"
#include "astro/astro.hpp"
#include
@@ -118,16 +118,14 @@ sky_pass::sky_pass(gl::rasterizer* rasterizer, const gl::framebuffer* framebuffe
double3 color_srgb = astro::blackbody(color_temperature);
// Transform to ACEScg colorspace
- double3 color_acescg = srgb_to_acescg(color_srgb);
+ double3 color_acescg = color::srgb::to_acescg(color_srgb);
// Calculate color luminance
- double color_luminance = acescg_to_luminance(color_acescg);
+ double color_luminance = color::acescg::luminance(color_acescg);
// Convert apparent magnitude to lux
double vmag_lux = astro::vmag_to_lux(vmag);
- std::cout << "mag: " << vmag << "; lux: " << vmag_lux << "remag: " << (astro::lux_to_vmag(vmag_lux)) << std::endl;
-
// Normalized color luminance and scale by apparent magnitude
double3 scaled_color = color_acescg * ((1.0 / color_luminance) * vmag_lux);
diff --git a/src/utility/aces.hpp b/src/utility/aces.hpp
deleted file mode 100644
index 4c3232b..0000000
--- a/src/utility/aces.hpp
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2021 Christopher J. Howard
- *
- * This file is part of Antkeeper source code.
- *
- * Antkeeper source code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Antkeeper source code is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Antkeeper source code. If not, see .
- */
-
-#ifndef ANTKEEPER_ACES_HPP
-#define ANTKEEPER_ACES_HPP
-
-#include "math/vector-type.hpp"
-
-/**
- * Transforms a linear sRGB color into the ACEScg colorspace, using the Bradford chromatic adaption transform.
- *
- * @param x Linear sRGB color.
- * @return Linear ACEScg color.
- *
- * @see https://www.colour-science.org/apps/
- */
-template
-math::vector srgb_to_acescg(const math::vector& x)
-{
- static const math::matrix matrix
- {{
- {0.6131324224, 0.0701243808, 0.0205876575},
- {0.3395380158, 0.9163940113, 0.1095745716},
- {0.0474166960, 0.0134515240, 0.8697854040}
- }};
-
- return matrix * x;
-}
-
-/**
- * Transforms an ACEScg color into the linear sRGB colorspace, using the Bradford chromatic adaption transform.
- *
- * @param x Linear ACEScg color.
- * @param return Linear sRGB color.
- *
- * @see https://www.colour-science.org/apps/
- */
-template
-math::vector acescg_to_srgb(const math::vector& x)
-{
- static const math::matrix matrix
- {{
- { 1.7048586763, -0.1300768242, -0.0239640729},
- {-0.6217160219, 1.1407357748, -0.1289755083},
- {-0.0832993717, -0.0105598017, 1.1530140189}
- }};
-
- return matrix * x;
-}
-
-/**
- * Calculates the luminance of an ACEScg color.
- *
- * @param x Linear ACEScg color.
- * @param return Luminance of @p x.
- */
-template
-T acescg_to_luminance(const math::vector& x)
-{
- static const math::vector luma = {0.2722287168, 0.6740817658, 0.0536895174};
- return math::dot(x, luma);
-}
-
-#endif // ANTKEEPER_ACES_HPP