我正在制作一个简单的应用程序/墙纸,它将简单的水波效果添加到背景图像中。
我正在测试HTC Desire (Android 2.2)。
我找到了这个解释,并在android Adrian Boeing: Blog上实现了它。
现在的问题是性能非常低。如果我有静态图像(使用正常的着色器),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的向量,并在for循环中执行以下代码。
发布于 2012-12-07 17:48:34
碎片着色器中的大量繁重计算会严重影响性能。对移动OpenGL ES设备进行优化的常见做法是将繁重的计算移动到顶点着色器。
在这种情况下,您需要重新考虑着色器的逻辑,并修改几何体。我建议做一个足够好的网格来模拟水波,并改变顶点的位置来产生涟漪效果。
或者,可以将所有逻辑保留在片段着色器中,但使用带有偏移数据的外部烘焙纹理更改UV偏移的计算。通过这种方式,您将具有相同的效果质量,但性能会有显着提高。您必须将给定距离的UV增量的烘焙数据存储在单独的纹理中,并从该纹理读取已准备好的预计算值。所有的移动设备GPU都至少有2个纹理采样器,所以额外的texture2D()调用几乎是免费的。
想知道它是如何工作的,请阅读这篇关于路径变形的文章http://prideout.net/blog/?p=56,但你应该看看从纹理中采样某些预先计算的数据的方法。
https://stackoverflow.com/questions/13754055
复制相似问题