如何在Android上创作复杂流畅的动画?
我想在Android上写一个动画,用水波效应为整个视图制作动画。经过一些研究,我在如何在Android上创作复杂流畅的动画?,android,animation,opengl-es,Android,Animation,Opengl Es,我想在Android上写一个动画,用水波效应为整个视图制作动画。经过一些研究,我在GLSurfaceView上用OpenGL ES 2.0实现了我的第一个实现。我有一个片段着色器,如下所示: precision mediump float; // Set the default precision to medium. We don't need as high of a // precision in the fr
GLSurfaceView
上用OpenGL ES 2.0实现了我的第一个实现。我有一个片段着色器,如下所示:
precision mediump float; // Set the default precision to medium. We don't need as high of a
// precision in the fragment shader.
uniform sampler2D u_Texture; // The input texture
uniform float u_Time; // Current time
uniform float u_CenterX; // Water ripple origin x, in (0, 1)
uniform float u_CenterY; // Water ripple origin y, in (0, 1)
uniform float u_AspectRatio; // Aspect ratio of screen
varying vec2 v_TexCoordinate; // Interpolated texture coordinate per fragment
float offset(float waveR, float r)
{
float HALF_PI = 3.14 * 0.5;
float WAVE_HEIGHT = 30.0;
float WAVE_WIDTH = 200.0;
return r + WAVE_HEIGHT * sin((r - waveR) / WAVE_WIDTH * HALF_PI) * exp(-abs(r - waveR) / WAVE_WIDTH);
}
void main()
{
float RES = 720.0;
float R = 0.3;
float T = 1000.0;
vec2 st = v_TexCoordinate.st;
float radius = RES * R;
vec2 xy = RES * st;
vec2 center = RES * vec2(u_CenterX, u_CenterY);
float waveR = 1.5 * RES * u_Time / T;
vec2 dxy = xy - center;
dxy.t = dxy.t * (1.0 / u_AspectRatio);
float beta = atan(dxy.y, dxy.x);
float r = length(dxy);
vec2 xy1 = xy;
float offsetR = offset(waveR, r);
xy1.s = center.s + offsetR * vec2(cos(beta)).s;
xy1.t = center.t + offsetR * vec2(sin(beta)).t * u_AspectRatio;
st = xy1 / RES;
vec3 irgb = texture2D(u_Texture, st).rgb;
gl_FragColor = vec4(irgb, 1.0);
}
setDrawingCacheEnabled(true);
destroyDrawingCache();
buildDrawingCache();
Bitmap selfCache = getDrawingCache();
setDrawingCacheEnabled(false);
然而,我的动画有几个问题。首先,它只在一台设备上运行良好。在其他设备上,效果看起来很奇怪。此外,我还必须获得整个视图的图形缓存,才能将其放在GLSurfaceView
上,这是一个缓慢的过程(~100毫秒),因此它会暂停上一个动画,看起来不自然。第三,在如何使图形缓存与原始视图的大小和位置完全相同方面存在问题。似乎SurfaceView
s不能有alpha值,所以我甚至不能通过淡入/淡出视图来进行任何变通。我获得的图形缓存如下所示:
precision mediump float; // Set the default precision to medium. We don't need as high of a
// precision in the fragment shader.
uniform sampler2D u_Texture; // The input texture
uniform float u_Time; // Current time
uniform float u_CenterX; // Water ripple origin x, in (0, 1)
uniform float u_CenterY; // Water ripple origin y, in (0, 1)
uniform float u_AspectRatio; // Aspect ratio of screen
varying vec2 v_TexCoordinate; // Interpolated texture coordinate per fragment
float offset(float waveR, float r)
{
float HALF_PI = 3.14 * 0.5;
float WAVE_HEIGHT = 30.0;
float WAVE_WIDTH = 200.0;
return r + WAVE_HEIGHT * sin((r - waveR) / WAVE_WIDTH * HALF_PI) * exp(-abs(r - waveR) / WAVE_WIDTH);
}
void main()
{
float RES = 720.0;
float R = 0.3;
float T = 1000.0;
vec2 st = v_TexCoordinate.st;
float radius = RES * R;
vec2 xy = RES * st;
vec2 center = RES * vec2(u_CenterX, u_CenterY);
float waveR = 1.5 * RES * u_Time / T;
vec2 dxy = xy - center;
dxy.t = dxy.t * (1.0 / u_AspectRatio);
float beta = atan(dxy.y, dxy.x);
float r = length(dxy);
vec2 xy1 = xy;
float offsetR = offset(waveR, r);
xy1.s = center.s + offsetR * vec2(cos(beta)).s;
xy1.t = center.t + offsetR * vec2(sin(beta)).t * u_AspectRatio;
st = xy1 / RES;
vec3 irgb = texture2D(u_Texture, st).rgb;
gl_FragColor = vec4(irgb, 1.0);
}
setDrawingCacheEnabled(true);
destroyDrawingCache();
buildDrawingCache();
Bitmap selfCache = getDrawingCache();
setDrawingCacheEnabled(false);
有没有更快的办法?或者如果我真的想要视图的最新更新外观,那么销毁/构建步骤是否真的必要
总的来说,我想问的是,带有GLSurfaceView
的OpenGL ES 2.0是否是实现此类动画的合适工具?我查看了其他人的一些水波效应演示(使用Java或JNI代码实现而不使用OpenGL),但是,我没有找到一个性能良好的实现(其中一些实现的fps为3!)。如果您能帮我指出我的着色器代码中的任何错误或我获取图形缓存的方式,我将非常感激