Ini ialah kesan khas animasi gelombang air 3D berdasarkan HTML5 Kesannya sangat realistik. Kita boleh menekan kekunci "G" untuk membuat batu dalam kolam terapung ke atas dan ke bawah, dan tekan kekunci "L" untuk. tambah kesan pencahayaan Reka bentuknya cukup sempurna. Pada masa yang sama, sila ambil perhatian bahawa animasi gelombang air 3D ini adalah berdasarkan teknologi pemaparan WebGL Anda boleh belajar tentang WebGL.
Kod XML/HTMLSalin kandungan ke papan keratan
-
<img id="jubin" src="tiles.jpg">
-
<img id="xneg" src="xneg.jpg">
-
<img id="xpos" src="xpos.jpg">
-
<img id="ypos" src="ypos.jpg">
-
<img id="zneg" src="zneg.jpg">
-
<img id="zpos" src="zpos.jpg">
-
Kod JavaScriptSalin kandungan ke papan keratan
-
fungsi Air() {
-
var vertexShader = '
-
pelbagai vec2 coord;
-
kosong utama() {
-
coord = gl_Vertex.xy * 0.5 0.5;
-
gl_Position = vec4(gl_Vertex.xyz, 1.0);
-
}
-
';
-
ini.plane = GL.Mesh.plane();
-
jika (!GL.Texture.canUseFloatingPointTextures()) {
-
buang baharu Ralat('Demo ini memerlukan tegangan_baharu >);
-
}
-
var penapis = GL.Texture.canUseFloatingPointLinearFiltering() ? gl.LINEAR : gl.NEAREST;
-
ini.textureA = baharu GL.Tekstur(256, 256, { jenis: gl.FLOAT, penapis: penapis });
-
ini.textureB = baharu GL.Tekstur(256, 256, { jenis: gl.FLOAT, penapis: penapis });
-
ini.dropShader = baharu GL.Shader(vertexShader, ' ' >
-
const float PI = 3.141592653589793;
-
tekstur sampler2D seragam;
-
pusat seragam vec2;
-
jejari apungan seragam;
-
kekuatan apungan seragam;
-
pelbagai vec2 coord;
-
kosong utama() {
-
/* dapatkan maklumat puncak */
-
vec4 info = texture2D(texture, coord);
-
-
/* tambahkan kejatuhan ke ketinggian */
-
float drop = maks(0.0, 1.0 - panjang(tengah * 0.5 0.5 - coord) / radius);
-
turun = 0.5 - kos(turun * PI) * 0.5;
-
info.r = jatuhkan * kekuatan;
-
-
gl_FragColor = maklumat;
-
}
-
');
-
ini.updateShader = baharu GL.Shader(vertexShader, ' ' >
-
tekstur sampler2D seragam;
-
seragam vec2 delta;
-
pelbagai vec2 coord;
-
kosong utama() {
-
/* dapatkan maklumat puncak */
-
vec4 info = texture2D(texture, coord);
-
-
/* kira purata tinggi jiran */
-
vec2 dx = vec2(delta.x, 0.0);
-
vec2 dy = vec2(0.0, delta.y);
-
purata terapung = (
-
tekstur2D(tekstur, coord - dx).r
-
texture2D(tekstur, coord - dy).r
-
tekstur2D(tekstur, coord dx).r
-
texture2D(tekstur, coord dy).r
-
) * 0.25;
-
-
/* tukar halaju untuk bergerak ke arah purata */
-
info.g = (purata - info.r) * 2.0;
-
-
/* melemahkan halaju sedikit sehingga gelombang tidak berkekalan selama-lamanya */
-
info.g *= 0.995;
-
-
/* gerakkan pucuk sepanjang halaju */
-
info.r = info.g;
-
-
gl_FragColor = maklumat;
-
}
-
');
-
ini.normalShader = baharu GL.Shader(vertexShader, ' ' >
-
tekstur sampler2D seragam;
-
seragam vec2 delta;
-
pelbagai vec2 coord;
-
kosong utama() {
-
/* dapatkan maklumat puncak */
-
vec4 info = texture2D(texture, coord);
-
-
/* kemas kini biasa */
-
vec3 dx = vec3(delta.x, texture2D(texture, vec2(coord.x delta.x, coord.y)).r - info.r, 0.0);
-
vec3 dy = vec3(0.0, texture2D(texture, vec2(coord.x, coord.y delta.y)).r - info.r, delta.y);
-
info.ba = normalize(cross(dy, dx)).xz;
-
-
gl_FragColor = maklumat;
-
}
-
');
-
ini.sphereShader = baharu GL.Shader(vertexShader, ' ' >
-
tekstur sampler2D seragam;
-
seragam vec3 oldCenter;
-
uniform vec3 newCenter;
-
jejari apungan seragam;
-
pelbagai vec2 coord;
-
-
float volumeInSphere(vec3 center) {
-
vec3 toCenter = vec3(coord.x * 2.0 - 1.0, 0.0, coord.y * 2.0 - 1.0) - center;
-
terapung t = panjang(kePusat) / jejari;
-
float dy = exp(-pow(t * 1.5, 6.0));
-
terapung ymin = min(0.0, center.y - dy);
-
float ymax = min(maks(0.0, center.y dy), ymin 2.0 * dy);
-
pulangan (ymax - ymin) * 0.1;
-
}
-
-
kosong utama() {
-
/* dapatkan maklumat puncak */
-
vec4 info = texture2D(texture, coord);
-
-
/* tambah volum lama */
-
info.r = volumeInSphere(oldCenter);
-
-
/* tolak jumlah baharu */
-
info.r -= volumeInSphere(newCenter);
-
-
gl_FragColor = maklumat;
-
}
-
');
-
}
-
-
Water.prototype.addDrop = fungsi(x, y, jejari, kekuatan) {
-
var ini_ = ini;
-
ini.textureB.drawTo(fungsi() {
-
this_.textureA.bind();
-
this_.dropShader.uniforms({
-
pusat: [x, y],
-
jejari: jejari,
-
kekuatan: kekuatan
-
}).draw(this_.plane);
-
});
-
ini.textureB.swapWith(ini.textureA);
-
};
-
-
Water.prototype.moveSphere = fungsi(oldCenter, newCenter, radius) {
-
var ini_ = ini;
-
ini.textureB.drawTo(fungsi() {
-
this_.textureA.bind();
-
this_.sphereShader.uniforms({
-
oldCenter: oldCenter,
-
Pusat baharu: Pusat baharu,
-
jejari: jejari
-
}).draw(this_.plane);
-
});
-
ini.textureB.swapWith(ini.textureA);
-
};
-
-
Water.prototype.stepSimulation = fungsi() {
-
var ini_ = ini;
-
ini.textureB.drawTo(fungsi() {
-
this_.textureA.bind();
-
this_.updateShader.uniforms({
-
delta: [1 / this_.textureA.width, 1 / this_.textureA.height]
-
}).draw(this_.plane);
-
});
-
ini.textureB.swapWith(ini.textureA);
-
};
-
-
Water.prototype.updateNormals = fungsi() {
-
var ini_ = ini;
-
ini.textureB.drawTo(fungsi() {
-
this_.textureA.bind();
-
ini_.normalShader.uniforms({
-
delta: [1 / this_.textureA.width, 1 / this_.textureA.height]
-
}).draw(this_.plane);
-
});
-
ini.textureB.swapWith(ini.textureA);
-
};