3

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

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

我已经找到了关于如何完成并为 android Adrian Boeing 实现它的解释:博客

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

问题是我想添加的不仅仅是 1 个涟漪,而且 fps 会按涟漪数下降 /2(ti 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使用vector,并在for循环中执行下面的代码。

4

1 回答 1

3

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

In this case you will need to reconsider logic of shaders and modify geometry too. I propose to make a mesh with good enough tessellation to simulate water waves, and alter vertex positions to make ripple effect.

Alternatively, you can leave all logic within fragment shader but alter computation of UV offset using external baked texture with offset data. This way you will have the same quality of effect but with significantly improved performance. You have to store in separate texture baked data for UV deltas for given distances and read ready pre-computed value from this texture. All mobile devices GPUs has at least 2 texture samplers so additional texture2D() call is almost free.

To have an idea how it works, please read this article http://prideout.net/blog/?p=56 It is about path deform, but you should take a look at the method of sampling certain pre-calculated data from texture.

于 2012-12-07T09:48:34.213 回答