Opengl es 2.0自定义着色器低fps(android)

时间:2012-12-06 22:49:59

标签: android performance opengl-es-2.0 glsl fragment-shader

我正在制作一个简单的应用程序/壁纸,为背景图像添加简单的水波纹效果。

我正在测试HTC Desire(Android 2.2)。

我已经找到了解决方法,并为android Adrian Boeing: Blog实现了它。

现在的问题是性能非常低。如果我有静止图像(使用普通着色器),则fps约为40-50fps。如果我添加计算sinc函数的部分,并使用纹理fps的新计算值下降到20fps。

问题是我想增加的不仅仅是1个波纹,而fps下降/ 2个数量的涟漪(t.i 2涟漪= 10fps,3涟漪5 fps等......)。

我是否严重实施了这个着色器,并且它有一些可以进行大幅优化的空间,还是以其他方式完成这样的效果?

效果类似于Android上的默认动态壁纸,名为Water(秋叶落到下面的涟漪池)。

以下是我的着色器的代码:

    private final String fragmentShaderCode = 
        "precision mediump float;" + 
        "uniform sampler2D uTexture;"+ 
        "varying vec2 vTexCoordinate;"+ 
        "uniform float mTime;"+ //time variable 
        "uniform float offX;"+//center of wave 
        "uniform float offY;"+//center of wave 
        "uniform float size;"+//size of wave (so you can make it smaller over time) 
        "void main() {" + 
        "        vec2 off2 = vec2(offX,offY);"+ 
        "        vec2 cPos = -1.0 + 2.0 * vTexCoordinate.xy;" + //bring coordinate to middle of screen 
        "        vec2 ofvec = cPos+off2;"+ //doda offset 
        "        float r = length(ofvec);"+ //length of vector 
        "        cPos = vTexCoordinate + (size)/(r*2.0)*sin(r*100.0-mTime); "+ //sinc function for wave simulation 
        "        gl_FragColor = texture2D(uTexture,cPos);" + //draw texture 
        "}"; 

注意:我添加了此代码,因为它易于阅读。使用多个触摸事件的代码,只使用offX,offY的向量,并在for循环中执行下面的代码。

1 个答案:

答案 0 :(得分:3)

片段着色器中的大量繁重计算严重影响了性能。移动OpenGL ES设备优化的常见做法是将大量计算移动到顶点着色器。

在这种情况下,您需要重新考虑着色器的逻辑并修改几何体。我建议制作一个具有足够细分的网格来模拟水波,并改变顶点位置以产生连锁反应。

或者,您可以将所有逻辑保留在片段着色器中,但使用带有偏移数据的外部烘焙纹理来更改UV偏移的计算。这样,您将获得相同的效果,但性能会有显着提升。对于给定距离的UV增量,您必须存储单独的纹理烘焙数据,并从此纹理中读取准备好的预先计算的值。所有移动设备GPU都至少有2个纹理采样器,因此额外的texture2D()呼叫几乎是免费的。

要了解它是如何工作的,请阅读这篇文章http://prideout.net/blog/?p=56这是关于路径变形的,但是你应该看一下从纹理中抽取某些预先计算的数据的方法。