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