【实例简介】
android动态壁纸中的水波纹效果,采用opengl中的shader实现
【实例截图】
【核心代码】
@Override
public String getVertexShader() {
String vertexShader = "attribute vec4 " ShaderProgram.POSITION_ATTRIBUTE ";\n" //
"attribute vec2 " ShaderProgram.TEXCOORD_ATTRIBUTE ";\n" //
"uniform mat4 u_projTrans;\n" //
"varying vec2 v_texCoords;\n" //
"\n" //
"void main()\n" //
"{\n" //
" v_texCoords = " ShaderProgram.TEXCOORD_ATTRIBUTE "; \n"
" gl_Position = u_projTrans * " ShaderProgram.POSITION_ATTRIBUTE ";\n" //
"}\n";
return vertexShader;
}
@Override
public String getFragmentShader() {
String fragmentShader =
"#define LOWP lowp\n" //
"precision mediump float;\n" //
"varying vec2 v_texCoords;\n" //
"uniform sampler2D u_texture;\n" //
"uniform vec4 u_ColorTotal;\n" //
"uniform float u_progress;\n" //
"const float c_wavelength = " mWaveLength ";\n" //波浪的宽度
"const float c_amps = c_wavelength / 6.283;\n" //3.1415 * 2.0
"const float c_amp = " mAmp ";\n" //计算振幅的参数
"const float c_radius = " mRatius ";\n"//最大的波浪半径
"\n"
"vec2 generateWaterRipples(float x, float y, float radius, vec2 pos) {\n"
(mRatio != 1f ? " x *= " mRatio ";\n" : "")
(mRatio != 1f ? " pos.x *= " mRatio ";\n" : "")
" vec2 delta = vec2(x, y) - pos;\n"
" float dist = length(delta);\n"
" if (dist < radius) { \n"//如果在半径以内,计算偏移
" float dist1 = radius - dist;\n"
" float amount = c_amp * (1.0 - u_progress);\n"//振幅比例随着时间慢慢变小
" amount *= sin(dist1 / c_amps);\n"//计算该点的振幅 3.1415 * 2.0
// " amount *= pow(dist1 / radius, 2.0);\n"//计算能量损失,离中心点越远,振幅越小
" return delta * amount;\n"
" }\n"
" return vec2(0.0, 0.0);\n"
"}\n"
"\n"
"void main()\n"//
"{\n" //
" vec2 texCoords = v_texCoords;\n"
" texCoords = generateWaterRipples(" mPosition[0] ", " mPosition[1] ", u_progress * c_radius, texCoords);\n"
// " if (texCoords.x < 0.0 || v_texCoords.y < 0.0 || texCoords.x > 1.0 || texCoords.y > 1.0)\n"
// " gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);\n"
// " else\n"
" gl_FragColor = texture2D(u_texture, texCoords) * u_ColorTotal;\n" //
"}";
return fragmentShader;
}