precision mediump float; uniform float uTime; uniform vec4 uMouse; uniform vec2 uSize; uniform vec4 uBackColor; uniform vec3 uForeColor; varying vec2 vUv; /** * 透明度計算用 */ float alpha( float edge,// [px] しきい値 float y // [px] Y座標 ) { const float blurRadius = 0.5;//(境界のボケる半径) return smoothstep( edge - blurRadius, edge + blurRadius, y ); } /** * 凸凹が連続する波 */ float f( float x, // [px] X座標 float wavelength,// [px] 波長 float amplitude, // [px] 振幅 float offsetX, // [px] 横のオフセット float offsetY // [px] 縦のオフセット ) { x = (x + offsetX) / wavelength; return sin(x * radians(360.)) * amplitude + offsetY; } /** * 凸が一個だけの波(マウスの影響を加える用) */ float g( float x, // [px] X座標 float wavelength,// [px] 波長 float amplitude, // [px] 振幅 float offsetX, // [px] 横のオフセット float offsetY // [px] 縦のオフセット ) { x = clamp( (x - offsetX) / wavelength, -1.0, 1.0 ); return (cos(x * radians(180.)) + 1.0) * 0.5 * amplitude + offsetY; } /** * 0〜1を一定時間[ms]で無限ループするのこぎり波の生成用 */ float time( float duration// ループ間隔[ms] ) { return clamp( mod(uTime, duration) / duration, 0.0, 1.0 ); } /** * 複雑なな形状の波の合成用(3種類の異なる波を足し合わせる) */ float wave( float x, // [px] X座標 float wavelength1, float amplitude1,// [px] 波①の波長&振幅 float wavelength2, float amplitude2,// [px] 波②の波長&振幅 float wavelength3, float amplitude3,// [px] 波③の波長&振幅(マウスエフェクト用) float offsetX, float offsetY // [px] 全体のオフセット ) { return f( x, uSize.x * wavelength1, uSize.y * amplitude1, uSize.x * offsetX, 0.0 ) + f( x, uSize.x * wavelength2, uSize.y * amplitude2, uSize.x * offsetX, 0.0 ) + g( x, uSize.x * wavelength3, uSize.y * amplitude3 * uMouse.w, (uMouse.x + 1.0) * 0.5 * uSize.x, 0.0 ) + uSize.y * offsetY; } /** * アルファブレンド用 */ vec4 blend( vec4 src,// 上の色 RGBA vec4 dst // 下の色 RGBA ) { return vec4( src.rgb * src.a + dst.rgb * (1.0 - src.a), src.a + dst.a ); } void main() { // (左上を原点とする)(上の)ピクセルの座標[px] vec2 px = vec2( 0.0 + gl_FragCoord.x, uSize.y - gl_FragCoord.y ); // 波① float wave1 = wave( px.x, 1.5, 0.05, 3.0, 0.03, 0.2, 0.08, 3.0 * time(2.0 * 91000.0),// wave1,2の最小公倍数となるように 0.5 ); // 波② float wave2 = wave( px.x, 0.5, 0.03, 2.0, 0.02, 0.3, 0.09, 4.0 * -time(2.0 * 71000.0),// wave1,2の最小公倍数となるように 0.5 ); // 波③ float wave3 = wave( px.x, 1.2, 0.08, 3.0, 0.05, 0.4, 0.05, 6.0 * time(2.0 * 61000.0),// wave1,2の最小公倍数となるように 0.5 ); // 波①の透明度 float a1 = alpha( wave1, px.y ); // 波②の透明度 float a2 = alpha( wave2, px.y ); // 波③の透明度 float a3 = alpha( wave3, px.y ); // 波①②③の色 //vec3 rgb = vec3(1.0, 1.0, 1.0);// 白 // 波①②③の透明度 float a = ( a1 * .3 + a2 * .3 + a3 * .4 ); // 前景, 背景 vec4 foreground = vec4(uForeColor, a); vec4 background = uBackColor; // 前景と背景を合成&出力 gl_FragColor = blend( foreground, background ); }