优化着色器(OSL GLSL2.0)

时间:2013-09-06 19:37:32

标签: android optimization opengl-es opengl-es-2.0 shader

我的目标是在openGl中重新创建气泡图的实现,以便它变得更快。作为参考,当前实现使用canvas以8 fps运行。它在Android手机屏幕上绘制了5200个圆圈。 它们实时改变颜色,大小和位置。

我曾尝试精灵批处理它们,但由于某些未知原因,我不能一次批量处理超过15个。 然后我试图将它们全部放入纹理矩形,但构建网格需要很长时间,即使我不在绘制之间更改它,它也很慢。

现在,我认为可以优化我当前的着色器,但我缺乏太多的知识。

优化的一个潜在地方是网格生成,目前它是这样的: x,y,z,r,g,b,a,tx,ty,x,y,z,.... 其中(x,y,z)是顶点位置,(r,g,b,a)是颜色,(tx,ty)是纹理坐标,但是(z,r,g,b,a)是相等的同一个正方形的所有顶点。 (tx,ty)对于顶点1总是0,0; 1,0表示顶点2,依此类推......

此外,每个正方形有6个顶点而不是4个,因为相同的网格具有析取正方形

我的顶点着色器:

uniform mat4 uMVPMatrix;
attribute vec4 aPosition;
attribute vec4 aColor;
attribute vec4 aTexCoordinate;
varying vec2 vTexCoordinate;
varying vec4 vColor;
void main() {
  vColor = aColor;
  vTexCoordinate = aTexCoordinate.xy;
  gl_Position = uMVPMatrix * aPosition;
}

My Fragment Shader:

private final String FragmentShaderCode = 
precision mediump float;
uniform sampler2D u_Texture;
varying vec4 vColor;
varying vec2 vTexCoordinate;
void main() {
  gl_FragColor = texture2D(u_Texture, vTexCoordinate) *vColor;
}

我真的不明白着色器代码是如何被翻译成“在这里画出这种颜色”的,所以我无法想象我应该如何解决这些冗余问题。

编辑/更新:

profiler screencap

原来有两种(不相关的?)方法导致减速。 EGLImpl.eglSwapBuffers和GLES20.glClear。但是,如果我不绘制5200个方格,这些方法不会导致减速。根据{{​​3}}它是由着色器引起的(如果我不绘制5200个三角形就不会发生),不幸的是,海报忘了告诉着色器做了什么导致这些方法变慢。< / p>

更新2,绘制代码,不确定它是否有帮助

public void draw(float[] mvpMatrix) {
    if (!isPacked) {
        pack();
    }
    GLES20.glUseProgram(GlProgram);
    // ////////////////////
    int mTextureUniformHandle = GLES20.glGetUniformLocation(GlProgram, "u_Texture");
    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureDataHandle);
    GLES20.glUniform1i(mTextureUniformHandle, 0);
    // ///////////////////////
    VertexBuffer.position(0);
    int PositionHandle = GLES20.glGetAttribLocation(GlProgram, "aPosition");
    GLES20.glEnableVertexAttribArray(PositionHandle);
    GLES20.glVertexAttribPointer(PositionHandle, 3, GLES20.GL_FLOAT, false, (3 + 4 + 2) * 4, VertexBuffer);
    // ///////////////
    VertexBuffer.position(3);
    int ColorHandle = GLES20.glGetAttribLocation(GlProgram, "aColor");
    GLES20.glEnableVertexAttribArray(ColorHandle);
    GLES20.glVertexAttribPointer(ColorHandle, 4, GLES20.GL_FLOAT, false, (3 + 4 + 2) * 4, VertexBuffer);
    // /////////////////
    VertexBuffer.position(7);
    int TexCoordinate = GLES20.glGetAttribLocation(GlProgram, "aTexCoordinate");
    GLES20.glEnableVertexAttribArray(TexCoordinate);
    GLES20.glVertexAttribPointer(TexCoordinate, 2, GLES20.GL_FLOAT, false, (3 + 4 + 2) * 4, VertexBuffer);
    // /////////////////
    int MVPMatrixHandle = GLES20.glGetUniformLocation(GlProgram, "uMVPMatrix");
    GLES20.glUniformMatrix4fv(MVPMatrixHandle, 1, false, mvpMatrix, 0);
    // /////////////
    GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, totalvertz);
    GLES20.glDisableVertexAttribArray(PositionHandle);
    GLES20.glDisableVertexAttribArray(ColorHandle);
    GLES20.glDisableVertexAttribArray(TexCoordinate);
}

1 个答案:

答案 0 :(得分:1)

绘制5200四边形是没有任务的,如果正确实施,它应该可以在任何设备上顺利运行。

你的着色器太简单了,无法优化,你几乎无能为力。

在继续之前,您检查过OpenGL错误吗? (是glGetError() == 0?)这些会导致大量的帧速率下降。

编辑: 还有一些我能想到的其他事情,但如果没有看到你的代码就很难了:

  • 您是否有效地使用FloatBuffers?
  • 您确定不是每帧都创建一个新的顶点缓冲区吗?
  • 所有四边形应该在一个网格中,这意味着一个绘制调用。是这种情况吗?