float Warp::squareToHSWPDF(const Point2f &p, HSWrapper *testWrapper) { float total = testWrapper->m_totalLum; float height = testWrapper->m_lightprob.rows(); float width = testWrapper->m_lightprob.cols(); float fPixH = height * p(1); float fPixW = width * p(0); int y = int(std::min(height - 1.0f ,std::floor(fPixH))); int x = int(std::min(width - 1.0f ,std::floor(fPixW))); int yNext = y + 1; int xNext = x + 1; Color3f Q11 = testWrapper->m_lightprob(y, x); Color3f Q21 = testWrapper->m_lightprob(y, std::min(int(width -1.0f), xNext)); Color3f Q12 = testWrapper->m_lightprob(std::min(int(height -1.0f), yNext), x); Color3f Q22 = testWrapper->m_lightprob(std::min(int(height -1.0f), yNext), std::min(int(width -1.0f), xNext)); float fact1 = ((xNext - fPixW) / (xNext - x)); float fact2 = ((fPixW - x) / (xNext - x)); Color3f R1 = fact1 * Q11 + fact2 * Q21; Color3f R2 = fact1 * Q12 + fact2 * Q22; fact1 = ((yNext - fPixH) / (yNext - y)); fact2 = ((fPixH - y) / (yNext - y)); Color3f result = fact1 * R1 + fact2 * R2; float lum = result.getLuminance(); if (lum < 0) { cout << "Negative luminance detected : " << lum << endl; } float pdf = lum / total; return pdf; }
float Bitmap::getTotalLuminace(){ Color3f totalColor = sum(); float totalLum = totalColor.getLuminance(); return totalLum; }
/// Invoke a series of t-tests on the provided input void activate() { int total = 0, passed = 0; pcg32 random; if (!m_bsdfs.empty()) { if (m_references.size() * m_bsdfs.size() != m_angles.size()) throw NoriException("Specified a different number of angles and reference values!"); if (!m_scenes.empty()) throw NoriException("Cannot test BSDFs and scenes at the same time!"); /* Test each registered BSDF */ int ctr = 0; for (auto bsdf : m_bsdfs) { for (size_t i=0; i<m_references.size(); ++i) { float angle = m_angles[i], reference = m_references[ctr++]; cout << "------------------------------------------------------" << endl; cout << "Testing (angle=" << angle << "): " << bsdf->toString() << endl; ++total; BSDFQueryRecord bRec(sphericalDirection(degToRad(angle), 0)); cout << "Drawing " << m_sampleCount << " samples .. " << endl; double mean=0, variance = 0; for (int k=0; k<m_sampleCount; ++k) { Point2f sample(random.nextFloat(), random.nextFloat()); double result = (double) bsdf->sample(bRec, sample).getLuminance(); /* Numerically robust online variance estimation using an algorithm proposed by Donald Knuth (TAOCP vol.2, 3rd ed., p.232) */ double delta = result - mean; mean += delta / (double) (k+1); variance += delta * (result - mean); } variance /= m_sampleCount - 1; std::pair<bool, std::string> result = hypothesis::students_t_test(mean, variance, reference, m_sampleCount, m_significanceLevel, (int) m_references.size()); if (result.first) ++passed; cout << result.second << endl; } } } else { if (m_references.size() != m_scenes.size()) throw NoriException("Specified a different number of scenes and reference values!"); Sampler *sampler = static_cast<Sampler *>( NoriObjectFactory::createInstance("independent", PropertyList())); int ctr = 0; for (auto scene : m_scenes) { const Integrator *integrator = scene->getIntegrator(); const Camera *camera = scene->getCamera(); float reference = m_references[ctr++]; cout << "------------------------------------------------------" << endl; cout << "Testing scene: " << scene->toString() << endl; ++total; cout << "Generating " << m_sampleCount << " paths.. " << endl; double mean = 0, variance = 0; for (int k=0; k<m_sampleCount; ++k) { /* Sample a ray from the camera */ Ray3f ray; Point2f pixelSample = (sampler->next2D().array() * camera->getOutputSize().cast<float>().array()).matrix(); Color3f value = camera->sampleRay(ray, pixelSample, sampler->next2D()); /* Compute the incident radiance */ value *= integrator->Li(scene, sampler, ray); /* Numerically robust online variance estimation using an algorithm proposed by Donald Knuth (TAOCP vol.2, 3rd ed., p.232) */ double result = (double) value.getLuminance(); double delta = result - mean; mean += delta / (double) (k+1); variance += delta * (result - mean); } variance /= m_sampleCount - 1; std::pair<bool, std::string> result = hypothesis::students_t_test(mean, variance, reference, m_sampleCount, m_significanceLevel, (int) m_references.size()); if (result.first) ++passed; cout << result.second << endl; } } cout << "Passed " << passed << "/" << total << " tests." << endl; }