Photon Engine 2.0.0-beta
A physically based renderer.
Loading...
Searching...
No Matches
TSpectrumBase.ipp
Go to the documentation of this file.
1#pragma once
2
4#include "Math/math.h"
7
8#include <Common/assertion.h>
9
10#include <cmath>
11
12namespace ph::math
13{
14
15template<typename Derived, EColorSpace COLOR_SPACE, typename T, std::size_t N>
16template<typename U>
18{
19 for(std::size_t i = 0; i < N; ++i)
20 {
21 m[i] = static_cast<T>(values[i]);
22 }
23}
24
25template<typename Derived, EColorSpace COLOR_SPACE, typename T, std::size_t N>
27{
28 return COLOR_SPACE;
29}
30
31template<typename Derived, EColorSpace COLOR_SPACE, typename T, std::size_t N>
33{
34 // minIndex() is not exposed; use "this" to access it in current scope
35 return this->minIndex();
36}
37
38template<typename Derived, EColorSpace COLOR_SPACE, typename T, std::size_t N>
40{
41 // maxIndex() is not exposed; use "this" to access it in current scope
42 return this->maxIndex();
43}
44
45template<typename Derived, EColorSpace COLOR_SPACE, typename T, std::size_t N>
47-> Derived&
49 // set() is not exposed; use "this" to access it in current scope
50 return this->set(values);
51}
53template<typename Derived, EColorSpace COLOR_SPACE, typename T, std::size_t N>
55-> Derived&
56{
57 // set() is not exposed; use "this" to access it in current scope
58 return this->set(rawColorValues);
59}
61template<typename Derived, EColorSpace COLOR_SPACE, typename T, std::size_t N>
63-> const TRawColorValues<T, N>&
64{
65 return m;
66}
67
68template<typename Derived, EColorSpace COLOR_SPACE, typename T, std::size_t N>
69template<EColorSpace SRC_COLOR_SPACE>
70inline auto TSpectrumBase<Derived, COLOR_SPACE, T, N>::setTransformed(const auto& srcColorValues, const EColorUsage usage)
71-> Derived&
73 const auto transformedColorValues = transform_color<SRC_COLOR_SPACE, COLOR_SPACE, T>(
74 srcColorValues, usage);
75 setColorValues(transformedColorValues);
76
77 return static_cast<Derived&>(*this);
78}
79
80template<typename Derived, EColorSpace COLOR_SPACE, typename T, std::size_t N>
81template<CColorValuesInterface ImplType>
82inline auto TSpectrumBase<Derived, COLOR_SPACE, T, N>::setTransformed(const ImplType& srcColorValues, const EColorUsage usage)
83-> Derived&
84{
85 return setTransformed<ImplType::getColorSpace()>(
86 srcColorValues.getColorValues(), usage);
87}
88
89template<typename Derived, EColorSpace COLOR_SPACE, typename T, std::size_t N>
90template<EColorSpace SPECTRAL_COLOR_SPACE>
92-> Derived&
93{
95
96 return setTransformed<SPECTRAL_COLOR_SPACE>(sampleValues, usage);
97}
99template<typename Derived, EColorSpace COLOR_SPACE, typename T, std::size_t N>
100template<CColorValuesInterface ImplType>
101inline auto TSpectrumBase<Derived, COLOR_SPACE, T, N>::setSpectral(const ImplType& sampleValues, const EColorUsage usage)
102-> Derived&
103{
104 return setSpectral<ImplType::getColorSpace()>(
105 sampleValues.getColorValues(), usage);
106}
107
108template<typename Derived, EColorSpace COLOR_SPACE, typename T, std::size_t N>
109template<EColorSpace DST_COLOR_SPACE>
111{
113 getColorValues(), usage);
114}
115
116template<typename Derived, EColorSpace COLOR_SPACE, typename T, std::size_t N>
117template<EColorSpace DST_COLOR_SPACE>
119{
120 return toTransformed<DST_COLOR_SPACE>(usage);
121}
122
123template<typename Derived, EColorSpace COLOR_SPACE, typename T, std::size_t N>
125{
126 return relative_luminance<COLOR_SPACE, T>(getColorValues(), usage);
127}
128
129template<typename Derived, EColorSpace COLOR_SPACE, typename T, std::size_t N>
130template<EColorSpace SRC_COLOR_SPACE>
132 const auto& srcColorValues, const EColorUsage usage)
133{
134 if constexpr(is_compatible<decltype(srcColorValues), SRC_COLOR_SPACE>)
135 {
136 setTransformed<SRC_COLOR_SPACE>(srcColorValues, usage);
137 }
138 else
139 {
140 throw ColorError(
141 "Using incompatible type for color transformation (`srcColorValues` is incompatible "
142 "with its color space).");
143 }
144}
145
146template<typename Derived, EColorSpace COLOR_SPACE, typename T, std::size_t N>
147template<EColorSpace DST_COLOR_SPACE>
148inline void TSpectrumBase<Derived, COLOR_SPACE, T, N>::toTransformedIfCompatible(
149 auto* const out_dstColorValues, const EColorUsage usage) const
150{
151 PH_ASSERT(out_dstColorValues);
152
154 {
155 *out_dstColorValues = toTransformed<DST_COLOR_SPACE>(usage);
156 }
157 else
158 {
159 throw ColorError(
160 "Using incompatible type for color transformation (`out_dstColorValues` is incompatible "
161 "with its color space).");
162 }
163}
164
165template<typename Derived, EColorSpace COLOR_SPACE, typename T, std::size_t N>
167 const auto& srcColorValues, const EColorSpace srcColorSpace, const EColorUsage usage)
168{
169 switch(srcColorSpace)
170 {
172 return setTransformedIfCompatible<EColorSpace::CIE_XYZ>(srcColorValues, usage);
173
175 return setTransformedIfCompatible<EColorSpace::CIE_xyY>(srcColorValues, usage);
176
178 return setTransformedIfCompatible<EColorSpace::Linear_sRGB>(srcColorValues, usage);
179
181 return setTransformedIfCompatible<EColorSpace::sRGB>(srcColorValues, usage);
182
184 return setTransformedIfCompatible<EColorSpace::ACEScg>(srcColorValues, usage);
185
187 return setTransformedIfCompatible<EColorSpace::Spectral_Smits>(srcColorValues, usage);
188
189 default:
190 // When failed, you may have added/removed some entries. Handle it in the above section.
191 PH_ASSERT_UNREACHABLE_SECTION();
192 setColorValues(0);
193 break;
194 }
195}
196
197template<typename Derived, EColorSpace COLOR_SPACE, typename T, std::size_t N>
199 auto* const out_dstColorValues, const EColorSpace dstColorSpace, const EColorUsage usage) const
200{
201 PH_ASSERT(out_dstColorValues);
202
203 switch(dstColorSpace)
204 {
206 return toTransformedIfCompatible<EColorSpace::CIE_XYZ>(out_dstColorValues, usage);
207
209 return toTransformedIfCompatible<EColorSpace::CIE_xyY>(out_dstColorValues, usage);
210
212 return toTransformedIfCompatible<EColorSpace::Linear_sRGB>(out_dstColorValues, usage);
213
215 return toTransformedIfCompatible<EColorSpace::sRGB>(out_dstColorValues, usage);
216
218 return toTransformedIfCompatible<EColorSpace::ACEScg>(out_dstColorValues, usage);
219
221 return toTransformedIfCompatible<EColorSpace::Spectral_Smits>(out_dstColorValues, usage);
222
223 default:
224 // When failed, you may have added/removed some entries. Handle it in the above section.
225 PH_ASSERT_UNREACHABLE_SECTION();
226 out_dstColorValues->fill(0);
227 break;
228 }
229}
230
231template<typename Derived, EColorSpace COLOR_SPACE, typename T, std::size_t N>
233-> Derived&
234{
235 static_assert(CColorValuesInterface<Derived>);
236
237 const auto transformedColorValues = transform_from_linear_sRGB<COLOR_SPACE, T>(
238 linearSRGB, usage);
239 setColorValues(transformedColorValues);
240
241 return static_cast<Derived&>(*this);
242}
243
244template<typename Derived, EColorSpace COLOR_SPACE, typename T, std::size_t N>
247{
248 static_assert(CColorValuesInterface<Derived>);
249
251 getColorValues(), usage);
252}
253
254template<typename Derived, EColorSpace COLOR_SPACE, typename T, std::size_t N>
256-> Derived&
257{
258 static_assert(CColorValuesInterface<Derived>);
259
260 // For tristimulus color space, use default spectral color space
262 {
263 return setColorValues(
264 put_color_energy<COLOR_SPACE, T>(getColorValues(), energyLevel));
265 }
266 // For spectral color space, use itself
267 else
268 {
269 return setColorValues(
270 put_color_energy<COLOR_SPACE, T, COLOR_SPACE>(getColorValues(), energyLevel));
271 }
272}
273
274}// end namespace ph::math
Error on the color-related functionalities.
Definition math_exceptions.h:24
static consteval bool isTristimulus() noexcept
Definition color_spaces.h:81
Base for spectrum implementations.
Definition TSpectrumBase.h:28
TRawColorValues< T, 3 > toLinearSRGB(EColorUsage usage) const
Helper for converting this spectrum to linear-sRGB color.
Definition TSpectrumBase.ipp:245
Derived & setTransformed(const auto &srcColorValues, EColorUsage usage)
TSpectrumBase(const TRawColorValues< U, N > &values)
Set color values directly. Calling setColorValues() has the same effect. This is the most general for...
Definition TSpectrumBase.ipp:17
void transformTo(auto *out_dstColorValues, EColorSpace dstColorSpace, EColorUsage usage) const
Definition TSpectrumBase.ipp:198
T relativeLuminance(EColorUsage usage=EColorUsage::EMR) const
Definition TSpectrumBase.ipp:124
const TRawColorValues< T, N > & getColorValues() const
Definition TSpectrumBase.ipp:62
void transformFrom(const auto &srcColorValues, EColorSpace srcColorSpace, EColorUsage usage)
Definition TSpectrumBase.ipp:166
static consteval EColorSpace getColorSpace() noexcept
Definition TSpectrumBase.ipp:26
std::size_t maxComponent() const
Definition TSpectrumBase.ipp:39
Derived & putEnergy(T energyLevel)
Definition TSpectrumBase.ipp:255
auto toTransformed(EColorUsage usage) const
Definition TSpectrumBase.ipp:110
TSpectralSampleValues< T > toSpectral(EColorUsage usage) const
Helper for getting spectral values from this spectrum.
Definition TSpectrumBase.ipp:118
Derived & setLinearSRGB(const TRawColorValues< T, 3 > &linearSRGB, EColorUsage usage)
Helper for setting linear-sRGB color to this spectrum.
Definition TSpectrumBase.ipp:232
Derived & setSpectral(const TSpectralSampleValues< T > &sampleValues, EColorUsage usage)
Helper for setting spectral values to this spectrum.
std::size_t minComponent() const
Definition TSpectrumBase.ipp:32
Derived & setColorValues(const TRawColorValues< T, N > &values)
Set and get raw color values directly.
Definition TSpectrumBase.ipp:46
Satisfying this concept makes ImplType usable as color values.
Definition color_basics.h:75
Miscellaneous math utilities.
Math functions and utilities.
Definition TransformInfo.h:10
auto put_color_energy(const auto &srcColorValues, T energyLevel)
Definition color_spaces.ipp:783
std::array< T, N > TRawColorValues
Definition color_basics.h:45
TRawColorValues< T, SampleProps::NUM_SAMPLES > TSpectralSampleValues
Definition color_basics.h:54
T relative_luminance(const auto &srcColorValues, EColorUsage usage=EColorUsage::EMR)
Definition color_spaces.ipp:701
constexpr bool is_compatible()
Check whether InColorValuesType is suitable to represent values in COLOR_SPACE.
Definition color_spaces.ipp:563
auto transform_color(const auto &srcColorValues, EColorUsage usage)
Definition color_spaces.ipp:589
EColorUsage
Definition color_enums.h:140
EColorSpace
Definition color_enums.h:7
TTristimulusValues< T > transform_to_linear_sRGB(const auto &srcColorValues, EColorUsage usage)
Helper for converting any color space to linear-sRGB.
Definition color_spaces.ipp:828
auto transform_from_linear_sRGB(const TTristimulusValues< T > &linearSRGB, EColorUsage usage)
Helper for converting from linear-sRGB to any color space.
Definition color_spaces.ipp:814