OpenGL GLSL 边缘溢出效果

OpenGL GLSL bloom effect bleeds on edges

我有一个名为 "FBScene" 的帧缓冲区,它渲染到纹理 TexScene。 我有一个名为 "FBBloom" 的帧缓冲区,它渲染到纹理 TexBloom。 我有一个名为 "FBBloomTemp" 的帧缓冲区,它渲染到纹理 TexBloomTemp。

首先,我将所有盛开/发光的对象渲染到 FBBloom,从而渲染到 TexBloom。然后我用 FBBloom 和 FBBloomTemp 玩乒乓球,交替水平/垂直模糊以获得漂亮的绽放纹理。

然后我将最终的 "TexBloom" 纹理和 TexScene 传递给屏幕着色器,该着色器使用两种纹理绘制屏幕填充四边形:

gl_FragColor = 纹理(TexBloom, uv) + 纹理(TexScene, uv);

问题是: 在模糊图像时,如果发光物体离屏幕边界太近,光晕效果会渗入屏幕的相对边缘。

这是我的模糊着色器:

vec4 color = vec4(0.0);
vec2 off1 = vec2(1.3333333333333333) * direction;
vec2 off1DivideByResolution =  off1 / resolution;
vec2 uvPlusOff1  = uv + off1DivideByResolution;
vec2 uvMinusOff1 = uv - off1DivideByResolution;


color += texture(image, uv) * 0.29411764705882354;
color += texture(image, uvPlusOff1) * 0.35294117647058826;
color += texture(image, uvMinusOff1) * 0.35294117647058826;
gl_FragColor = color;

我想我需要防止 uvPlusOff1 和 uvMinusOff1 超出 -1 和 +1 紫外线范围。但是我不知道该怎么做。

我试图在上面的代码中将 uv 值限制在间隙处:

float px = clamp(uvPlusOff1.x, -1, 1);
float py = clamp(uvPlusOff1.y, -1, 1);
float mx = clamp(uvMinusOff1.x, -1, 1);
float my = clamp(uvMinusOff1.y, -1, 1);

uvPlusOff1 = vec2(px, py);
uvMinusOff1 = vec2(mx, my);

但它没有按预期工作。非常感谢任何帮助。

当 wrap-mode 设置为 GL_REPEAT 时,通常会出现向屏幕另一边溢出的情况。将其设置为 GL_CLAMP_TO_EDGE,这样就不会再发生了。

编辑 - 进一步解释为什么会发生这种情况:[1,1] 的纹理坐标表示右下纹素的右下角。启用线性过滤后,此位置将读取该角周围的四个像素。在重复纹理的情况下,其中三个位于屏幕的另一侧。如果你想手动防止这个问题,你必须限制在 [0 + 1/texture_size, 1 - 1/texture_size].

范围内

我也不确定为什么你甚至限制到 [-1, 1],因为纹理坐标通常在 [0, 1] 范围内。负值将在纹理之外并由环绕模式处理。