ホームページ >ウェブフロントエンド >H5 チュートリアル >多視点 3D リアルな HTML5 水波アニメーション _html5 チュートリアル スキル

多視点 3D リアルな HTML5 水波アニメーション _html5 チュートリアル スキル

WBOY
WBOYオリジナル
2016-05-16 15:45:382088ブラウズ

これは HTML5 に基づいた 3D 水の波のアニメーション特殊効果で、「G」キーを押すとプール内の石が上下に浮かび上がり、「L」キーを押すと非常にリアルになります。照明効果を追加すると、デザインが非常に完璧になります。同時に、この 3D 水の波のアニメーションは WebGL レンダリング技術に基づいていることに注意してください。WebGL について学ぶことができます。

オンライン プレビュー ソース コードのダウンロード

HTML コード

XML/HTML コードコンテンツをクリップボードにコピー
  1. <img id="タイル" src="tiles.jpg">
  2. <img id="xneg" src="xneg.jpg">
  3. <img id="xpos" src="xpos.jpg">
  4. <img id="ypos" src="ypos.jpg">
  5. <img id="zneg" src="zneg.jpg">
  6. <img id="zpos" src="zpos.jpg">

JavaScript コード

JavaScript コードコンテンツをクリップボードにコピーします
  1. 関数 Water() {
  2. var vertexShader = '
  3. さまざまな vec2 座標;
  4. void main() {
  5. coord = gl_Vertex.xy * 0.5 0.5;
  6. gl_Position = vec4(gl_Vertex.xyz, 1.0);
  7. }
  8. ';   
  9. this.plane = GL.Mesh.plane();   
  10. if (!GL.Texture.canUseFloatingPointTextures()) {
  11. throw new Error('このデモには OES_texture_float 拡張機能が必要です');   
  12. }
  13. var filter = GL.Texture.canUseFloatingPointLinearFiltering() ? gl.LINEAR : gl.NEAREST;   
  14. this.textureA = new GL.Texture(256, 256, { type: gl.FLOAT,フィルター: フィルター });   
  15. this.textureB = 新しい GL.Texture(256, 256, { type: gl.FLOAT,フィルター: フィルター });   
  16. this.dropShader = new GL.Shader(vertexShader, '
  17. const float PI = 3.141592653589793;
  18. 均一なサンプラー 2D テクスチャ。
  19. ユニフォーム vec2 センター;
  20. 均一なフロート半径。
  21. 均一なフロート強度。
  22. さまざまな vec2 座標;
  23. void main() {
  24. /* 頂点情報を取得 */
  25. vec4 info = texture2D(テクスチャ, 座標);
  26. /* ドロップを 高さ に追加します */
  27. float drop = max(0.0, 1.0 - length(center * 0.5 0.5 - coord) / radius);
  28. drop = 0.5 - cos(drop * PI) * 0.5;
  29. info.r = ドロップ * 強度;
  30. gl_FragColor = 情報;
  31. }
  32. ');   
  33. this.updateShader = new GL.Shader(vertexShader, '
  34. 均一なサンプラー 2D テクスチャ。
  35. uniform vec2 delta;
  36. さまざまな vec2 座標;
  37. void main() {
  38. /* 頂点情報を取得 */
  39. vec4 info = texture2D(テクスチャ, 座標);
  40. /* 平均近隣身長を計算する */
  41. vec2 dx = vec2(delta.x, 0.0);
  42. vec2 dy = vec2(0.0, delta.y);
  43. 浮動小数点平均 = (
  44. texture2D(texture, coord - dx).r
  45. texture2D(texture, coord - dy).r
  46. texture2D(texture, coord dx).r
  47. texture2D(texture, coord dy).r
  48. ) * 0.25;
  49. /* 速度を変更して 平均に向けて移動します */
  50. info.g = (平均 - info.r) * 2.0;
  51. /* 波が永久に続かないように速度を少し減衰させます */
  52. info.g *= 0.995;
  53. /* 速度に沿って頂点を移動します */
  54. info.r = info.g;
  55. gl_FragColor = 情報;
  56. }
  57. ');   
  58. this.normalShader = new GL.Shader(vertexShader, '
  59. 均一なサンプラー 2D テクスチャ。
  60. uniform vec2 delta;
  61. さまざまな vec2 座標;
  62. void main() {
  63. /* 頂点情報を取得 */
  64. vec4 info = texture2D(テクスチャ, 座標);
  65. /* 通常の更新 */
  66. vec3 dx = vec3(delta.x, texture2D(texture, vec2(coord.x delta.x, coord.y)).r - info.r, 0.0);
  67. vec3 dy = vec3(0.0, texture2D(texture, vec2(coord.x, coord.y delta.y)).r - info.r, delta.y);
  68. info.ba = normalize(cross(dy, dx)).xz;
  69. gl_FragColor = 情報;
  70. }
  71. ');   
  72. this.sphereShader = 新しい GL.Shader(vertexShader, '
  73. 均一なサンプラー 2D テクスチャ。
  74. uniform vec3 oldCenter;
  75. uniform vec3 newCenter;
  76. 均一なフロート半径。
  77. さまざまな vec2 座標;
  78. float volumeInSphere(vec3 center) {
  79. vec3 toCenter = vec3(coord.x * 2.0 - 1.0, 0.0, coord.y * 2.0 - 1.0) - center;
  80. float t = length(toCenter) / radius;
  81. float dy = exp(-pow(t * 1.5, 6.0));
  82. float ymin = min(0.0, center.y - dy);
  83. float ymax = min(max(0.0, center.y dy), ymin 2.0 * dy);
  84. return (ymax - ymin) * 0.1;
  85. }
  86. void main() {
  87. /* 頂点情報を取得 */
  88. vec4 info = texture2D(テクスチャ, 座標);
  89. /* 古いボリュームを追加 */
  90. info.r = volumeInSphere(oldCenter);
  91. /* 新しい ボリュームを減算 */
  92. info.r -= volumeInSphere(newCenter);
  93. gl_FragColor = 情報;
  94. }
  95. ');   
  96. }
  97. Water.prototype.addDrop = 関数(x, y, 半径, 強度) {
  98. var this_ = this;   
  99. this.textureB.drawTo(function() {
  100. this_.textureA.bind();   
  101. this_.dropShader.uniforms({
  102. センター: [x, y],
  103. 半径: 半径、
  104. 強度: 強度
  105. }).draw(this_.plane);   
  106. });   
  107. this.textureB.swapWith(this.textureA);   
  108. };   
  109. Water.prototype.moveSphere = 関数(oldCenter, newCenter, radius) {
  110. var this_ = this;   
  111. this.textureB.drawTo(function() {
  112. this_.textureA.bind();   
  113. this_.sphereShader.uniforms({
  114. oldCenter: oldCenter,
  115. newCenter: newCenter,
  116. 半径: 半径
  117. }).draw(this_.plane);   
  118. });   
  119. this.textureB.swapWith(this.textureA);   
  120. };   
  121. Water.prototype.stepSimulation = 関数() {
  122. var this_ = this;   
  123. this.textureB.drawTo(function() {
  124. this_.textureA.bind();   
  125. this_.updateShader.uniforms({
  126. デルタ: [1 / this_.textureA.width, 1 / this_.textureA.height]
  127. }).draw(this_.plane);   
  128. });   
  129. this.textureB.swapWith(this.textureA);   
  130. };   
  131. Water.prototype.updateNormals = 関数() {
  132. var this_ = this;   
  133. this.textureB.drawTo(function() {
  134. this_.textureA.bind();   
  135. this_.normalShader.uniforms({
  136. デルタ: [1 / this_.textureA.width, 1 / this_.textureA.height]
  137. }).draw(this_.plane);   
  138. });   
  139. this.textureB.swapWith(this.textureA);   
  140. };   

以上が本書のすべての内容であり、広く学術的に役立つことが期待されます。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。