@@ -130,6 +130,8 @@ extern const RegularSpectrum31f XYZCMFCIE196410Deg[3]; // CIE 1964 10-d
130130extern const RegularSpectrum31f RGBCMFStilesBurch19552Deg[3 ]; // Stiles and Burch (1955) 2-deg
131131extern const RegularSpectrum31f RGBCMFStilesBurch195910Deg[3 ]; // Stiles and Burch (1959) 10-deg (recommended)
132132
133+ // Color matching normalization:
134+ extern const float NORMALIZATIONCIE19312Deg;
133135
134136//
135137// Basis spectra for RGB-to-spectrum conversion.
@@ -171,6 +173,21 @@ class LightingConditions
171173};
172174
173175
176+ //
177+ // SIMID color matching functions.
178+ //
179+
180+ class SIMDColorMatching
181+ {
182+ public:
183+ APPLESEED_SIMD4_ALIGN Color4f m_cmf[32 ];
184+
185+ SIMDColorMatching (const RegularSpectrum31f cmf[3 ]);
186+ };
187+
188+ extern const SIMDColorMatching XYZCMFCIE19312DegSIMD;
189+
190+
174191//
175192// HSV <-> linear RGB transformations.
176193//
@@ -335,10 +352,14 @@ T luminance(const Color<T, 3>& linear_rgb);
335352
336353// Convert a spectrum to a color in the CIE XYZ color space.
337354template <typename T, typename SpectrumType>
338- Color<T, 3 > spectrum_to_ciexyz (
355+ Color<T, 3 > spectrum_reflectance_to_ciexyz (
339356 const LightingConditions& lighting,
340357 const SpectrumType& spectrum);
341358
359+ template <typename T, typename SpectrumType>
360+ Color<T, 3 > spectrum_illuminance_to_ciexyz (const SpectrumType& spectrum);
361+
362+
342363// Convert a spectrum to a color in the CIE XYZ color space using the CIE D65 illuminant
343364// and the CIE 1964 10-deg color matching functions.
344365APPLESEED_DLLSYMBOL void spectrum_to_ciexyz_standard (
@@ -840,13 +861,13 @@ inline T luminance(const Color<T, 3>& linear_rgb)
840861//
841862
842863template <typename T, typename SpectrumType>
843- Color<T, 3 > spectrum_to_ciexyz (
864+ Color<T, 3 > spectrum_reflectance_to_ciexyz (
844865 const LightingConditions& lighting,
845866 const SpectrumType& spectrum)
846867{
847868 static_assert (
848869 SpectrumType::Samples == 31 ,
849- " foundation::spectrum_to_ciexyz () expects 31-channel spectra" );
870+ " foundation::spectrum_reflectance_to_ciexyz () expects 31-channel spectra" );
850871
851872 T x = T (0.0 );
852873 T y = T (0.0 );
@@ -863,10 +884,36 @@ Color<T, 3> spectrum_to_ciexyz(
863884 return Color<T, 3 >(x, y, z);
864885}
865886
887+ template <typename T, typename SpectrumType>
888+ Color<T, 3 > spectrum_illuminance_to_ciexyz (const SpectrumType& spectrum)
889+ {
890+ static_assert (
891+ SpectrumType::Samples == 31 ,
892+ " foundation::spectrum_illuminance_to_ciexyz() expects 31-channel spectra" );
893+
894+ T x = T (0.0 );
895+ T y = T (0.0 );
896+ T z = T (0.0 );
897+
898+ for (size_t w = 0 ; w < 31 ; ++w)
899+ {
900+ const T val = spectrum[w];
901+ x += XYZCMFCIE19312Deg[0 ][w] * val;
902+ y += XYZCMFCIE19312Deg[1 ][w] * val;
903+ z += XYZCMFCIE19312Deg[2 ][w] * val;
904+ }
905+
906+ x *= NORMALIZATIONCIE19312Deg;
907+ y *= NORMALIZATIONCIE19312Deg;
908+ z *= NORMALIZATIONCIE19312Deg;
909+
910+ return Color<T, 3 >(x, y, z);
911+ }
912+
866913#ifdef APPLESEED_USE_SSE
867914
868915template <>
869- inline Color3f spectrum_to_ciexyz <float , RegularSpectrum31f>(
916+ inline Color3f spectrum_reflectance_to_ciexyz <float , RegularSpectrum31f>(
870917 const LightingConditions& lighting,
871918 const RegularSpectrum31f& spectrum)
872919{
@@ -893,6 +940,33 @@ inline Color3f spectrum_to_ciexyz<float, RegularSpectrum31f>(
893940 return Color3f (transfer[0 ], transfer[1 ], transfer[2 ]);
894941}
895942
943+ template <>
944+ inline Color3f spectrum_illuminance_to_ciexyz<float , RegularSpectrum31f>(const RegularSpectrum31f& spectrum)
945+ {
946+ __m128 xyz1 = _mm_setzero_ps ();
947+ __m128 xyz2 = _mm_setzero_ps ();
948+ __m128 xyz3 = _mm_setzero_ps ();
949+ __m128 xyz4 = _mm_setzero_ps ();
950+
951+ for (size_t w = 0 ; w < 8 ; ++w)
952+ {
953+ xyz1 = _mm_add_ps (xyz1, _mm_mul_ps (_mm_set1_ps (spectrum[4 * w + 0 ]), _mm_load_ps (&XYZCMFCIE19312DegSIMD.m_cmf [4 * w + 0 ][0 ])));
954+ xyz2 = _mm_add_ps (xyz2, _mm_mul_ps (_mm_set1_ps (spectrum[4 * w + 1 ]), _mm_load_ps (&XYZCMFCIE19312DegSIMD.m_cmf [4 * w + 1 ][0 ])));
955+ xyz3 = _mm_add_ps (xyz3, _mm_mul_ps (_mm_set1_ps (spectrum[4 * w + 2 ]), _mm_load_ps (&XYZCMFCIE19312DegSIMD.m_cmf [4 * w + 2 ][0 ])));
956+ xyz4 = _mm_add_ps (xyz4, _mm_mul_ps (_mm_set1_ps (spectrum[4 * w + 3 ]), _mm_load_ps (&XYZCMFCIE19312DegSIMD.m_cmf [4 * w + 3 ][0 ])));
957+ }
958+
959+ xyz1 = _mm_add_ps (xyz1, xyz2);
960+ xyz3 = _mm_add_ps (xyz3, xyz4);
961+ xyz1 = _mm_add_ps (xyz1, xyz3);
962+
963+ xyz1 = _mm_mul_ps (xyz1, _mm_set1_ps (NORMALIZATIONCIE19312Deg));
964+
965+ APPLESEED_SIMD4_ALIGN float transfer[4 ];
966+ _mm_store_ps (transfer, xyz1);
967+
968+ return Color3f (transfer[0 ], transfer[1 ], transfer[2 ]);
969+ }
896970#endif // APPLESEED_USE_SSE
897971
898972template <typename T, typename SpectrumType>
@@ -1092,7 +1166,6 @@ void linear_rgb_illuminance_to_spectrum_unclamped(
10921166 const Color<T, 3 >& linear_rgb,
10931167 SpectrumType& spectrum)
10941168{
1095- /* This gives an undesirable blue tint...
10961169 impl::linear_rgb_to_spectrum (
10971170 linear_rgb,
10981171 RGBToSpectrumWhiteIlluminance,
@@ -1102,17 +1175,6 @@ void linear_rgb_illuminance_to_spectrum_unclamped(
11021175 RGBToSpectrumRedIlluminance,
11031176 RGBToSpectrumGreenIlluminance,
11041177 RGBToSpectrumBlueIlluminance,
1105- spectrum); */
1106-
1107- impl::linear_rgb_to_spectrum (
1108- linear_rgb,
1109- RGBToSpectrumWhiteReflectance,
1110- RGBToSpectrumCyanReflectance,
1111- RGBToSpectrumMagentaReflectance,
1112- RGBToSpectrumYellowReflectance,
1113- RGBToSpectrumRedReflectance,
1114- RGBToSpectrumGreenReflectance,
1115- RGBToSpectrumBlueReflectance,
11161178 spectrum);
11171179}
11181180
0 commit comments