mitsuba/src/tests/test_spectrum.cpp

147 lines
4.6 KiB
C++

/*
This file is part of Mitsuba, a physically based rendering system.
Copyright (c) 2007-2012 by Wenzel Jakob and others.
Mitsuba is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License Version 3
as published by the Free Software Foundation.
Mitsuba 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <mitsuba/render/testcase.h>
#include <mitsuba/core/bitmap.h>
#include <mitsuba/core/fstream.h>
MTS_NAMESPACE_BEGIN
class TestSpectrum : public TestCase {
public:
MTS_BEGIN_TESTCASE()
MTS_DECLARE_TEST(test01_spectrum)
MTS_DECLARE_TEST(test02_interpolatedSpectrum)
MTS_DECLARE_TEST(test03_blackBody)
MTS_END_TESTCASE()
void test01_spectrum() {
#if SPECTRUM_SAMPLES > 3
Spectrum spec(0.0f);
Float binStart = Spectrum::getBinCoverage(2).first;
Float binEnd = Spectrum::getBinCoverage(2).second;
spec[2] = 1.0f;
assertEquals(spec.eval(binStart+Epsilon), 1.0f);
assertEquals(spec.eval(binEnd-Epsilon), 1.0f);
assertEquals(spec.eval(binStart-Epsilon), 0.0f);
assertEquals(spec.eval(binEnd+Epsilon), 0.0f);
#endif
assertEqualsEpsilon(Spectrum(1.0f).getLuminance(), 1.0f, 1e-5f);
#if SPECTRUM_SAMPLES == 30
/* Verify against the implementation in PBRT */
Spectrum test;
Float r, g, b;
test.fromLinearRGB(0.1f, 0.2f, 0.3f, Spectrum::EReflectance);
test.toLinearRGB(r, g, b);
assertEqualsEpsilon(r, 0.124274f, 1e-5f);
assertEqualsEpsilon(g, 0.190133f, 1e-5f);
assertEqualsEpsilon(b, 0.270029f, 1e-5f);
test.fromLinearRGB(0.1f, 0.2f, 0.3f, Spectrum::EIlluminant);
test.toLinearRGB(r, g, b);
assertEqualsEpsilon(r, 0.0961602f, 1e-5f);
assertEqualsEpsilon(g, 0.184446f, 1e-5f);
assertEqualsEpsilon(b, 0.273519f, 1e-5f);
#elif SPECTRUM_SAMPLES == 3
Spectrum test;
Float x, y, z;
test.fromXYZ(0.1f, 0.2f, 0.3f);
test.toXYZ(x, y, z);
assertEqualsEpsilon(x, 0.1, 1e-5f);
assertEqualsEpsilon(y, 0.2, 1e-5f);
assertEqualsEpsilon(z, 0.3, 1e-5f);
#endif
}
void test02_interpolatedSpectrum() {
/* Test the interpolated spectrum
evaluation and integration routines */
InterpolatedSpectrum spec;
spec.append(500, 1);
spec.append(700, 2);
spec.append(800, 3);
InterpolatedSpectrum spec2 = spec;
assertEquals(spec.eval(499), 0.0f);
assertEquals(spec.eval(500), 1.0f);
assertEquals(spec.eval(600), 1.5f);
assertEquals(spec.eval(700), 2.0f);
assertEquals(spec.eval(750), 2.5f);
assertEquals(spec.eval(800), 3.0f);
assertEquals(spec.eval(801), 0.0f);
assertEqualsEpsilon(spec.average(0, 1000), 550.0f/1000.0f, 1e-6f);
assertEqualsEpsilon(spec.average(550, 551), 1.2525f, 1e-6f);
spec2.zeroExtend();
assertEquals(spec2.eval(500.0f-150.0f), 0.0f);
assertEquals(spec2.eval(500.0f-150.0f/2.0f), 0.5f);
spec2.clear();
spec2.append(0, 1);
spec2.append(1000, 1);
Spectrum spec3;
spec3.fromContinuousSpectrum(spec2);
#if SPECTRUM_SAMPLES > 3
assertEqualsEpsilon(spec3, Spectrum(1.0f), 1e-5f);
#endif
Float x, y, z;
spec3.toXYZ(x, y, z);
assertEqualsEpsilon(x, 1.0f, 1e-3f);
assertEqualsEpsilon(y, 1.0f, 1e-3f);
assertEqualsEpsilon(z, 1.0f, 1e-3f);
#if SPECTRUM_SAMPLES > 3
spec2.clear();
spec2.append(Spectrum::getBinCoverage(0).first, 0);
spec2.append(Spectrum::getBinCoverage(1).first, 1);
spec2.append(Spectrum::getBinCoverage(2).first, 1);
spec2.append(Spectrum::getBinCoverage(2).second, 0);
spec3.fromContinuousSpectrum(spec2);
Spectrum spec4(0.0f);
spec4[0] = 0.5f;
spec4[1] = 1.0f;
spec4[2] = 0.5f;
assertEqualsEpsilon(spec3, spec4, 1e-5f);
#endif
}
void test03_blackBody() {
/* Spot-check a 5000 Kelvin spectrum against values obtained at
https://www.sensiac.org/external/resources/calculators/infrared_radiance_calculator.jsf
Mitsuba uses units of W * m^-2 * sr^-1 * nm^-1, whereas that
page uses W * cm^-2 * sr^-1 * um^-1 --- this is the reason for
the factor of 10-difference.
*/
BlackBodySpectrum spec(5000);
assertEqualsEpsilon(spec.eval(400)/10, 874.f, .5f);
assertEqualsEpsilon(spec.eval(500)/10, 1211.f, .5f);
assertEqualsEpsilon(spec.eval(600)/10, 1276.f, .5f);
assertEqualsEpsilon(spec.eval(2000)/10, 115.8f, .5f);
assertEqualsEpsilon(spec.average(100, 1000) * .09f, 715.f, 1);
}
};
MTS_EXPORT_TESTCASE(TestSpectrum, "Testcase for manipulating spectral data")
MTS_NAMESPACE_END