C++ 线性采样高斯模糊质量问题

C++ 线性采样高斯模糊质量问题,c++,glsl,shader,blur,aliasing,C++,Glsl,Shader,Blur,Aliasing,我最近根据本文实现了一个线性采样高斯模糊: 它通常表现得很好,但似乎在文本和较薄的像素集合上有轻微的边缘化。我很困惑到底是什么导致了这种情况,这是我的着色器或权重计算的问题,还是使用这种方法的继承回退 我想补充一点,当我定期采样每个像素而不是使用双线性滤波时,我不会遇到这个问题 非常感谢您的任何见解。以下是我如何计算体重的代码示例: int support = int(sigma * 3.0f); float total = 0.0f; weights.push_back(exp(-(0*

我最近根据本文实现了一个线性采样高斯模糊:

它通常表现得很好,但似乎在文本和较薄的像素集合上有轻微的边缘化。我很困惑到底是什么导致了这种情况,这是我的着色器或权重计算的问题,还是使用这种方法的继承回退

我想补充一点,当我定期采样每个像素而不是使用双线性滤波时,我不会遇到这个问题

非常感谢您的任何见解。以下是我如何计算体重的代码示例:

int support = int(sigma * 3.0f);

float total = 0.0f;

weights.push_back(exp(-(0*0)/(2*sigma*sigma))/(sqrt(2*constants::pi)*sigma));
total += weights.back();

offsets.push_back(0);

for (int i = 1; i <= support; i++)
{
  float w1 = exp(-(i*i)/(2*sigma*sigma))/(sqrt(2*constants::pi)*sigma);
  float w2 = exp(-((i+1)*(i+1))/(2*sigma*sigma))/(sqrt(2*constants::pi)*sigma);

  weights.push_back(w1 + w2);
  total += 2.0f * weights[i];

  offsets.push_back((i * w1 + (i + 1) * w2) / weights[i]);
}

for (int i = 0; i < support; i++)
{
  weights[i] /= total;
}
int支持=int(sigma*3.0f);
总浮点数=0.0f;
重量。推回(exp(-(0*0)/(2*西格玛*西格玛))/(sqrt(2*常数::π)*西格玛));
总计+=重量。返回();
偏移量。推回(0);

对于(int i=1;i这在我看来像是一个正确的高斯模糊。文本被破坏的程度取决于你的
sigma
。你使用的是什么值

此外,我还将检查您使用的投影的缩放矩阵

如果想要模糊但不影响文本和细像素线,可以考虑

  • 将结果与温和高通滤波器的输出合成
  • 使用较小的
    sigma
  • 更改内核的形状,使其不是高斯的:您可以尝试具有更高多余峰度的函数,而不是
    exp(-i*i/s*s)
    。您可以尝试线性向上/向下函数,或者改用此页面上列出的函数之一:。它们都会导致模糊,并对细节造成不同程度的干扰

这是双线性滤波的固有问题。这是不可避免的。

我以前实现过高斯滤波器,当我尝试使用浮动偏移时,也有这些伪影。当我使用整数偏移时(我指的是纹理的中心)它看起来更平滑,似乎是一个过滤问题。我观察到了类似的结果。当我使用双西格玛在每个像素的中心采样一次时,我得到了一个更平滑的结果。你可以应用高斯滤波器几次以获得更高的模糊度,同时使用像素中心来获得平滑和高度模糊的结果。如果结果达到dark、 你可以将过程加在一起。使用此方法的目的是将采样计数减半。我已经有了一个模糊,看起来很好,我想优化我已经正确工作的部分。
 void main()
 {
  vec3 acc = texture2D(tex_object, v_tex_coord.st).rgb*weights[0];
  for (int i = 1; i < NUM_SAMPLES; i++)
  {
    acc += texture2D(tex_object, (v_tex_coord.st+(vec2(offsets[i], 0.0)/tex_size))).rgb*weights[i];
    acc += texture2D(tex_object, (v_tex_coord.st-(vec2(offsets[i], 0.0)/tex_size))).rgb*weights[i];
  }
  gl_FragColor = vec4(acc, 1.0);