【发布时间】:2012-09-18 03:27:17
【问题描述】:
我正在尝试在 OpenGL ES2.0 for iOS 中实现 2D 轮廓着色器。它非常缓慢。就像 5fps 慢一样。我已经追踪到 texture2D() 调用。然而,没有这些,任何卷积着色器都是不可撤销的。我试过用lowp代替mediump,但一切都是黑色的,虽然它确实给了另外5fps,但它仍然无法使用。
这是我的片段着色器。
varying mediump vec4 colorVarying;
varying mediump vec2 texCoord;
uniform bool enableTexture;
uniform sampler2D texture;
uniform mediump float k;
void main() {
const mediump float step_w = 3.0/128.0;
const mediump float step_h = 3.0/128.0;
const mediump vec4 b = vec4(0.0, 0.0, 0.0, 1.0);
const mediump vec4 one = vec4(1.0, 1.0, 1.0, 1.0);
mediump vec2 offset[9];
mediump float kernel[9];
offset[0] = vec2(-step_w, step_h);
offset[1] = vec2(-step_w, 0.0);
offset[2] = vec2(-step_w, -step_h);
offset[3] = vec2(0.0, step_h);
offset[4] = vec2(0.0, 0.0);
offset[5] = vec2(0.0, -step_h);
offset[6] = vec2(step_w, step_h);
offset[7] = vec2(step_w, 0.0);
offset[8] = vec2(step_w, -step_h);
kernel[0] = kernel[2] = kernel[6] = kernel[8] = 1.0/k;
kernel[1] = kernel[3] = kernel[5] = kernel[7] = 2.0/k;
kernel[4] = -16.0/k;
if (enableTexture) {
mediump vec4 sum = vec4(0.0);
for (int i=0;i<9;i++) {
mediump vec4 tmp = texture2D(texture, texCoord + offset[i]);
sum += tmp * kernel[i];
}
gl_FragColor = (sum * b) + ((one-sum) * texture2D(texture, texCoord));
} else {
gl_FragColor = colorVarying;
}
}
这是未优化的,也未最终确定,但我需要先提高性能,然后再继续。我试过用一个纯 vec4 替换循环中的 texture2D() 调用,它运行没有问题,尽管其他一切都在发生。
我该如何优化呢?我知道这是可能的,因为我在 3D 运行中看到了更多涉及的效果,没有问题。我完全不明白为什么这会造成任何麻烦。
【问题讨论】:
-
"我尝试将循环中的 texture2D() 调用替换为纯 vec4 并且运行没有问题" 这是什么意思?它变得更快了吗?它没有改变性能吗?发生了什么?
-
"我完全不明白为什么这会造成任何麻烦。" 您在每个着色器调用中执行 十次纹理访问,并且你看不出是什么导致了问题?此外,您访问中心纹素两次。
-
在没有纹理查找的情况下(不包括最后一个),我得到了稳定的 60fps。正如我所说,它没有优化,但没有办法避免这些纹理调用。否则过滤器无法工作。但是我见过很多游戏,无论是手机游戏还是非手机游戏,都使用基于卷积过滤器的效果,而且它们似乎没有任何问题。除非有一些技巧可以避免它们?
标签: opengl-es filter opengl-es-2.0 glsl convolution