vector<Task*> CreateGaussianFitTasks(const SkinCoefficients& coeffs, const vector<float>& sigmas, SpectralGaussianCoeffs& sgc) { WLDValue mfp_min(FLT_MAX), mfp_max(0.f); int nTotalTasks = 0; WLDValue mutp_epi = coeffs.mua_epi() + coeffs.musp_epi(); WLDValue mutp_derm = coeffs.mua_derm() + coeffs.musp_derm(); WLDValue mfp_epi = WLDValue(10) / mutp_epi; WLDValue mfp_derm = WLDValue(10) / mutp_derm; mfp_min = Min(Min(mfp_min, mfp_epi), mfp_derm); mfp_max = Max(Max(mfp_max, mfp_epi), mfp_derm); float minmfp = mfp_min.Min(); float maxmfp = mfp_max.Max(); sgc.sigmas = sigmas; SampledSpectrum mua[2] = { coeffs.mua_epi().toSampledSpectrum() / 10.f, coeffs.mua_derm().toSampledSpectrum() / 10.f }; SampledSpectrum musp[2] = { coeffs.musp_epi().toSampledSpectrum() / 10.f, coeffs.musp_derm().toSampledSpectrum() / 10.f }; float et[2] = { 1.4f, 1.4f }; float thickness[2] = { 0.25f, 20.f }; sgc.coeffs.resize(sigmas.size(), SampledSpectrum(0.f)); vector<Task*> tasks; for (int sc = 0; sc < SampledSpectrum::nComponents; sc++) { tasks.push_back(new GaussianFitTask(mua, musp, et, thickness, sgc, sc, 512)); } return tasks; }
SampledSpectrum ImageSpectrumTexture::evaluate(const SurfacePoint &surfPt, const WavelengthSamples &wls) const { Point3D tc = m_mapping->map(surfPt); float u = std::fmod(tc.x, 1.0f); float v = std::fmod(tc.y, 1.0f); u += u < 0 ? 1.0f : 0.0f; v += v < 0 ? 1.0f : 0.0f; uint32_t px = std::min((uint32_t)(m_data->width() * u), m_data->width() - 1); uint32_t py = std::min((uint32_t)(m_data->height() * v), m_data->height() - 1); SampledSpectrum ret; switch (m_data->format()) { #ifdef Use_Spectral_Representation case ColorFormat::uvs16Fx3: { const uvs16Fx3 &data = m_data->get<uvs16Fx3>(px, py); ret = UpsampledContinuousSpectrum(data.u, data.v, data.s / Upsampling::EqualEnergyReflectance).evaluate(wls); break; } case ColorFormat::uvsA16Fx4: { const uvsA16Fx4 &data = m_data->get<uvsA16Fx4>(px, py); ret = UpsampledContinuousSpectrum(data.u, data.v, data.s / Upsampling::EqualEnergyReflectance).evaluate(wls); break; } case ColorFormat::Gray8: { const Gray8 &data = m_data->get<Gray8>(px, py); ret = SampledSpectrum(data.v / 255.0f); break; } #else case ColorFormat::RGB8x3: { const RGB8x3 &data = m_data->get<RGB8x3>(px, py); ret.r = data.r / 255.0f; ret.g = data.g / 255.0f; ret.b = data.b / 255.0f; break; } case ColorFormat::RGB_8x4: { const RGB_8x4 &data = m_data->get<RGB_8x4>(px, py); ret.r = data.r / 255.0f; ret.g = data.g / 255.0f; ret.b = data.b / 255.0f; break; } case ColorFormat::RGBA8x4: { const RGBA8x4 &data = m_data->get<RGBA8x4>(px, py); ret.r = data.r / 255.0f; ret.g = data.g / 255.0f; ret.b = data.b / 255.0f; break; } case ColorFormat::RGBA16Fx4: { const RGBA16Fx4 &data = m_data->get<RGBA16Fx4>(px, py); ret.r = data.r; ret.g = data.g; ret.b = data.b; break; } case ColorFormat::Gray8: { const Gray8 &data = m_data->get<Gray8>(px, py); ret.r = ret.g = ret.b = data.v / 255.0f; break; } #endif default: SLRAssert(false, "Image data format is unknown."); break; } return ret; }