Opengl es 如何在opengles中优化纹理提取

Opengl es 如何在opengles中优化纹理提取,opengl-es,Opengl Es,我想在着色器中绘制一个贴图,它由五个纹理组成。一个用于每个纹理的比率(CC_Texture0:512x512),另外四个是不同的元素(u_tex_r、u_tex_g、u_tex_b、u_tex_a:256x256) 我的着色器是: varying vec4 v_fragmentColor; #ifdef GL_ES varying highp vec2 v_uv0; #else varying vec2 v_uv0; #endif //uniform vec2 repeated_r; //un

我想在着色器中绘制一个贴图,它由五个纹理组成。一个用于每个纹理的比率(CC_Texture0:512x512),另外四个是不同的元素(u_tex_r、u_tex_g、u_tex_b、u_tex_a:256x256)

我的着色器是:

varying vec4 v_fragmentColor;
#ifdef GL_ES
varying highp vec2 v_uv0;
#else
varying vec2 v_uv0;
#endif

//uniform vec2 repeated_r;
//uniform vec2 repeated_g;
//uniform vec2 repeated_b;
//uniform vec2 repeated_a;

uniform vec4 u_repeat_1;
uniform vec4 u_repeat_2;

uniform sampler2D u_tex_r;
uniform sampler2D u_tex_g;
uniform sampler2D u_tex_b;
uniform sampler2D u_tex_a;

void main()
{
    vec4 mix = texture2D(CC_Texture0, v_uv0);

    vec4 r = texture2D(u_tex_r, vec2(v_uv0.x * 20, v_uv0.y * 20));
    vec4 g = texture2D(u_tex_g, vec2(v_uv0.x * 20, v_uv0.y * 20));
    vec4 b = texture2D(u_tex_b, vec2(v_uv0.x * 20, v_uv0.y * 20));
    vec4 a = texture2D(u_tex_a, vec2(v_uv0.x * 20, v_uv0.y * 20));

    gl_FragColor = vec4((r * mix.r + g * mix.g + b * mix.b + a * mix.a).rgb, 1.0);
    //gl_FragColor = vec4((r * mix.r + g * mix.g + b * mix.b).rgb, 1.0);
}

该设备是三星G5308W,帧速率只有50 fps,甚至我删除的规模。当我只打印CC_Texture0时,帧速率可以是60fps。为什么?GPU内存还是规模?任何人都可以帮助改进它?

显然,您的着色器在计算方面非常简单,因此我怀疑限制性能的因素是获取teture数据的成本。这在移动设备上并不少见,内存带宽通常是帧速率的限制因素,也是影响电池寿命和设备散热的最大能源消耗因素之一

一些建议:

  • 您提到移除刻度对性能没有帮助(我想您的意思是在构建UV时移除
    *20
    )。即使它对这个设备没有可测量的影响,我仍然建议避免读取依赖纹理,因为它可能会稍微提高性能,并且可能会在一些旧设备上大大提高性能。添加第二组UV,您可以在顶点着色器上计算这些UV,并将其作为变量传入。如果每个纹理需要不同的比例,那么我会添加4个新的变量。瓦林鞋很便宜。不要试图将多个UV编码到vec4中,这可能会导致依赖纹理读取
  • 您提到的是纹理分辨率,而不是纹理格式。如果您能够尽可能降低这些纹理的每像素位数,您将看到对性能的巨大影响。压缩纹理(例如,ETC1是4bpp)是最好的,但即使从8888切换到565或4444也会有很大帮助
  • 在某些情况下可以使用更简单的着色器吗?您没有提到上下文,但这有地形纹理飞溅的感觉。在地形中,您通常会发现,很少有几何体块实际使用所有平铺纹理。如果您可以识别引用较少纹理的几何体,并对引用较少纹理的几何体使用更专门的片段着色器,那么您将获得良好的性能提升。取舍是更复杂的代码和可能更多的绘制调用和状态更改,这可能会影响CPU时间,因此这可能是一个棘手的平衡操作
  • 最后,G5308W是一款有6年历史的设备,如果你不能达到每秒60帧,那么它就不是世界末日

PS。如果删除“缩放”,帧速率会更好。对不起,fps在此设备中不太稳定非常感谢!对于第一个建议,我不是很清楚。你能给我一个样品吗?是的,这是一个地形纹理喷溅。我们将很快尝试您的建议。一些移动硬件有一个特殊的快速路径,允许在片段着色器运行之前获取纹理数据。但是,它只能在事先知道UV坐标的情况下执行此操作(即UV不依赖于着色器)。很容易意外地使纹理与读取相关。你的
texture2D(CC_Texture0,v_uv0)是完美的。你的
纹理2d(u_tex_r,vec2(v_uv0.x*20,v_uv0.y*20))不是因为修改了UV。类似于
texture2D(CC_Texture0,v_uv0.zw)也会有问题。你需要
texture2D(u_tex_r,v_uv1)其中
v_uv1
是一个新的变量。完美,我知道。我以前也尝试过同样的方法,将地图分割成多个网格并计算UV。但我记得FPS没有改进。但是你的建议对我很有帮助。我将再次检查代码并进行进一步测试。再次感谢!