package com.glview.graphics.shader;
import com.glview.libgdx.graphics.glutils.ShaderProgram.HandleInfo;
public class RippleShader extends DefaultTextureShader {
float mRatio;
float[] mPosition = new float[2];
float mProgress = 0f;
HandleInfo mProgressHandleInfo;
float mWaveLength = 0.4f;
float mAmp = 0.2f;
float mRatius = 1.0f;
public RippleShader() {
this(0, 0, false);
}
public RippleShader(float width, float height, boolean circle) {
if (circle) {
mRatio = width / height;
} else {
mRatio = 1f;
}
mPosition[0] = 0.5f;
mPosition[1] = 0.5f;
mProgressHandleInfo = new HandleInfo("u_progress");
}
public void setProgress(float progress) {
mProgress = progress;
}
@Override
protected String generateFragmentShader() {
StringBuffer fragmentShader = new StringBuffer();
fragmentShader.append("#ifdef GL_ES\n"); //
fragmentShader.append("#define LOWP lowp\n"); //
fragmentShader.append("precision mediump float;\n"); //
fragmentShader.append("#else\n"); //
fragmentShader.append("#define LOWP \n"); //
fragmentShader.append("#endif\n"); //
fragmentShader.append("varying vec2 v_texCoords;\n"); //
fragmentShader.append("uniform sampler2D u_texture;\n"); //
fragmentShader.append("uniform vec4 u_ColorTotal;\n"); //
fragmentShader.append("uniform float u_progress;\n"); //
fragmentShader.append("const float c_wavelength = " + mWaveLength + ";\n"); //波浪的宽度
fragmentShader.append("const float c_amps = c_wavelength / 6.283;\n"); //3.1415 * 2.0
fragmentShader.append("const float c_amp = " + mAmp + ";\n"); //计算振幅的参数
fragmentShader.append("const float c_radius = " + mRatius + ";\n"); //最大的波浪半径
fragmentShader.append("\n"); //
fragmentShader.append("vec2 generateWaterRipples(float x, float y, float radius, vec2 pos) {\n"); //
fragmentShader.append((mRatio != 1f ? " x *= " + mRatio + ";\n" : "")); //
fragmentShader.append((mRatio != 1f ? " pos.x *= " + mRatio + ";\n" : "")); //
fragmentShader.append(" vec2 delta = vec2(x, y) - pos;\n"); //
fragmentShader.append(" float dist = length(delta);\n"); //
fragmentShader.append(" if (dist < radius) { \n"); //如果在半径以内,计算偏移
fragmentShader.append(" float dist1 = radius - dist;\n"); //
fragmentShader.append(" float amount = c_amp * (1.0 - u_progress);\n"); //振幅比例随着时间慢慢变小
fragmentShader.append(" amount *= sin(dist1 / c_amps);\n"); //计算该点的振幅 3.1415 * 2.0
// fragmentShader.append(" amount *= pow(dist1 / radius, 2.0);\n"); //计算能量损失,离中心点越远,振幅越小
fragmentShader.append(" return delta * amount;\n"); //
fragmentShader.append(" }\n"); //
fragmentShader.append(" return vec2(0.0, 0.0);\n"); //
fragmentShader.append("}\n"); //
fragmentShader.append("\n"); //
fragmentShader.append("void main()\n");//
fragmentShader.append("{\n");//
fragmentShader.append(" vec2 texCoords = v_texCoords;\n"); //
fragmentShader.append(" texCoords += generateWaterRipples(" + mPosition[0] + ", " + mPosition[1] + ", u_progress * c_radius, texCoords);\n"); //
// fragmentShader.append(" if (texCoords.x < 0.0 || v_texCoords.y < 0.0 || texCoords.x > 1.0 || texCoords.y > 1.0)\n"); //
// fragmentShader.append(" gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);\n"); //
// fragmentShader.append(" else\n"); //
fragmentShader.append(" gl_FragColor = u_ColorTotal*texture2D(u_texture, texCoords);\n"); //
fragmentShader.append("}");
return fragmentShader.toString();
}
@Override
public void setupCustomValues() {
getShaderProgram().setUniformf(mProgressHandleInfo, mProgress);
}
}