8个纹理单元的opengl es多纹理着色器的思考

Posted

技术标签:

【中文标题】8个纹理单元的opengl es多纹理着色器的思考【英文标题】:Thoughts on opengl es multitexture shader with 8 texture units 【发布时间】:2013-02-12 16:36:31 【问题描述】:

下面是一个表现不佳的片段着色器。删除条件分支似乎并没有提高性能。只有 150 个多边形,我在 Kindle Fire 上获得 10fps,在 Galaxy S3 上获得 20fps。如果有的话,对优化这个的最佳方法有什么想法吗? iPad 2 上的类似着色器运行 30+fps。

在下面的代码中,texture1 到 texture8 被绑定到八个纹理。 VertexTexturesOut1 和 VertexTexturesOut2 是从顶点着色器传递过来的,它们的值是 0.0 到 1.0,表示要混合的着色量。这个想法是混合景观纹理,让草均匀地融入泥土、岩石、沙子等。

uniform sampler2D texture1;
uniform sampler2D texture2;
uniform sampler2D texture3;
uniform sampler2D texture4;
uniform sampler2D texture5;
uniform sampler2D texture6;
uniform sampler2D texture7;
uniform sampler2D texture8;

varying mediump vec2 TextureCoordOut;
varying lowp vec4 VertexTexturesOut1;
varying lowp vec4 VertexTexturesOut2;

...

    lowp vec4 Color = vec4( 0.0, 0.0, 0.0, 0.0);

    if (VertexTexturesOut1.x != 0.0) Color = Color + texture2D ( texture1, TextureCoordOut ) * VertexTexturesOut1.x;
    if (VertexTexturesOut1.y != 0.0) Color = Color + texture2D ( texture2, TextureCoordOut ) * VertexTexturesOut1.y;
    if (VertexTexturesOut1.z != 0.0) Color = Color + texture2D ( texture3, TextureCoordOut ) * VertexTexturesOut1.z;
    if (VertexTexturesOut1.w != 0.0) Color = Color + texture2D ( texture4, TextureCoordOut ) * VertexTexturesOut1.w;

    if (VertexTexturesOut2.x != 0.0) Color = Color + texture2D ( texture5, TextureCoordOut ) * VertexTexturesOut2.x;
    if (VertexTexturesOut2.y != 0.0) Color = Color + texture2D ( texture6, TextureCoordOut ) * VertexTexturesOut2.y;
    if (VertexTexturesOut2.z != 0.0) Color = Color + texture2D ( texture7, TextureCoordOut ) * VertexTexturesOut2.z;
    if (VertexTexturesOut2.w != 0.0) Color = Color + texture2D ( texture8, TextureCoordOut ) * VertexTexturesOut2.w;

    gl_FragColor = Color;    

【问题讨论】:

1.拥有这些 if 语句有什么意义?这真的比只做乘法更快吗? 2. 刺破黑暗:也许对同一个变量的多次赋值不是最优的?拥有Color1Color2 并添加它们怎么样? 【参考方案1】:

在设计片段着色器时,您的着色器有许多 DONT。您有许多条件语句,因此所有线程都需要始终等待经纱(或批处理)中的所有其他线程。您还访问了 8 个纹理,这意味着您需要等待所有这些纹理查找(这也会消耗内存带宽)。使用任何优化工具,例如 Adreno SDK、Mali SDK 或您选择的任何供应商,并在他们的优化工具中运行着色器以发现 GPU 在哪里花费更多时间。

您是否使用完整的 RGB888 纹理?一个

也许如果您告诉我们您要归档什么,我们可以考虑另一种解决方案,而无需使用 8 个纹理查找。

【讨论】:

以上是关于8个纹理单元的opengl es多纹理着色器的思考的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL/C++:将多个纹理传递给一个着色器的问题

具有多个着色器程序的 OpenGL 多纹理

传递给片段着色器的纹理坐标全部为 0

没有纹理图像单元的 Opengl 纹理

GLSL Motion Blur Post Processing,进入着色器的 2 个纹理是相同的

OpenGL ES之如何传输一个超大数组给着色器程序