這是一款基於HTML5的3D水波動畫特效,它的效果非常逼真,我們可以按「G」鍵來讓水池中的石頭上下浮動,按「L」鍵添加燈光效果,設計相當完美。同時說明一下,這款3D水波動畫是基於WebGL渲染技術的,大家可以了解WebGL。
id
=id
=id src="zneg.jpg">
img id=id=id=
" 🎜> src="zpos.jpg">
JavaScript程式碼
JavaScript Code複製內容到剪貼簿
-
函數 水() {
-
var vertexShader = '
-
變化的 vec2 座標;
-
void main() {
-
座標 = gl_Vertex.xy * 0.5 0.5;
-
gl_Position = vec4(gl_Vertex.xyz, 1.0);
-
}
- ';
-
這.plane = GL.Mesh.plane();
-
if (!GL.Texture.canUseFloatingPointTextures()) {
-
拋出 新 >);
}
-
- var filter = GL.Texture.canUseFloatingPointLinearFiltering() ? gl.線性:gl.最近;
這個
- .textureA = 新 GL.Texture(256,Texture(256,I56,過濾器:過濾器});
這個
.textureB = -
新 GL.Texture(256,Texture(256,I56,過濾器:過濾器});
-
這個.dropShader = 新 GL.Shader((Shader), cp >
const float PI = 3.141592653589793; -
統一取樣器二維紋理; -
均勻 vec2 中心; -
統一浮動半徑; -
均勻的漂浮強度; -
變化的 vec2 座標; -
void main() { -
/* 取得頂點資訊*/ -
vec4 info = texture2D(紋理, 座標); -
-
/* 將水滴加到高度*/ -
浮點數 = max(0.0, 1.0 - 長度(中心 * 0.5 0.5 - 座標)/半徑); -
drop = 0.5 - cos(drop * PI) * 0.5; -
info.r = 掉落 * 肌力; -
-
gl_FragColor = 資訊; -
}
- ');
-
這個.updateShader = 新 GL.Shader( >
統一取樣器二維紋理; -
統一 vec2 delta; -
變化的 vec2 座標; -
void main() { -
/* 取得頂點資訊*/ -
vec4 info = texture2D(紋理, 座標); -
-
/* 計算鄰居平均身高*/ -
vec2 dx = vec2(delta.x, 0.0); -
vec2 dy = vec2(0.0, delta.y); -
浮動平均值= ( -
texture2D(紋理, 座標 - dx).r -
texture2D(紋理, 座標 - dy).r -
texture2D(紋理, 座標 dx).r -
texture2D(紋理, 座標 dy).r -
) * 0.25; -
-
/* 改變速率以朝向平均值移動*/ -
info.g = (平均值 - info.r) * 2.0; -
-
/*稍微減弱速度,因此波浪不會永遠持續*/ -
info.g *= 0.995; -
-
/* 沿速度移動頂點*/ -
info.r = info.g; -
-
gl_FragColor = 資訊; -
}
- ');
-
這個.normalShader = 新 GL.Shader((Shader) >
統一取樣器二維紋理; -
統一 vec2 delta; -
變化的 vec2 座標; -
void main() { -
/* 取得頂點資訊*/ -
vec4 info = texture2D(紋理, 座標); -
-
/* 更新正常*/ -
vec3 dx = vec3(delta.x, texture2D(texture, vec2(coord.x dx delta.x, coord.y)).info 🎜> -
vec3 dy = vec3(0.0, texture2D(texture, vec2(coord.x, coord.y texture2D(texture, vec2(coord.x, coord.y ),
-
info.ba = 歸一化(cross(dy, dx)).xz;
-
-
gl_FragColor = 資訊;
-
}
- ');
-
這個.sphereShader =
- 新 GL.Shader(vert( >
統一取樣器二維紋理;
統一 vec3 oldCenter;
-
uniform vec3 newCenter;
-
統一浮動半徑;
-
變化的 vec2 座標;
-
-
float volumeInSphere(vec3 center) {
-
vec3 toCenter = vec3(coord.x * 2.0 - 1.0, 0.0, coord.y * 2.0 - 1.0) - center;
-
float t = 長度(至中心)/ 半徑;
-
float dy = exp(-pow(t * 1.5, 6.0));
-
float ymin = min(0.0, center.y - dy);
-
float ymax = min(max(0.0, center.y dy), ymin 2.0 *作用
-
返回(ymax - ymin)* 0.1;
-
}
-
-
void main() {
-
/* 取得頂點資訊*/
-
vec4 info = texture2D(紋理, 座標);
-
-
/* 新增舊卷*/
-
info.r = volumeInSphere(oldCenter);
-
-
/* 減去新卷*/
-
info.r -= volumeInSphere(newCenter);
-
-
gl_FragColor = 資訊;
-
}
- ');
-
}
-
-
Water.prototype.addDrop = 函數(x, y, 半徑, 強度) {
-
var 這個_ = 這個; 🎜>這個
- ; 🎠 這個.textureB.drawTo(函數
().
-
this_.textureA.bind();
-
this_.dropShader.uniforms({
-
中心:[x, y],
-
半徑:半徑,
-
強度: 強度
-
}).draw(this_.plane);
-
});
-
這個.textureB.swapWith(這個.textureA);
}; -
-
Water.prototype.moveSphere = -
函數(oldCenter, newCenter, 半徑) {
- var 這個_ = 這個; 🎜>這個
; 🎠- 這個.textureB.drawTo(函數().
- this_.textureA.bind();
- this_.sphereShader.uniforms({
- oldCenter:oldCenter,
- 新中心:新中心,
- 半徑:半徑
- }).draw(this_.plane);
- });
- 這個.textureB.swapWith(這個.textureA);
};
-
-
Water.prototype.stepSimulation = 函數() {
-
var 這個_ = 這個; 🎜>這個
- ; 🎠 這個.textureB.drawTo(函數
().
-
this_.textureA.bind();
-
this_.updateShader.uniforms({
-
增量:[1 / this_.textureA.width, 1 / this_.textureA.height]
-
}).draw(this_.plane);
-
});
-
這個.textureB.swapWith(這個.textureA);
}; -
-
Water.prototype.updateNormals = -
函數() {
-
var 這個_ = 這個; 🎜>這個; 🎠
這個.textureB.drawTo(函數().
this_.textureA.bind(); -
this_.normalShader.uniforms({ -
增量:[1 / this_.textureA.width, 1 / this_.textureA.height] -
}).draw(this_.plane); -
}); -
-
這個.textureB.swapWith(這個.textureA);
};
-
以上就是本文的全部內容,希望對大家的學習有所幫助。