void AbstractOnGpuComparator::filter(Rendering::RenderingContext & context, TexRef_t src, TexRef_t dst) { if (!filterValid) { shaderFilterH->setUniform(context, Uniform("filterSize", filterSize)); shaderFilterV->setUniform(context, Uniform("filterSize", filterSize)); // std::cerr << getTypeName() << " Filter: " << (filterType == GAUSS ? "Gauss" : "Box") << " (" << filterSize << ") : " << "["; std::vector<float> values; if (filterType == GAUSS) { // old formula was filterSize * 1.5, which was too big. // older value used for some measurements in 2013's papers: 0.3 const double sigma = 0.3 * (filterSize - 1) + 0.8; // sqrtOfTwoTimesPi = std::sqrt(2.0 * pi) const double sqrtOfTwoTimesPi = 2.506628274631000502415765284811045253006986740609938316629923; const double a = 1.0 / (sigma * sqrtOfTwoTimesPi); double sum = 0.0; for (int i = 0; i <= filterSize; i++) { const double v = a * std::exp(-((i * i) / (2.0 * sigma * sigma))); values.push_back(v); sum += (i == 0 ? v : 2 * v); } for (int i = 0; i <= filterSize; i++) { values[i] /= sum; } } else if (filterType == BOX) { for (int i = 0; i <= filterSize; i++) { float v = 1.0f / (filterSize * 2.0f + 1.0f); values.push_back(v); } } else WARN("the roof is on fire"); // for(const auto & x : values) // std::cerr << x << " "; // std::cerr << "\b]" << std::endl; while (values.size() < 16) values.push_back(0.0f); shaderFilterH->setUniform(context, Uniform("filterValues", values)); shaderFilterV->setUniform(context, Uniform("filterValues", values)); filterValid = true; } Reference<TexRef> tmp = new TexRef(Vec2i(src->get()->getWidth(), src->get()->getHeight())); context.pushAndSetShader(shaderFilterH.get()); context.pushAndSetTexture(0, src->get()); fbo->attachColorTexture(context, tmp->get()); Rendering::drawFullScreenRect(context); context.setShader(shaderFilterV.get()); context.setTexture(0, tmp->get()); fbo->attachColorTexture(context, dst.isNull() ? src->get() : dst->get()); Rendering::drawFullScreenRect(context); fbo->detachColorTexture(context); context.popTexture(0); context.popShader(); }