147 lines
4.6 KiB
C++
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
|