Browse Source

Add ACES colorspace conversion and luminance functions. Closes #13

master
C. J. Howard 3 years ago
parent
commit
78a0422913
3 changed files with 91 additions and 2 deletions
  1. +2
    -1
      src/ecs/systems/astronomy-system.cpp
  2. +9
    -1
      src/renderer/passes/sky-pass.cpp
  3. +80
    -0
      src/utility/aces.hpp

+ 2
- 1
src/ecs/systems/astronomy-system.cpp View File

@ -24,6 +24,7 @@
#include "ecs/components/transform-component.hpp" #include "ecs/components/transform-component.hpp"
#include "renderer/passes/sky-pass.hpp" #include "renderer/passes/sky-pass.hpp"
#include "astro/blackbody.hpp" #include "astro/blackbody.hpp"
#include "utility/aces.hpp"
#include <iostream> #include <iostream>
namespace ecs { namespace ecs {
@ -88,7 +89,7 @@ void astronomy_system::update(double t, double dt)
// Set sun color // Set sun color
float correlated_temperature = 3000.0f + std::sin(spherical.y) * 5000.0f; float correlated_temperature = 3000.0f + std::sin(spherical.y) * 5000.0f;
float3 correlated_color = math::type_cast<float>(astro::blackbody(correlated_temperature));
float3 correlated_color = math::type_cast<float>(srgb_to_acescg(astro::blackbody(correlated_temperature)));
sun_light->set_color(correlated_color); sun_light->set_color(correlated_color);
// Set sun intensity (in lux) // Set sun intensity (in lux)

+ 9
- 1
src/renderer/passes/sky-pass.cpp View File

@ -37,6 +37,7 @@
#include "renderer/material.hpp" #include "renderer/material.hpp"
#include "scene/camera.hpp" #include "scene/camera.hpp"
#include "utility/fundamental-types.hpp" #include "utility/fundamental-types.hpp"
#include "utility/aces.hpp"
#include "math/interpolation.hpp" #include "math/interpolation.hpp"
#include "astro/astro.hpp" #include "astro/astro.hpp"
#include <cmath> #include <cmath>
@ -116,9 +117,12 @@ sky_pass::sky_pass(gl::rasterizer* rasterizer, const gl::framebuffer* framebuffe
// Calculate linear sRGB color from color temperature // Calculate linear sRGB color from color temperature
double3 color_srgb = astro::blackbody(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 // Scale color by apparent magnitude
double intensity = astro::vmag_to_lux(vmag); double intensity = astro::vmag_to_lux(vmag);
double3 scaled_color = color_srgb * intensity;
double3 scaled_color = color_acescg * intensity;
// Build vertex // Build vertex
*(star_vertex++) = static_cast<float>(rectangular.x); *(star_vertex++) = static_cast<float>(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_projection_input = star_shader_program->get_input("projection");
star_distance_input = star_shader_program->get_input("star_distance"); star_distance_input = star_shader_program->get_input("star_distance");
star_exposure_input = star_shader_program->get_input("camera.exposure"); 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() sky_pass::~sky_pass()

+ 80
- 0
src/utility/aces.hpp View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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 <class T>
math::vector<T, 3> srgb_to_acescg(const math::vector<T, 3>& x)
{
static const math::matrix<T, 3, 3> 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 <class T>
math::vector<T, 3> acescg_to_srgb(const math::vector<T, 3>& x)
{
static const math::matrix<T, 3, 3> 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 <class T>
T acescg_to_luminance(const math::vector<T, 3>& x)
{
static const math::vector<T, 3> luma = {0.2722287168, 0.6740817658, 0.0536895174};
return math::dot(x, luma);
}
#endif // ANTKEEPER_ACES_HPP

Loading…
Cancel
Save