three+webgl+gsap模拟海底海水涟漪动画效果代码
代码语言:html
所属分类:动画
代码描述:three+webgl+gsap模拟海底海水涟漪动画效果代码
代码标签: three webgl gsap 模拟 海底 海水 涟漪 动画
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<link type="text/css" rel="stylesheet" href="//repo.bfw.wiki/bfwrepo/css/reset.min.css">
</head>
<body>
<canvas id="webgl-canvas"></canvas>
<!-- vertexShader -->
<script id="js-vertex-shader" type="x-shader/x-vertex">
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
</script>
<!-- fragmentShader -->
<script id="js-fragment-shader" type="x-shader/x-fragment">
precision mediump float;
uniform float time;
uniform float uCircleScale;
uniform vec2 uViewport;
uniform sampler2D uVideo;
uniform sampler2D uImage;
varying vec2 vUv;
// 以下のサイトにあるavener.glslのノイズを使い、ノイズを生成する。
// https://gist.github.com/akella/330b3caec2b68bb7f4534dae5918c0e9
mat2 rot2d (in float angle) {
return mat2(cos(angle), -sin(angle), sin(angle), cos(angle));
}
float r (in float a, in float b) { return fract(sin(dot(vec2(a,b),vec2(12.9898,78.233)))*43758.5453); }
float h (in float a) { return fract(sin(dot(a,dot(12.9898,78.233)))*43758.5453); }
float noise (in vec3 x) {
vec3 p = floor(x);
vec3 f = fract(x);
f = f*f*(3.0-2.0*f);
float n = p.x + p.y*57.0 + 113.0*p.z;
return mix(mix(mix( h(n+0.0), h(n+1.0),f.x),
mix( h(n+57.0), h(n+58.0),f.x),f.y),
mix(mix( h(n+113.0), h(n+114.0),f.x),
mix( h(n+170.0), h(n+171.0),f.x),f.y),f.z);
}
// http://www.iquilezles.org/www/articles/morenoise/morenoise.htm
// http://www.pouet.net/topic.php?post=401468
vec3 dnoise2f (in vec2 p) {
float i = floor(p.x), j = floor(p.y);
float u = p.x-i, v = p.y-j;
float du = 30.*u*u*(u*(u-2.)+1.);
float dv = 30.*v*v*(v*(v-2.)+1.);
u=u*u*u*(u*(u*6.-15.)+10.);
v=v*v*v*(v*(v*6.-15.)+10.);
float a = r(i, j );
float b = r(i+1.0, j );
float c = r(i, j+1.0);
float d = r(i+1.0, j+1.0);
float k0 = a;
float k1 = b-a;
float k2 = c-a;
float k3 = a-b-c+d;
return vec3(k0 + k1*u + k2*v + k3*u*v,
du*(k1 + k3*v),
dv*(k2 + k3*u));
}
float fbm (in vec2 uv) {
vec2 p = uv;
float f, dx, dz, w = 0.5;
f = dx = dz = 0.0;
for(int i = 0; i < 3; ++i){
vec3 n = dnoise2f(uv);
dx += n.y;
dz += n.z;
f += w * n.x / (1.0 + dx*dx + dz*dz);
w *= 0.86;
uv *= vec2(1.36);
uv *= rot2d(1.25 * noise(vec3(p * 0.1, 0.12 * time)) +
0.75 * noise(vec3(p * 0.1, 0.20 * time)));
}
return f;
}
float fbmLow (in vec2 uv) {
float f, dx, dz, w = 0.5;
f = dx = dz = 0.0;
for(int i = 0; i < 3; ++i){
vec3 n = dnoise2f(uv);
dx += n.y;
dz += n.z;
f += w * n.x / (1.0 + dx*dx + dz*dz);
w *= 0.95;
uv *= vec2(3);
}
return f;
}
// ノイズここまで
// circle関数
// 円を作成する。
float circle(vec2 uv, float radius, float sharp) {
// 円の位置を中心にする。
vec2 tempUV = uv - vec2(0.5);
// sharp(輪郭)に半径を乗算したものを半径から減算したもの(x)と、
// sharp(輪郭)に半径を乗算したものに半径を加算したもの(y)の値を、
// dotに渡したtempUVの値で線形補間する。
// 最終的に求められた値を1.0から引くことによって、円の内側に動画が表示されるようになる。(逆に1.0から引かないと、円の外側に動画が表示される)
return 1.0 - smoothstep(
radius - radius * sharp,
radius + radius * sharp,
dot(tempUV, tempUV) * 4.0
);
}
void main() {
// 動画のアスペクト比(幅 / 高さ)
float videoAspect = 1280.0 / 720.0;
// 画面のアスペクト比(幅 / 高さ)
float screenAspect = uViewport.x / uViewport.y;
vec2 multiplier = vec2(1.0);
// 動画の位置を中心にする。
vec2 centerVector = vUv - vec2(0.5);
// 動画のアスペクト比が画面のアスペクト比よりも大きかったら、
// multiplierのxに"画面のアスペクト比 / 動画のアスペクト比"を渡す。
if(videoAspect > screenAspect) {
multiplier = vec2(screenAspect / videoAspect, 1.0);
}
// centerVectorにmultiplierを乗算し、それに0.5を加算したものをnewUVとする。
vec2 newUV = centerVector * multiplier + vec2(0.5);
// ripple.........完整代码请登录后点击上方下载按钮下载查看
网友评论0