OpenGL水波纹效果

OpenGL水波纹效果

glsl水波纹效果,可使用shadertoy直接运行。sin和iTime配合得到水波纹mask,通过mask流动变化得到水波纹效果。

脚本1

#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);
}

脚本2

#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);
}

脚本3

#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);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章