多视角3D逼真HTML5水波动画

我发现我好像变了,原来每当人成长的时候都会改变。生命本该有意义,我们绝不是白来一场。

这是一款基于HTML5的3D水波动画特效,它的效果非常逼真,我们可以按“G”键来让水池中的石头上下浮动,按“L”键添加灯光效果,设计相当完美。同时说明一下,这款3D水波动画是基于WebGL渲染技术的,大家可以了解一下WebGL。

在线预览 源码下载

HTML代码

XML/HTML Code复制内容到剪贴板
  1. <imgid="tiles"src="tiles.jpg">
  2. <imgid="xneg"src="xneg.jpg">
  3. <imgid="xpos"src="xpos.jpg">
  4. <imgid="ypos"src="ypos.jpg">
  5. <imgid="zneg"src="zneg.jpg">
  6. <imgid="zpos"src="zpos.jpg">

JavaScript代码

JavaScript Code复制内容到剪贴板
  1. functionWater(){
  2. varvertexShader='\
  3. varyingvec2coord;\
  4. voidmain(){\
  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. thrownewError('ThisdemorequirestheOES_texture_floatextension');
  12. }
  13. varfilter=GL.Texture.canUseFloatingPointLinearFiltering()?gl.LINEAR:gl.NEAREST;
  14. this.textureA=newGL.Texture(256,256,{type:gl.FLOAT,filter:filter});
  15. this.textureB=newGL.Texture(256,256,{type:gl.FLOAT,filter:filter});
  16. this.dropShader=newGL.Shader(vertexShader,'\
  17. constfloatPI=3.141592653589793;\
  18. uniformsampler2Dtexture;\
  19. uniformvec2center;\
  20. uniformfloatradius;\
  21. uniformfloatstrength;\
  22. varyingvec2coord;\
  23. voidmain(){\
  24. /*getvertexinfo*/\
  25. vec4info=texture2D(texture,coord);\
  26. \
  27. /*addthedroptotheheight*/\
  28. floatdrop=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=newGL.Shader(vertexShader,'\
  36. uniformsampler2Dtexture;\
  37. uniformvec2delta;\
  38. varyingvec2coord;\
  39. voidmain(){\
  40. /*getvertexinfo*/\
  41. vec4info=texture2D(texture,coord);\
  42. \
  43. /*calculateaverageneighborheight*/\
  44. vec2dx=vec2(delta.x,0.0);\
  45. vec2dy=vec2(0.0,delta.y);\
  46. floataverage=(\
  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. /*changethevelocitytomovetowardtheaverage*/\
  54. info.g+=(average-info.r)*2.0;\
  55. \
  56. /*attenuatethevelocityalittlesowavesdonotlastforever*/\
  57. info.g*=0.995;\
  58. \
  59. /*movethevertexalongthevelocity*/\
  60. info.r+=info.g;\
  61. \
  62. gl_FragColor=info;\
  63. }\
  64. ');
  65. this.normalShader=newGL.Shader(vertexShader,'\
  66. uniformsampler2Dtexture;\
  67. uniformvec2delta;\
  68. varyingvec2coord;\
  69. voidmain(){\
  70. /*getvertexinfo*/\
  71. vec4info=texture2D(texture,coord);\
  72. \
  73. /*updatethenormal*/\
  74. vec3dx=vec3(delta.x,texture2D(texture,vec2(coord.x+delta.x,coord.y)).r-info.r,0.0);\
  75. vec3dy=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=newGL.Shader(vertexShader,'\
  82. uniformsampler2Dtexture;\
  83. uniformvec3oldCenter;\
  84. uniformvec3newCenter;\
  85. uniformfloatradius;\
  86. varyingvec2coord;\
  87. \
  88. floatvolumeInSphere(vec3center){\
  89. vec3toCenter=vec3(coord.x*2.0-1.0,0.0,coord.y*2.0-1.0)-center;\
  90. floatt=length(toCenter)/radius;\
  91. floatdy=exp(-pow(t*1.5,6.0));\
  92. floatymin=min(0.0,center.y-dy);\
  93. floatymax=min(max(0.0,center.y+dy),ymin+2.0*dy);\
  94. return(ymax-ymin)*0.1;\
  95. }\
  96. \
  97. voidmain(){\
  98. /*getvertexinfo*/\
  99. vec4info=texture2D(texture,coord);\
  100. \
  101. /*addtheoldvolume*/\
  102. info.r+=volumeInSphere(oldCenter);\
  103. \
  104. /*subtractthenewvolume*/\
  105. info.r-=volumeInSphere(newCenter);\
  106. \
  107. gl_FragColor=info;\
  108. }\
  109. ');
  110. }
  111. Water.prototype.addDrop=function(x,y,radius,strength){
  112. varthis_=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. varthis_=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. varthis_=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. varthis_=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. };

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

标签: