我目前使用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);
有什么想法可能出了什么问题吗?
我想通了。
似乎"_offsets"必须与内核的大小相同。造成这种情况的主要原因是偏移量的中心位置必须与内核的中心位置位于同一位置。如果不这样做,那么高斯将无法与纹理正确对齐。
一种方法是使"_offsets"与内核的大小相同。
几天来我一直在寻找这个解决方案-_-'