【发布时间】:2017-09-15 19:20:03
【问题描述】:
我想要模糊一个对象。
- 将其渲染为透明 (glClear with 1, 1, 1, 0) FBO。
- 使用垂直模糊着色器将其渲染到第二个透明 FBO。
- 使用水平模糊着色器将其渲染到屏幕上。
这是一个看起来没有模糊,然后用这种技术模糊的例子:
显然问题在于模糊对象周围的白光。
我想我掌握了为什么会发生这种情况的基本概念。虽然 FBO 中对象周围的像素是透明的,但它们仍然保持颜色 (1,1,1),因此,该颜色混合到模糊中。
我只是不知道该怎么做才能解决这个问题?
这是我的水平模糊着色器,垂直方向大致相同:
hBlur.vert
uniform mat4 u_projTrans;
uniform float u_blurPixels;
uniform float u_texelWidth;
attribute vec4 a_position;
attribute vec2 a_texCoord0;
attribute vec4 a_color;
varying vec2 v_texCoord;
varying vec2 v_blurTexCoords[14];
void main()
{
v_texCoord = a_texCoord0;
gl_Position = u_projTrans * a_position;
float blurDistance6 = u_blurPixels * u_texelWidth;
float blurDistance5 = blurDistance6 * 0.84;
float blurDistance4 = blurDistance6 * 0.70;
float blurDistance3 = blurDistance6 * 0.56;
float blurDistance2 = blurDistance6 * 0.42;
float blurDistance1 = blurDistance6 * 0.28;
float blurDistance0 = blurDistance6 * 0.14;
v_blurTexCoords[ 0] = v_texCoord + vec2(-blurDistance6, 0.0);
v_blurTexCoords[ 1] = v_texCoord + vec2(-blurDistance5, 0.0);
v_blurTexCoords[ 2] = v_texCoord + vec2(-blurDistance4, 0.0);
v_blurTexCoords[ 3] = v_texCoord + vec2(-blurDistance3, 0.0);
v_blurTexCoords[ 4] = v_texCoord + vec2(-blurDistance2, 0.0);
v_blurTexCoords[ 5] = v_texCoord + vec2(-blurDistance1, 0.0);
v_blurTexCoords[ 6] = v_texCoord + vec2(-blurDistance0, 0.0);
v_blurTexCoords[ 7] = v_texCoord + vec2( blurDistance0, 0.0);
v_blurTexCoords[ 8] = v_texCoord + vec2( blurDistance1, 0.0);
v_blurTexCoords[ 9] = v_texCoord + vec2( blurDistance2, 0.0);
v_blurTexCoords[10] = v_texCoord + vec2( blurDistance3, 0.0);
v_blurTexCoords[11] = v_texCoord + vec2( blurDistance4, 0.0);
v_blurTexCoords[12] = v_texCoord + vec2( blurDistance5, 0.0);
v_blurTexCoords[13] = v_texCoord + vec2( blurDistance6, 0.0);
}
blur.frag
uniform sampler2D u_texture;
varying vec2 v_texCoord;
varying vec2 v_blurTexCoords[14];
void main()
{
gl_FragColor = vec4(0.0);
gl_FragColor += texture2D(u_texture, v_blurTexCoords[ 0]) * 0.0044299121055113265;
gl_FragColor += texture2D(u_texture, v_blurTexCoords[ 1]) * 0.00895781211794;
gl_FragColor += texture2D(u_texture, v_blurTexCoords[ 2]) * 0.0215963866053;
gl_FragColor += texture2D(u_texture, v_blurTexCoords[ 3]) * 0.0443683338718;
gl_FragColor += texture2D(u_texture, v_blurTexCoords[ 4]) * 0.0776744219933;
gl_FragColor += texture2D(u_texture, v_blurTexCoords[ 5]) * 0.115876621105;
gl_FragColor += texture2D(u_texture, v_blurTexCoords[ 6]) * 0.147308056121;
gl_FragColor += texture2D(u_texture, v_texCoord ) * 0.159576912161;
gl_FragColor += texture2D(u_texture, v_blurTexCoords[ 7]) * 0.147308056121;
gl_FragColor += texture2D(u_texture, v_blurTexCoords[ 8]) * 0.115876621105;
gl_FragColor += texture2D(u_texture, v_blurTexCoords[ 9]) * 0.0776744219933;
gl_FragColor += texture2D(u_texture, v_blurTexCoords[10]) * 0.0443683338718;
gl_FragColor += texture2D(u_texture, v_blurTexCoords[11]) * 0.0215963866053;
gl_FragColor += texture2D(u_texture, v_blurTexCoords[12]) * 0.00895781211794;
gl_FragColor += texture2D(u_texture, v_blurTexCoords[13]) * 0.0044299121055113265;
}
如果我说我完全确定这段代码在做什么,那我就是在撒谎。但总而言之,它只是从u_blurPixels 的半径内采样像素,并使用预先确定的高斯权重对gl_FragColor 的结果颜色求和。
如何修改它以防止由于透明背景而产生的白光?
【问题讨论】:
-
是的,这是一个预乘 alpha 问题。至少这是我从其他有类似问题的人那里读到的。