Photon Engine 2.0.0-beta
A physically based renderer.
Loading...
Searching...
No Matches
chromatic_adaptations.ipp
Go to the documentation of this file.
1#pragma once
2
5
6#include <Common/assertion.h>
7
8namespace ph::math
9{
10
11template<EChromaticAdaptation ALGORITHM>
13{
14 static_assert(ALGORITHM != EChromaticAdaptation::Unspecified);
15
16public:
17 inline static consteval EChromaticAdaptation getAlgorithm() noexcept
18 {
19 return ALGORITHM;
20 }
21};
22
29template<typename T>
31 const TMatrix3<T>& CIEXYZToConeResponse,
32 const TMatrix3<T>& ConeResponseToCIEXYZ,
33 const EReferenceWhite srcRefWhite,
34 const EReferenceWhite dstRefWhite)
35{
36 PH_ASSERT(srcRefWhite != EReferenceWhite::Unspecified);
37 PH_ASSERT(dstRefWhite != EReferenceWhite::Unspecified);
38 PH_ASSERT(srcRefWhite != dstRefWhite);
39
41 CIEXYZToConeResponse,
42 ConeResponseToCIEXYZ,
43 CIEXYZ_of<T>(srcRefWhite),
44 CIEXYZ_of<T>(dstRefWhite));
45}
46
53template<typename T>
55 const TMatrix3<T>& CIEXYZToConeResponse,
56 const TMatrix3<T>& ConeResponseToCIEXYZ,
57 const TTristimulusValues<T>& srcRefWhite,
58 const TTristimulusValues<T>& dstRefWhite)
59{
60 const TTristimulusValues<T> srcConeResponse = CIEXYZToConeResponse.multiplyVector(srcRefWhite);
61 const TTristimulusValues<T> dstConeResponse = CIEXYZToConeResponse.multiplyVector(dstRefWhite);
62
63 PH_ASSERT_NE(srcConeResponse[0], 0);
64 PH_ASSERT_NE(srcConeResponse[1], 0);
65 PH_ASSERT_NE(srcConeResponse[2], 0);
66
67 const TTristimulusValues<T> coneResponseScale = {
68 dstConeResponse[0] / srcConeResponse[0],
69 dstConeResponse[1] / srcConeResponse[1],
70 dstConeResponse[2] / srcConeResponse[2]
71 };
72
73 const auto coneResponseScaleMat = TMatrix3<T>().setScale(coneResponseScale);
74 return ConeResponseToCIEXYZ.mul(coneResponseScaleMat).mul(CIEXYZToConeResponse);
75}
76
79template<typename T>
81 : public TChromaticAdaptationDefinitionHelper<EChromaticAdaptation::XYZScaling>
82{
83public:
85 {
86 return TMatrix3<T>().setIdentity();
87 }
88
90 {
91 return TMatrix3<T>().setIdentity();
92 }
93
95 const TTristimulusValues<T>& CIEXYZColor,
96 const EReferenceWhite srcRefWhite,
97 const EReferenceWhite dstRefWhite)
98 {
99 const auto CATMatrix = create_von_kries_linear_CAT_matrix<T>(
100 getCIEXYZToConeResponse(),
101 getConeResponseToCIEXYZ(),
102 srcRefWhite,
103 dstRefWhite);
104
105 return CATMatrix.multiplyVector(CIEXYZColor);
106 }
107};
108
116template<typename T>
118 : public TChromaticAdaptationDefinitionHelper<EChromaticAdaptation::Bradford>
119{
120public:
122 {
123 return TMatrix3<T>(Matrix3D(
124 0.8951000, 0.2664000, -0.1614000,
125 -0.7502000, 1.7135000, 0.0367000,
126 0.0389000, -0.0685000, 1.0296000));
127 }
128
130 {
131 return TMatrix3<T>(Matrix3D(
132 0.9869929054667121899, -0.14705425642099010066, 0.15996265166373123948,
133 0.43230526972339451002, 0.51836027153677753834, 0.049291228212855612148,
134 -0.0085286645751773312464, 0.040042821654084864313, 0.96848669578754998478));
135 }
136
138 const TTristimulusValues<T>& CIEXYZColor,
139 const EReferenceWhite srcRefWhite,
140 const EReferenceWhite dstRefWhite)
141 {
142 const auto CATMatrix = create_von_kries_linear_CAT_matrix<T>(
143 getCIEXYZToConeResponse(),
144 getConeResponseToCIEXYZ(),
145 srcRefWhite,
146 dstRefWhite);
147
148 return CATMatrix.multiplyVector(CIEXYZColor);
149 }
150};
151
152template<typename T>
154 : public TChromaticAdaptationDefinitionHelper<EChromaticAdaptation::VonKries>
155{
156public:
158 {
159 return TMatrix3<T>(Matrix3D(
160 0.4002400, 0.7076000, -0.0808100,
161 -0.2263000, 1.1653200, 0.0457000,
162 0.0000000, 0.0000000, 0.9182200));
163 }
164
166 {
167 return TMatrix3<T>(Matrix3D(
168 1.8599363874558397422, -1.1293816185800914784, 0.21989740959619327624,
169 0.36119143624176752624, 0.63881246328504213303, -0.0000063705968386570599758,
170 0, 0, 1.0890636230968613186));
171 }
172
174 const TTristimulusValues<T>& CIEXYZColor,
175 const EReferenceWhite srcRefWhite,
176 const EReferenceWhite dstRefWhite)
177 {
178 const auto CATMatrix = create_von_kries_linear_CAT_matrix<T>(
179 getCIEXYZToConeResponse(),
180 getConeResponseToCIEXYZ(),
181 srcRefWhite,
182 dstRefWhite);
183
184 return CATMatrix.multiplyVector(CIEXYZColor);
185 }
186};
187
188// End Chromatic Adaptation Definitions
189
190// Unspecified adaption configuration must not be a valid definition.
191static_assert(!CChromaticAdaptationDefinition<
193
194template<EChromaticAdaptation ALGORITHM, typename T>
196 const TTristimulusValues<T>& srcCIEXYZColor,
197 const EReferenceWhite srcRefWhite,
198 const EReferenceWhite dstRefWhite)
199{
200 using ChromaticAdapter = TChromaticAdaptationDefinition<ALGORITHM, T>;
201
203 "No definition for the specified chromatic adaptation ALGORITHM.");
204
205 return ChromaticAdapter::adapt(srcCIEXYZColor, srcRefWhite, dstRefWhite);
206}
207
208}// end namespace ph::math
Marks the derived class as uninstantiable.
Definition IUninstantiable.h:13
static TMatrix3< T > getCIEXYZToConeResponse()
Definition chromatic_adaptations.ipp:121
static TTristimulusValues< T > adapt(const TTristimulusValues< T > &CIEXYZColor, const EReferenceWhite srcRefWhite, const EReferenceWhite dstRefWhite)
Definition chromatic_adaptations.ipp:137
static TMatrix3< T > getConeResponseToCIEXYZ()
Definition chromatic_adaptations.ipp:129
static TTristimulusValues< T > adapt(const TTristimulusValues< T > &CIEXYZColor, const EReferenceWhite srcRefWhite, const EReferenceWhite dstRefWhite)
Definition chromatic_adaptations.ipp:173
static TMatrix3< T > getConeResponseToCIEXYZ()
Definition chromatic_adaptations.ipp:165
static TMatrix3< T > getCIEXYZToConeResponse()
Definition chromatic_adaptations.ipp:157
static TMatrix3< T > getConeResponseToCIEXYZ()
Definition chromatic_adaptations.ipp:89
static TTristimulusValues< T > adapt(const TTristimulusValues< T > &CIEXYZColor, const EReferenceWhite srcRefWhite, const EReferenceWhite dstRefWhite)
Definition chromatic_adaptations.ipp:94
static TMatrix3< T > getCIEXYZToConeResponse()
Definition chromatic_adaptations.ipp:84
Definition chromatic_adaptations.ipp:13
static consteval EChromaticAdaptation getAlgorithm() noexcept
Definition chromatic_adaptations.ipp:17
Sinkhole for undefined chromatic adaptation routines. Specialize the class to provide definitions for...
Definition chromatic_adaptations.h:28
Represents a 3x3 matrix.
Definition TMatrix3.h:16
TVector3< T > mul(const TVector3< T > &rhsColVector) const
Definition TMatrix3.ipp:68
TRawColVector< T, M > multiplyVector(const TRawColVector< T, M > &rhsColVector) const
Definition TMatrixMxNBase.ipp:57
Derived & setIdentity()
Sets the matrix to be an identity matrix.
Definition TMatrixNBase.ipp:13
Derived & setScale(const TRawColVector< T, N > &scaleFactor)
Definition TMatrixNBase.ipp:27
Definition chromatic_adaptations.h:13
Math functions and utilities.
Definition TransformInfo.h:10
TTristimulusValues< T > CIEXYZ_of(const EReferenceWhite refWhite)
Definition color_basics.h:243
real ColorValue
Definition color_basics.h:42
TTristimulusValues< T > chromatic_adapt(const TTristimulusValues< T > &srcCIEXYZColor, EReferenceWhite srcRefWhite, EReferenceWhite dstRefWhite)
Definition chromatic_adaptations.ipp:195
TMatrix3< T > create_von_kries_linear_CAT_matrix(const TMatrix3< T > &CIEXYZToConeResponse, const TMatrix3< T > &ConeResponseToCIEXYZ, const EReferenceWhite srcRefWhite, const EReferenceWhite dstRefWhite)
Definition chromatic_adaptations.ipp:30
TMatrix3< float64 > Matrix3D
Definition math_fwd.h:72
TRawColorValues< T, 3 > TTristimulusValues
Definition color_basics.h:48
EReferenceWhite
Definition color_enums.h:49
EChromaticAdaptation
Methods to map image appearance between different illumination sources. This kind of mapping is commo...
Definition color_enums.h:114