如何在glsl着色器中模糊透明纹理?

如何在glsl着色器中模糊透明纹理?,glsl,webgl,Glsl,Webgl,我的设置: 乒乓RGBA FBO和两个用于模糊的着色器:水平和垂直着色器。想象一下,我想模糊一个红色矩形 混合功能如下所示: _gl.blendEquationSeparate(_gl.FUNC_ADD, _gl.FUNC_ADD); _gl.blendFuncSeparate(_gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA, _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA); 在我的模糊着色器中,我添加了以下几个片段: vec4 color =

我的设置:

乒乓RGBA FBO和两个用于模糊的着色器:水平和垂直着色器。想象一下,我想模糊一个红色矩形

混合功能如下所示:

_gl.blendEquationSeparate(_gl.FUNC_ADD, _gl.FUNC_ADD);
_gl.blendFuncSeparate(_gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA, _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA);
在我的模糊着色器中,我添加了以下几个片段:

vec4 color = texture2D(u_image, v_tex_coord + vec2(x, y) * u_amount) * weight;
问题:

模糊处理在不透明纹理上效果很好,但当它混合越来越多的透明度时,颜色会变成黑色,就像所有东西都与黑色背景混合一样。我的清晰颜色是
0,0,0,0
,这很有意义

问题:

如何获得真正变成透明红色的模糊效果,而不是随着alpha值变为零,红色与越来越多的黑色混合


我基本上想要的是在Photoshop中在完全透明的背景上模糊某些东西时的效果。我需要预乘FBO还是需要以不同方式处理着色器中片段的混合?

要对透明纹理应用模糊,需要使用alpha进行校正。一个像素有一个简化公式:

resultColor = (sum of pixels of input image) * 1 / K;
通常K是内核大小

如果模糊透明纹理,则需要累积alpha并将其用作K

resultAlpha = (sum of alpha pixels of input image);
resultColor = (sum of pixels of input image) * 1 / resultAlpha;
resultAlpha = resultAlpha * 1 / K;
对于此公式,如果模糊4个像素,其中一个是不透明度,另一个是透明的,则结果像素的颜色将相同,但alpha将小4倍


在我的示例中,所有通道的值都是0到1。

我通过在所有地方使用预乘alpha来解决它

由于习惯了Photoshop的工作原理,我花了一段时间才理解这个概念。这感觉有点违反直觉,但对我帮助很大

现在,我的所有着色器都将RGB值乘以它的A:

gl_FragColor=clr.rgb*alpha

我正在使用一种不同的blendmode来实现这一点:

\u总账合并公式(\u总账功能\u添加);
_总帐blendFunc(_gl.1,_gl.1减去_SRC_ALPHA);

我必须确保我的.PNG图像纹理也是预乘的。我是这样做的:


\u gl.pixelStorei(\u gl.UNPACK\u PREMULTIPLY\u ALPHA\u WEBGL,true)

我确实用错了阿尔法。不过我要回答我自己的问题,因为它涉及到更多的问题。