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();
}