Glsl 基于可变权重的线性高斯模糊偏移量计算

Glsl 基于可变权重的线性高斯模糊偏移量计算,glsl,blur,gaussian,sampling,Glsl,Blur,Gaussian,Sampling,我最近一直在研究通过使用线性采样方法而不是离散方法来优化高斯模糊着色器 我读了一篇内容丰富的文章: 在两个texel合并的情况下,我们必须调整坐标,使确定的坐标与texel#1中心的距离等于texel#2的权重除以两个权重之和。在同一样式中,确定的坐标与texel#2中心的距离应等于texel#1的权重除以两个权重之和 虽然我理解这背后的逻辑,但我不确定他们是如何得出给定权重的偏移量的数字的。有没有人能帮我解释一下,在均匀权重变量的情况下,我们如何计算正确的偏移量 关于非硬编码偏移量,我发现另

我最近一直在研究通过使用线性采样方法而不是离散方法来优化高斯模糊着色器

我读了一篇内容丰富的文章:

在两个texel合并的情况下,我们必须调整坐标,使确定的坐标与texel#1中心的距离等于texel#2的权重除以两个权重之和。在同一样式中,确定的坐标与texel#2中心的距离应等于texel#1的权重除以两个权重之和

虽然我理解这背后的逻辑,但我不确定他们是如何得出给定权重的偏移量的数字的。有没有人能帮我解释一下,在均匀权重变量的情况下,我们如何计算正确的偏移量

关于非硬编码偏移量,我发现另一篇文章推荐了一种计算偏移量的方法,但是没有针对可变数量的样本发布解决方案。我怎样才能做到这一点

vec2 offsets[3];
offsets[0] = vec2(0.0, 0.0);

offsets[1] = vec2(dFdx(gl_TexCoord[0].s), dFdy(gl_TexCoord[0].t));

offsets[2] = offsets[1] + offsets[1];

我刚刚看到同一篇文章,发现它也非常有用。其中给出了计算权重和偏移的公式:


(来源:)

作者使用帕斯卡三角形中的第12行来计算权重。例如,第二个偏移量通过以下公式计算:

1.3846153846 = (1 * 792 + 2 * 495) / (792 + 495)
0.1945945946 = (792 + 495) / 4070
第二个权重通过以下公式计算:

1.3846153846 = (1 * 792 + 2 * 495) / (792 + 495)
0.1945945946 = (792 + 495) / 4070

我不确定你给出的是用统一的重量变量计算偏移量的意思,但是如果它有帮助的话,我在这个帖子的结尾包含了一个C++程序,它输出了Pascal三角形中任意行的偏移和权重。 如果我理解您关于非硬编码偏移的问题,那么您希望能够在GLSL中动态计算偏移吗?您可以通过移植下面的程序来实现这一点,但是您仍然需要硬编码二项式系数,或者动态计算这些系数。然而,这将是昂贵的,因为它将不得不做每一个像素。我认为一个更好的替代方法是用C(或您正在使用的任何编程语言)预先计算偏移量和权重,然后将它们绑定到GLSL中的统一数组值。下面是GLSL片段,我的意思是:

    uniform float offset[5];
    uniform float weight[5];"
    uniform int numOffsets;
您需要将“5”替换为计划使用的最大偏移/权重数,并将numofsets设置为用于特定操作的数字

这是输出权重和偏移的程序。“coeff”应替换为pascal表中所需行的二项式系数。这里包括的是第22排的

#include <iostream>
#include <vector>

using namespace std;

int main(int argc, char* argv[])
{
  float coeffs[] = { 705432, 646646, 497420, 319770, 170544, 74613, 26334, 7315, 1540, 231 };
  double total = coeffs[0];
  for (int i = 1; i < sizeof(coeffs) / sizeof(float); i++)
    {
      total += 2 * coeffs[i];
    }
  vector<float> offsets;
  vector<float> weights;

  offsets.push_back(0);
  weights.push_back(coeffs[0] / total);

  for (int i = 1;  i <= (sizeof(coeffs) / sizeof(float) - 1) / 2; i++) 
    {
      int index = (i - 1) * 2 + 1;
      float weight = coeffs[index] + coeffs[index + 1]; 
      offsets.push_back((coeffs[index] * index + coeffs[index + 1] * (index + 1)) /  weight);
      weights.push_back(weight / total);
    }

  for (int i = 0; i < offsets.size(); i++)
    {
      cout << offsets[i] << ", ";
    }
  cout << "\n";

  for (int i = 0; i < weights.size(); i++)
    {
      cout << weights[i] << ", ";
    }
  cout << "\n";
}
#包括
#包括
使用名称空间std;
int main(int argc,char*argv[])
{
浮动系数[]={705432、646646、497420、319770、170544、74613、26334、7315、1540、231};
双倍总计=系数[0];
对于(int i=1;i对于(int i=1;我感谢Steve解决了我最初的困惑。请问您为什么选择第22行?我使用第22行来试验19抽头过滤器。本文将第12行用于9抽头过滤器。一般来说,对于N抽头过滤器,您希望使用(N+3)第四行。我只是想补充一点,我不确定一般的经验法则是否是使用第N+3行,但是如果你想像文章建议的那样忽略边缘系数,那么这就是应该遵循的方法。这似乎是一个很好的经验法则。我比较了两者之间的差异,非常值得减少这些额外的迭代。我也觉得这是有益的为了在FBO之间使用第22行而不是“乒乓球”,对于阅读本文的人,我最终计算出了我的权重值,如:exp(-(ii)/(2*sigmasigma))/(sqrt(2*constants::pi)*sigma);