pbrt-v3 icon indicating copy to clipboard operation
pbrt-v3 copied to clipboard

Failed to load .spd files with between (300 and 800 nm)

Open marwan-abdellah opened this issue 8 years ago • 0 comments

The default implementation of the AddSampledSpectrumFiles assumes that all the loaded .spd files match with the hard-coded parameters in the spectrum.h file that ranges, by default, between 300 and 700 nm. So, if the given .spd file contains a different range, then the obtained spectrum is no more valid.

I have tried to go for a quick solution that checks the range of the given wavelengths in the .spd file and those in the spectrum.h file and get the right mapping between them.

In paramset.cpp

void ParamSet::AddSampledSpectrumFiles(const std::string &name,
                                       const char **names, int nValues) {
    EraseSpectrum(name);
    std::unique_ptr<Spectrum[]> s(new Spectrum[nValues]);
    for (int i = 0; i < nValues; ++i) {
        std::string fn = AbsolutePath(ResolveFilename(names[i]));
        if (cachedSpectra.find(fn) != cachedSpectra.end()) {
            s[i] = cachedSpectra[fn];
            continue;
        }
        std::vector<Float> vals;
        if (!ReadFloatFile(fn.c_str(), &vals)) {
            Warning(
                "Unable to read SPD file \"%s\".  Using black distribution.",
                fn.c_str());
            s[i] = Spectrum(0.);
        } else {
            if (vals.size() % 2) {
                Warning(
                    "Extra value found in spectrum file \"%s\". "
                    "Ignoring it.",
                    fn.c_str());
            }
            std::vector<Float> wls, v;
            float wlsValues[nSpectralSamples];
            float vValues[nSpectralSamples];
            for (int j = 0; j < nSpectralSamples; ++j) {
                wlsValues[j] = sampledLambdaStart + j;
                vValues[j] = 0.f;
            }
            for (size_t j = 0; j < vals.size() / 2; ++j) {
                const float lambda = vals[2 * j];
                const float spd = vals[2 * j + 1];
                float lambdaIndex;
                if (lambda >= sampledLambdaStart && lambda <= sampledLambdaEnd) {
                    lambdaIndex = lambda - sampledLambdaStart;
                    wlsValues[int(lambdaIndex)] = lambda;
                    vValues[int(lambdaIndex)] = spd;
                }
            }
            for (int j = 0; j < nSpectralSamples; ++j) {
                wls.push_back(wlsValues[j]);
                v.push_back(vValues[j]);
            }
            s[i] = Spectrum::FromSampled(&wls[0], &v[0], wls.size());
        }
        cachedSpectra[fn] = s[i];
    }

    std::shared_ptr<ParamSetItem<Spectrum>> psi(
        new ParamSetItem<Spectrum>(name, std::move(s), nValues));
    spectra.push_back(psi);
}

HTH

marwan-abdellah avatar Jan 15 '16 17:01 marwan-abdellah