diff --git a/src/ecs/systems/astronomy-system.cpp b/src/ecs/systems/astronomy-system.cpp index e7e9e7f..0788572 100644 --- a/src/ecs/systems/astronomy-system.cpp +++ b/src/ecs/systems/astronomy-system.cpp @@ -24,6 +24,7 @@ #include "ecs/components/transform-component.hpp" #include "renderer/passes/sky-pass.hpp" #include "astro/blackbody.hpp" +#include "utility/aces.hpp" #include namespace ecs { @@ -88,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(astro::blackbody(correlated_temperature)); + float3 correlated_color = math::type_cast(srgb_to_acescg(astro::blackbody(correlated_temperature))); sun_light->set_color(correlated_color); // Set sun intensity (in lux) diff --git a/src/renderer/passes/sky-pass.cpp b/src/renderer/passes/sky-pass.cpp index fe27832..380b758 100644 --- a/src/renderer/passes/sky-pass.cpp +++ b/src/renderer/passes/sky-pass.cpp @@ -37,6 +37,7 @@ #include "renderer/material.hpp" #include "scene/camera.hpp" #include "utility/fundamental-types.hpp" +#include "utility/aces.hpp" #include "math/interpolation.hpp" #include "astro/astro.hpp" #include @@ -116,9 +117,12 @@ sky_pass::sky_pass(gl::rasterizer* rasterizer, const gl::framebuffer* framebuffe // Calculate linear sRGB color from color temperature double3 color_srgb = astro::blackbody(color_temperature); + // Transform to ACEScg colorspace + double3 color_acescg = srgb_to_acescg(color_srgb); + // Scale color by apparent magnitude double intensity = astro::vmag_to_lux(vmag); - double3 scaled_color = color_srgb * intensity; + double3 scaled_color = color_acescg * intensity; // Build vertex *(star_vertex++) = static_cast(rectangular.x); @@ -153,6 +157,10 @@ sky_pass::sky_pass(gl::rasterizer* rasterizer, const gl::framebuffer* framebuffe star_projection_input = star_shader_program->get_input("projection"); star_distance_input = star_shader_program->get_input("star_distance"); star_exposure_input = star_shader_program->get_input("camera.exposure"); + + std::cout << "vmag_to_lux(-14.2) = " << astro::vmag_to_lux(-14.2) << std::endl; + std::cout << "vmag_to_lux(-26.74) = " << astro::vmag_to_lux(-26.74) << std::endl; + std::cout << "vmag_to_lux(-1.47) = " << astro::vmag_to_lux(-1.47) << std::endl; } sky_pass::~sky_pass() diff --git a/src/utility/aces.hpp b/src/utility/aces.hpp new file mode 100644 index 0000000..4c3232b --- /dev/null +++ b/src/utility/aces.hpp @@ -0,0 +1,80 @@ +/* + * 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