如何使用opengl在帧缓冲区中正确卷积非二次幂图像

时间:2017-04-11 04:17:00

标签: opengl glsl blur convolution framebuffer

我有一个800x600的窗口,我想对渲染图像应用一些卷积(即高斯模糊)。

首先,我将场景渲染为1024x1024 float16纹理,其中包含800x600视口和剪刀框。因此,视口外的区域包含垃圾,它在我的机器上看起来像随机颜色。当我使用像这样的片段着色器将此纹理渲染到窗口时:

uniform sampler2D tex;
out vec4 outFragColor;
smooth in vec2 texCoord;
const float weight[5] = float[] (0.227027, 0.1945946, 0.1216216, 0.054054, 0.016216);

void main()
{
    vec3 color = texture(tex, texCoord).rgb * weight[0];
    vec2 texOffset = 1.0f / textureSize(tex, 0);
    for (int i = 1; i < 5; ++i) {
        color += texture(tex, texCoord + vec2(texOffset.x * i, 0.0f)).rgb * weight[i];
        color += texture(tex, texCoord - vec2(texOffset.x * i, 0.0f)).rgb * weight[i];
    }
    outFragColor = vec4(color, 1.0f);
}

我显然在视口新窗口边界外采样并将垃圾混合到最终图像中。例如,在这里我们看到顶部的随机值和右边的零值:

enter image description here

我考虑过哪些解决方案:

1)使用纹理大小的视口渲染并仅显示子图像。一个坏主意,因为片段着色器会做很多无用的工作。

2)使用稍大的视口,即810x610。看起来像一个疯狂的黑客。

3)使用非幂二纹理扩展。据我所知,他们有一个微妙的性能损失,更糟糕的是,他们缺乏适当的驱动程序支持,可能是特定于供应商。特别是关于float16纹理(对项目至关重要)和WebGL。

那么在没有在视口外采样的情况下,将帧缓冲图像与内核进行卷积的最佳方法是什么?

0 个答案:

没有答案