【问题标题】:OpenGL ES shader degrades too much performanceOpenGL ES 着色器降低了太多性能
【发布时间】:2012-05-28 22:42:19
【问题描述】:

我正在优化一款适用于 iPhone 和 Android 的游戏。我正在使用 4 个着色器来绘制场景,我注意到如果我将其中一个更改为另一个,则 fps 从 32 变为 42,即使该着色器仅绘制了 1 个精灵,而这 2 个着色器的唯一区别只是片段着色器中的一个产品。

这些是着色器:

default-2d-tex.shader

#ifdef GL_ES
precision highp float;
precision lowp int;
#endif

#ifdef VERTEX

uniform mat4        umvp;

attribute vec4      avertex;
attribute vec2      auv;

varying vec2        vuv;

void main()
{
    // Pass the texture coordinate attribute to a varying.
    vuv = auv;

    // Here we set the final position to this vertex.
    gl_Position = umvp * avertex;
}

#endif

#ifdef FRAGMENT

uniform sampler2D   map0;
uniform vec4 ucolor;

varying vec2        vuv;

void main()
{
    gl_FragColor =  texture2D(map0, vuv) * ucolor;
}

#endif

default-2d-tex-white.shader

#ifdef GL_ES
precision highp float;
precision lowp int;
#endif

#ifdef VERTEX

uniform mat4        umvp;

attribute vec4      avertex;
attribute vec2      auv;

varying vec2        vuv;

void main()
{
    // Pass the texture coordinate attribute to a varying.
    vuv = auv;

    // Here we set the final position to this vertex.
    gl_Position = umvp * avertex;
}

#endif

#ifdef FRAGMENT

uniform sampler2D   map0;

varying vec2        vuv;

void main()
{
    gl_FragColor =  texture2D(map0, vuv);
}

#endif

再次,
如果我修改 default-2d-tex.shader 并删除产品“* ucolor”,则 fps 会从 32 变为 42,并且我只将它用于场景中的一个精灵!

这正常吗?为什么这个着色器这么慢,我该如何改进它?

编辑:

我发现 iPod 和 Android 的性能下降的比例相同。两者都是 PowerVr SGX GPU(iPod 第三代和三星 Galaxy SL -PowerVR SGX 530-)。 iOS 版本是 4.1,Android 是 2.3.3

我正在绘制的精灵被缩放以填充屏幕(缩放为 4 倍),并且我每帧绘制一次。它取自纹理贴图,因此纹理实际上更大(1024x1024),但所取的部分为 80x120。 Alpha 混合已启用。

编辑 2

我犯了一个错误。精灵缩放 11 倍:它的 32x48。 如果我根本不画那个精灵,fps 会变成 45。我在场景中画了很多精灵,为什么要花这么多时间?难道是因为它的规模太大了?

【问题讨论】:

  • 作为建议,在分析时测量帧渲染时间,而不是帧速率。 Framerate isn't always the best metric。您在哪个硬件和操作系统版本上看到了这种减速? Android 和 iOS 的减速是否一致?这个精灵有多大的像素?您启用了哪种混合模式?
  • 我很难发现代码中的差异只是片段着色器中的最终输出乘法。你应该只发布那部分。而且我怀疑这么小的乘法会导致性能下降。您的渲染通道设置如何?如果您的渲染设置模拟更多像素(通常用于后处理),则可能会导致性能下降。
  • 信息在哪里?您只提供不相关的纹理大小。这个精灵在屏幕上占据了多少像素?它不是全屏还是缩放到 4 倍是什么意思?
  • @djmj:我澄清了区别是“* ucolor”,我添加了所有信息。请再读一遍,精灵被缩放以填满屏幕(ipod 为 320x480,android 为 480x800)
  • 请注意,iOS 4.2 引入了更好的着色器编译器,因此您可能不会在使用该操作系统版本及更高版本的设备上看到这么多的减速。我的猜测是混合是这里的罪魁祸首,因为在这些设备上这是一项极其昂贵的操作。混合通常可以成倍增加片段着色器中额外计算的影响。尝试将下面的内容渲染为不透明元素,首先关闭混合,然后仅对这个叠加精灵启用混合并绘制它。

标签: android iphone performance opengl-es glsl


【解决方案1】:

当您从上述代码中删除“* ucolor”时,会发生很多事情:

  1. 制服 ucolor 变为未使用
  2. GLSL 编译器从活动制服集中移除此制服
  3. 当你有你的程序链接失踪制服的 ID 变为 -1
  4. 当您对已移除的制服执行 glUniform4fv(-1, value) 时 立即退出,无需任何更新

与使用“* ucolor”相比,这要少得多。

此外,在片段着色器中,每个片段的操作更少。

【讨论】:

  • 那么完全使用制服将是与他的帧率下拉相关的最大性能杀手!我从来没有观察过这样的使用制服的下拉菜单。
  • 是的。这个着色器只有 1 个不断更新的制服。制服被脱掉了。这解释了一些性能提升。着色器本身也变得更轻量级。这就解释了更多的速度增益。
  • 再次:我每帧使用一次此着色器。 @SergeyK。你觉得shader有那么贵吗?
  • 取决于您绘制的像素数。如果你画一个全屏四边形——它可能会很贵,尤其是在新 iPad 上。
  • @Damian:我们体验到填充率非常有限。带有近乎微不足道的着色器的全屏四边形会吞噬一切。
【解决方案2】:

您的问题出在 default-2d-tex.shader 中的片段着色器中。你有 统一的 vec4 ucolor; 这意味着,您的每个颜色组件 (RGBA) 都将转换为 32 位浮点值。这会严重降低性能。 应该: 统一的lowp vec4 ucolor;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多