glsl水波纹效果,可使用shadertoy直接运行。sin和iTime配合得到水波纹mask,通过mask流动变化得到水波纹效果。
#iChannel0 "file://./bg0.jpg"
// 水波纹中心点
const vec2 center = vec2(0.5, 0.5);
// 水波纹速度
const float speed = 2.5;
// 水波纹强度
const float intensity = 36.0;
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
// 计算uv
vec2 uv = fragCoord.xy / iResolution.xy;
// 计算center到各个uv的值
float dst = distance(uv, center);
// fragColor = vec4(vec3(dst), 1.0);
// 计算水波纹
// sin将对这个范围限制到[-1, 1]
// dst范围是[0, sqrt(2)]
// intensity可以理解为波纹数
// iTime的引入让一个点可以从[-1, 1]的变化
// speed是速度
// 可以理解为dst*intensity是初始波纹, iTime的引入让波纹动了起来
float wave = sin(sqrt(dst)*intensity-iTime*speed);
// fragColor = vec4(vec3(wave), 1.0);
// 接下来使用da和偏移的db来mix, 也就是水波纹白色区域取db, 黑色区域取da
vec3 da = texture2D(iChannel0, uv).rgb;
vec3 db = texture2D(iChannel0, uv-vec2(0.01)).rgb;
vec3 res = mix(da, db, wave*wave); // wave*wave范围为[0, 1]
fragColor = vec4(res, 1.0);
}
#iChannel1 "file://./bg0.jpg"
#iChannel2 "file://./mask.png"
const float intensity = 0.02;
const float speed = 10.0;
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
vec2 uv1 = fragCoord.xy / iResolution.xy;
// mask的uv流动
vec2 uv2 = uv1 + vec2(0.0, iTime * speed / 100.0);
// 由于vs中不能对iChannel2进行repeat, 所以进行一个求余操作
uv2 = mod(uv2, 1.0);
// 得到mask的流动
vec2 wave = texture2D(iChannel2, uv2).xy;
// wave范围是[0, 1], intensity限制了范围, 错位得取像素
uv1 = uv1 + wave*intensity;
fragColor = texture(iChannel1, uv1);
}
#iChannel0 "file://./bg0.jpg"
const float speed = 1.0;
const float intensity = 6.0;
float wave(vec2 pos, float t, float freq, float numWaves, vec2 center) {
float d = length(pos - center);
d = log(1.0 + exp(d));
return 1.0/(1.0+20.0*d*d) * sin(2.0*3.1415*(-numWaves*d + t*freq));
}
float height(vec2 pos, float t) {
float w;
w = wave(pos, t, speed, intensity, vec2(0.5, -0.5));
w += wave(pos, t, speed, intensity, -vec2(0.5, -0.5));
return w;
}
vec2 normal(vec2 pos, float t) {
return vec2(height(pos - vec2(0.01, 0), t) - height(pos, t),
height(pos - vec2(0, 0.01), t) - height(pos, t));
}
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
vec2 uv = fragCoord.xy / iResolution.xy;
vec2 uvn = 2.0*uv - vec2(1.0);
uv += normal(uvn, iTime);
fragColor = texture2D(iChannel0, uv);
}