热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

多视角3D逼真HTML5水波动画_html5教程技巧

这篇文章主要介绍了多视角3D逼真HTML5水波动画,它的效果非常逼真,水池中的石头在水中沉浮,泛起了一层层水波。同时我们可以拖拽鼠标从不同的视角来浏览水池,3D效果非常不错,感兴趣的小伙伴们可以参考一下
这是一款基于HTML5的3D水波动画特效,它的效果非常逼真,我们可以按“G”键来让水池中的石头上下浮动,按“L”键添加灯光效果,设计相当完美。同时说明一下,这款3D水波动画是基于WebGL渲染技术的,大家可以了解一下WebGL。

在线预览 源码下载

HTML代码

XML/HTML Code复制内容到剪贴板

  1. <img id="tiles" 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 Code复制内容到剪贴板

  1. function Water() {
  2. var vertexShader = '\
  3. varying vec2 coord;\
  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('This demo requires the OES_texture_float extension');
  12. }
  13. var filter = GL.Texture.canUseFloatingPointLinearFiltering() ? gl.LINEAR : gl.NEAREST;
  14. this.textureA = new GL.Texture(256, 256, { type: gl.FLOAT, filter: filter });
  15. this.textureB = new GL.Texture(256, 256, { type: gl.FLOAT, filter: filter });
  16. this.dropShader = new GL.Shader(vertexShader, '\
  17. const float PI = 3.141592653589793;\
  18. uniform sampler2D texture;\
  19. uniform vec2 center;\
  20. uniform float radius;\
  21. uniform float strength;\
  22. varying vec2 coord;\
  23. void main() {\
  24. /* get vertex info */\
  25. vec4 info = texture2D(texture, coord);\
  26. \
  27. /* add the drop to the height */\
  28. float drop = max(0.0, 1.0 - length(center * 0.5 + 0.5 - coord) / radius);\
  29. drop = 0.5 - cos(drop * PI) * 0.5;\
  30. info.r += drop * strength;\
  31. \
  32. gl_FragColor = info;\
  33. }\
  34. ');
  35. this.updateShader = new GL.Shader(vertexShader, '\
  36. uniform sampler2D texture;\
  37. uniform vec2 delta;\
  38. varying vec2 coord;\
  39. void main() {\
  40. /* get vertex info */\
  41. vec4 info = texture2D(texture, coord);\
  42. \
  43. /* calculate average neighbor height */\
  44. vec2 dx = vec2(delta.x, 0.0);\
  45. vec2 dy = vec2(0.0, delta.y);\
  46. float average = (\
  47. texture2D(texture, coord - dx).r +\
  48. texture2D(texture, coord - dy).r +\
  49. texture2D(texture, coord + dx).r +\
  50. texture2D(texture, coord + dy).r\
  51. ) * 0.25;\
  52. \
  53. /* change the velocity to move toward the average */\
  54. info.g += (average - info.r) * 2.0;\
  55. \
  56. /* attenuate the velocity a little so waves do not last forever */\
  57. info.g *= 0.995;\
  58. \
  59. /* move the vertex along the velocity */\
  60. info.r += info.g;\
  61. \
  62. gl_FragColor = info;\
  63. }\
  64. ');
  65. this.normalShader = new GL.Shader(vertexShader, '\
  66. uniform sampler2D texture;\
  67. uniform vec2 delta;\
  68. varying vec2 coord;\
  69. void main() {\
  70. /* get vertex info */\
  71. vec4 info = texture2D(texture, coord);\
  72. \
  73. /* update the normal */\
  74. vec3 dx = vec3(delta.x, texture2D(texture, vec2(coord.x + delta.x, coord.y)).r - info.r, 0.0);\
  75. vec3 dy = vec3(0.0, texture2D(texture, vec2(coord.x, coord.y + delta.y)).r - info.r, delta.y);\
  76. info.ba = normalize(cross(dy, dx)).xz;\
  77. \
  78. gl_FragColor = info;\
  79. }\
  80. ');
  81. this.sphereShader = new GL.Shader(vertexShader, '\
  82. uniform sampler2D texture;\
  83. uniform vec3 oldCenter;\
  84. uniform vec3 newCenter;\
  85. uniform float radius;\
  86. varying vec2 coord;\
  87. \
  88. float volumeInSphere(vec3 center) {\
  89. vec3 toCenter = vec3(coord.x * 2.0 - 1.0, 0.0, coord.y * 2.0 - 1.0) - center;\
  90. float t = length(toCenter) / radius;\
  91. float dy = exp(-pow(t * 1.5, 6.0));\
  92. float ymin = min(0.0, center.y - dy);\
  93. float ymax = min(max(0.0, center.y + dy), ymin + 2.0 * dy);\
  94. return (ymax - ymin) * 0.1;\
  95. }\
  96. \
  97. void main() {\
  98. /* get vertex info */\
  99. vec4 info = texture2D(texture, coord);\
  100. \
  101. /* add the old volume */\
  102. info.r += volumeInSphere(oldCenter);\
  103. \
  104. /* subtract the new volume */\
  105. info.r -= volumeInSphere(newCenter);\
  106. \
  107. gl_FragColor = info;\
  108. }\
  109. ');
  110. }
  111. Water.prototype.addDrop = function(x, y, radius, strength) {
  112. var this_ = this;
  113. this.textureB.drawTo(function() {
  114. this_.textureA.bind();
  115. this_.dropShader.uniforms({
  116. center: [x, y],
  117. radius: radius,
  118. strength: strength
  119. }).draw(this_.plane);
  120. });
  121. this.textureB.swapWith(this.textureA);
  122. };
  123. Water.prototype.moveSphere = function(oldCenter, newCenter, radius) {
  124. var this_ = this;
  125. this.textureB.drawTo(function() {
  126. this_.textureA.bind();
  127. this_.sphereShader.uniforms({
  128. oldCenter: oldCenter,
  129. newCenter: newCenter,
  130. radius: radius
  131. }).draw(this_.plane);
  132. });
  133. this.textureB.swapWith(this.textureA);
  134. };
  135. Water.prototype.stepSimulation = function() {
  136. var this_ = this;
  137. this.textureB.drawTo(function() {
  138. this_.textureA.bind();
  139. this_.updateShader.uniforms({
  140. delta: [1 / this_.textureA.width, 1 / this_.textureA.height]
  141. }).draw(this_.plane);
  142. });
  143. this.textureB.swapWith(this.textureA);
  144. };
  145. Water.prototype.updateNormals = function() {
  146. var this_ = this;
  147. this.textureB.drawTo(function() {
  148. this_.textureA.bind();
  149. this_.normalShader.uniforms({
  150. delta: [1 / this_.textureA.width, 1 / this_.textureA.height]
  151. }).draw(this_.plane);
  152. });
  153. this.textureB.swapWith(this.textureA);
  154. };

以上就是本文的全部内容,希望对大家的学习有所帮助。

推荐阅读
  • 表单提交前的最后验证:通常在表单提交前,我们必须确认用户是否都把必须填选的做了,如果没有,就不能被提交到服务器,这里我们用到表单的formname.submit()看演示,其实这个对于我们修炼道 ... [详细]
  • 但有时候,需要当某事件触发时,我们先做一些操作,然后再跳转,这时,就要用JAVASCRIPT来实现这一跳转功能。下面是具体的做法:一:跳转到新页面,并且是在新窗口中打开时:复制代码代码如下:fu ... [详细]
  • JavaScript在常人看来都是门出不了厅堂的小语言,仅管它没有明星语言的闪耀,但至少网页的闪耀还是需要它的,同时它是一门很实用的语言,本人平时就喜欢拿它来写点实用工具或应用,本文演示用JavaSc ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 本文介绍了使用AJAX的POST请求实现数据修改功能的方法。通过ajax-post技术,可以实现在输入某个id后,通过ajax技术调用post.jsp修改具有该id记录的姓名的值。文章还提到了AJAX的概念和作用,以及使用async参数和open()方法的注意事项。同时强调了不推荐使用async=false的情况,并解释了JavaScript等待服务器响应的机制。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文讨论了Alink回归预测的不完善问题,指出目前主要针对Python做案例,对其他语言支持不足。同时介绍了pom.xml文件的基本结构和使用方法,以及Maven的相关知识。最后,对Alink回归预测的未来发展提出了期待。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文介绍了在SpringBoot中集成thymeleaf前端模版的配置步骤,包括在application.properties配置文件中添加thymeleaf的配置信息,引入thymeleaf的jar包,以及创建PageController并添加index方法。 ... [详细]
  • Java验证码——kaptcha的使用配置及样式
    本文介绍了如何使用kaptcha库来实现Java验证码的配置和样式设置,包括pom.xml的依赖配置和web.xml中servlet的配置。 ... [详细]
  • 本文介绍了使用cacti监控mssql 2005运行资源情况的操作步骤,包括安装必要的工具和驱动,测试mssql的连接,配置监控脚本等。通过php连接mssql来获取SQL 2005性能计算器的值,实现对mssql的监控。详细的操作步骤和代码请参考附件。 ... [详细]
  • iOS超签签名服务器搭建及其优劣势
    本文介绍了搭建iOS超签签名服务器的原因和优势,包括不掉签、用户可以直接安装不需要信任、体验好等。同时也提到了超签的劣势,即一个证书只能安装100个,成本较高。文章还详细介绍了超签的实现原理,包括用户请求服务器安装mobileconfig文件、服务器调用苹果接口添加udid等步骤。最后,还提到了生成mobileconfig文件和导出AppleWorldwideDeveloperRelationsCertificationAuthority证书的方法。 ... [详细]
  • Itwasworkingcorrectly,butyesterdayitstartedgiving401.IhavetriedwithGooglecontactsAPI ... [详细]
  • 用JavaScript实现的太空人手表
    用JavaScript实现的太空人手表-JS写的太空人手表,没有用canvas、svg。主要用几个大的函数来动态显示时间、天气这些。天气的获取用到了AJAX请求。代码中有详细的注释 ... [详细]
  • Iwouldliketobeabletohaveasidebarthatcanbetoggledinandoutonabuttonpress.However ... [详细]
author-avatar
WSSDRED_935
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有