【问题标题】:Opengl - Gaussian blur displaced / disalignment issueOpengl - 高斯模糊位移/错位问题
【发布时间】:2013-01-14 20:46:39
【问题描述】:

我目前使用 C++ 在 Opengl 中实现了一个高斯模糊着色器。高斯模糊有效。然而,与原始图像相比,结果似乎有点偏移。生成的模糊图像似乎放置在更高的位置,而在左侧放置了一些。并且与原版不在同一个地方。

我使用的高斯模糊是两遍计算。 我基于我在网上找到的演示代码进行了高斯计算。

高斯核计算如下:

    for(i = 0; i <= center; ++i)
    {
        result            = exp(-(i*i)/(double)(2*_sigma*_sigma));
        _kernel[center+i]  = _kernel[center-i] = (float)result;
        sum              += (float)result;
        if(i != 0) sum   += (float)result;

    }

    // normalize kernel
    for(i = 0; i <= center; ++i)
    {
        _kernel[center+i] = _kernel[center-i] /= sum;
    }

偏移量计算如下:

_offsets        = new float [_kernelSize * 2 + 1];
_offsetSize     = _kernelSize * 2 + 1;

float xInc      = 0;

if(_shaderType == S2DGaussianComponentBlurShaderHorizontal)
{
    xInc        = 1.0f / (float)_width;
}
else
{
    xInc        = 1.0f / (float)_height;
}

int   index     = 0;
for (int i = -_kernelSize; i < _kernelSize + 1; ++i)
{
    index            = i + _kernelSize;
    _offsets [index] = i * xInc;
}

片段着色器如下所示:

#version 120   \n                               \
uniform sampler2D texture;                      \
varying vec4 texcoord;                          \
                                                \
                                                \
uniform int kernelSize;                         \
uniform float weight[50];                       \
uniform float offsets[50];                      \
void main(void)                                 \
{                                               \
vec2 uv  = texcoord.xy;                         \
vec4 sum = vec4(0.0);                           \
for (int i = 0; i< kernelSize; i++)             \
{                                               \
vec4 tmp       = texture2D( texture,  uv + vec2(0.0, offsets[i]) ); \
sum           += tmp * weight[i];               \
}                                               \
                                                \
gl_FragColor = sum;                             \
}"

纹理输入正在使用这些:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);

有什么想法可能是错的吗?

【问题讨论】:

  • 内核/着色器代码看起来不错。问题可能出在您应用它的方式上 - 例如顶点着色器或顶点位置/纹理坐标。
  • @kerim 我想通了,请查看下面的答案:)

标签: c++ opengl shader blur gaussian


【解决方案1】:

我想通了。

'_offsets' 似乎必须与内核大小相同。主要原因是偏移的中心位置必须与内核的中心位置相同。如果你不这样做,那么高斯将无法与纹理正确对齐。

这样做的一种方法是使“_offsets”的大小与内核相同。

我这几天一直在寻找这个解决方案-_-'

【讨论】:

  • 很高兴你知道了!那么您原始代码中的_kernelSize_kernel 数组的大小? center 类似于 _kernelSize/2?
  • @kerim 是的,出了问题的是'_offsetSize = _kernelSize * 2 + 1;'这应该是 _offsetSize = kernelSize。如果 offsetSize 太大,offset 数组会比 kernel 数组大,造成奇怪的偏移。
猜你喜欢
  • 2016-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-30
  • 2021-06-25
  • 2018-05-01
  • 1970-01-01
相关资源
最近更新 更多