我尝试制作一个平滑的高斯模糊,但我不知道如何做到这一点。
我尝试过这样的事情:
#version 100
precision mediump float;
varying vec3 vColor;
varying vec2 TexCoords;
uniform sampler2D texture0;
uniform float radius;
uniform vec2 dir;
uniform resolution;
void main() {
vec4 sum = vec4(0.0);
vec2 tc = TexCoords;
float blur = radius/resolution;
float hstep = dir.x;
float vstep = dir.y;
sum += texture2D(texture0, vec2(tc.x - 4.0*blur*hstep, tc.y - 4.0*blur*vstep)) * 0.0162162162;
sum += texture2D(texture0, vec2(tc.x - 3.0*blur*hstep, tc.y - 3.0*blur*vstep)) * 0.0540540541;
sum += texture2D(texture0, vec2(tc.x - 2.0*blur*hstep, tc.y - 2.0*blur*vstep)) * 0.1216216216;
sum += texture2D(texture0, vec2(tc.x - 1.0*blur*hstep, tc.y - 1.0*blur*vstep)) * 0.1945945946;
sum += texture2D(texture0, vec2(tc.x, tc.y)) * 0.2270270270;
sum += texture2D(texture0, vec2(tc.x + 1.0*blur*hstep, tc.y + 1.0*blur*vstep)) * 0.1945945946;
sum += texture2D(texture0, vec2(tc.x + 2.0*blur*hstep, tc.y + 2.0*blur*vstep)) * 0.1216216216;
sum += texture2D(texture0, vec2(tc.x + 3.0*blur*hstep, tc.y + 3.0*blur*vstep)) * 0.0540540541;
sum += texture2D(texture0, vec2(tc.x + 4.0*blur*hstep, tc.y + 4.0*blur*vstep)) * 0.0162162162;
gl_FragColor = vec4(vColor, 1.0) * vec4(sum.rgb, 1.0);
}
但结果是这样的: http://i.imgur.com/N6ks3Pw.png
如何才能取得更好的成绩呢?
答案 0 :(得分:1)
您似乎是正确的方式,但您的vstep
和hstep
似乎太大了。应该设计一个步骤,以便只取一个下一个像素,这意味着它应该是1/size
,其大小等于你的情况下的纹理大小。
你只需要几个像素就可以产生很多模糊效果。通常你至少会采用7x7或9x9矩阵。你正在采取的是有点奇怪,因为这看起来你只使用当前像素周围的一些对角线值。
在概念上,结果应该类似于
for(horizontalOffset = -radius; horizontalOffset<radius; horizontalOffset += step) {
for(verticalOffset = -radius; verticalOffset<radius; verticalOffset += step) {
sum += texture2D(texture, textureCoordinate+vec2(horizontalOffset, verticalOffset))*gaussFactorForOffset(sqrt(horizontalOffset*horizontalOffset + verticalOffset*verticalOffset)/radius);
}
}
这有点慢,但因为例如有7个步骤将对纹理产生49次访问,这使得它成为o2。您可以通过将其拆分为2个绘制调用来优化它,其中一个创建垂直模糊,另一个创建水平模糊。这意味着您需要2个着色器,其中一个仅采用垂直循环,另一个仅采用水平循环。结果是你有14个调用7个步骤的纹理,这样就可以在另外一个绘制调用和内存中有另一个纹理的情况下生成2o(除非你可以重复使用原来的第二个绘制调用)。
您也可以在this one等页面上在线找到大量着色器。它们通常没有经过优化,但它们至少可以为您提供一个起点。