当前位置:   article > 正文

分享一个樱花漫天飞舞的html效果_html樱花特效代码

html樱花特效代码

 代码如下

  1. <!doctype html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title>樱花漫天飞舞</title>
  6. </head>
  7. <style>
  8. body {
  9. padding: 0;
  10. margin: 0;
  11. overflow: hidden;
  12. height: 600px;
  13. position: relative;
  14. }
  15. canvas {
  16. padding: 0;
  17. margin: 0;
  18. }
  19. div.btnbg {
  20. position: fixed;
  21. left: 0;
  22. top: 0;
  23. }
  24. .nihao {
  25. position: fixed;
  26. top: 0;
  27. }
  28. .red {
  29. color: red;
  30. }
  31. </style>
  32. <body>
  33. <canvas id="sakura"></canvas>
  34. <script id="sakura_point_vsh" type="x-shader/x_vertex">
  35. uniform mat4 uProjection;
  36. uniform mat4 uModelview;
  37. uniform vec3 uResolution;
  38. uniform vec3 uOffset;
  39. uniform vec3 uDOF; //x:focus distance, y:focus radius, z:max radius
  40. uniform vec3 uFade; //x:start distance, y:half distance, z:near fade start
  41. attribute vec3 aPosition;
  42. attribute vec3 aEuler;
  43. attribute vec2 aMisc; //x:size, y:fade
  44. varying vec3 pposition;
  45. varying float psize;
  46. varying float palpha;
  47. varying float pdist;
  48. //varying mat3 rotMat;
  49. varying vec3 normX;
  50. varying vec3 normY;
  51. varying vec3 normZ;
  52. varying vec3 normal;
  53. varying float diffuse;
  54. varying float specular;
  55. varying float rstop;
  56. varying float distancefade;
  57. void main(void) {
  58. // Projection is based on vertical angle
  59. vec4 pos = uModelview * vec4(aPosition + uOffset, 1.0);
  60. gl_Position = uProjection * pos;
  61. gl_PointSize = aMisc.x * uProjection[1][1] / -pos.z * uResolution.y * 0.5;
  62. pposition = pos.xyz;
  63. psize = aMisc.x;
  64. pdist = length(pos.xyz);
  65. palpha = smoothstep(0.0, 1.0, (pdist - 0.1) / uFade.z);
  66. vec3 elrsn = sin(aEuler);
  67. vec3 elrcs = cos(aEuler);
  68. mat3 rotx = mat3(
  69. 1.0, 0.0, 0.0,
  70. 0.0, elrcs.x, elrsn.x,
  71. 0.0, -elrsn.x, elrcs.x
  72. );
  73. mat3 roty = mat3(
  74. elrcs.y, 0.0, -elrsn.y,
  75. 0.0, 1.0, 0.0,
  76. elrsn.y, 0.0, elrcs.y
  77. );
  78. mat3 rotz = mat3(
  79. elrcs.z, elrsn.z, 0.0,
  80. -elrsn.z, elrcs.z, 0.0,
  81. 0.0, 0.0, 1.0
  82. );
  83. mat3 rotmat = rotx * roty * rotz;
  84. normal = rotmat[2];
  85. mat3 trrotm = mat3(
  86. rotmat[0][0], rotmat[1][0], rotmat[2][0],
  87. rotmat[0][1], rotmat[1][1], rotmat[2][1],
  88. rotmat[0][2], rotmat[1][2], rotmat[2][2]
  89. );
  90. normX = trrotm[0];
  91. normY = trrotm[1];
  92. normZ = trrotm[2];
  93. const vec3 lit = vec3(0.6917144638660746, 0.6917144638660746, -0.20751433915982237);
  94. float tmpdfs = dot(lit, normal);
  95. if(tmpdfs < 0.0) {
  96. normal = -normal;
  97. tmpdfs = dot(lit, normal);
  98. }
  99. diffuse = 0.4 + tmpdfs;
  100. vec3 eyev = normalize(-pos.xyz);
  101. if(dot(eyev, normal) > 0.0) {
  102. vec3 hv = normalize(eyev + lit);
  103. specular = pow(max(dot(hv, normal), 0.0), 20.0);
  104. }
  105. else {
  106. specular = 0.0;
  107. }
  108. rstop = clamp((abs(pdist - uDOF.x) - uDOF.y) / uDOF.z, 0.0, 1.0);
  109. rstop = pow(rstop, 0.5);
  110. //-0.69315 = ln(0.5)
  111. distancefade = min(1.0, exp((uFade.x - pdist) * 0.69315 / uFade.y));
  112. }
  113. </script>
  114. <script id="sakura_point_fsh" type="x-shader/x_fragment">
  115. #ifdef GL_ES
  116. //precision mediump float;
  117. precision highp float;
  118. #endif
  119. uniform vec3 uDOF; //x:focus distance, y:focus radius, z:max radius
  120. uniform vec3 uFade; //x:start distance, y:half distance, z:near fade start
  121. const vec3 fadeCol = vec3(0.08, 0.03, 0.06);
  122. varying vec3 pposition;
  123. varying float psize;
  124. varying float palpha;
  125. varying float pdist;
  126. //varying mat3 rotMat;
  127. varying vec3 normX;
  128. varying vec3 normY;
  129. varying vec3 normZ;
  130. varying vec3 normal;
  131. varying float diffuse;
  132. varying float specular;
  133. varying float rstop;
  134. varying float distancefade;
  135. float ellipse(vec2 p, vec2 o, vec2 r) {
  136. vec2 lp = (p - o) / r;
  137. return length(lp) - 1.0;
  138. }
  139. void main(void) {
  140. vec3 p = vec3(gl_PointCoord - vec2(0.5, 0.5), 0.0) * 2.0;
  141. vec3 d = vec3(0.0, 0.0, -1.0);
  142. float nd = normZ.z; //dot(-normZ, d);
  143. if(abs(nd) < 0.0001) discard;
  144. float np = dot(normZ, p);
  145. vec3 tp = p + d * np / nd;
  146. vec2 coord = vec2(dot(normX, tp), dot(normY, tp));
  147. //angle = 15 degree
  148. const float flwrsn = 0.258819045102521;
  149. const float flwrcs = 0.965925826289068;
  150. mat2 flwrm = mat2(flwrcs, -flwrsn, flwrsn, flwrcs);
  151. vec2 flwrp = vec2(abs(coord.x), coord.y) * flwrm;
  152. float r;
  153. if(flwrp.x < 0.0) {
  154. r = ellipse(flwrp, vec2(0.065, 0.024) * 0.5, vec2(0.36, 0.96) * 0.5);
  155. }
  156. else {
  157. r = ellipse(flwrp, vec2(0.065, 0.024) * 0.5, vec2(0.58, 0.96) * 0.5);
  158. }
  159. if(r > rstop) discard;
  160. vec3 col = mix(vec3(1.0, 0.8, 0.75), vec3(1.0, 0.9, 0.87), r);
  161. float grady = mix(0.0, 1.0, pow(coord.y * 0.5 + 0.5, 0.35));
  162. col *= vec3(1.0, grady, grady);
  163. col *= mix(0.8, 1.0, pow(abs(coord.x), 0.3));
  164. col = col * diffuse + specular;
  165. col = mix(fadeCol, col, distancefade);
  166. float alpha = (rstop > 0.001)? (0.5 - r / (rstop * 2.0)) : 1.0;
  167. alpha = smoothstep(0.0, 1.0, alpha) * palpha;
  168. gl_FragColor = vec4(col * 0.5, alpha);
  169. }
  170. </script>
  171. <!-- effects -->
  172. <script id="fx_common_vsh" type="x-shader/x_vertex">
  173. uniform vec3 uResolution;
  174. attribute vec2 aPosition;
  175. varying vec2 texCoord;
  176. varying vec2 screenCoord;
  177. void main(void) {
  178. gl_Position = vec4(aPosition, 0.0, 1.0);
  179. texCoord = aPosition.xy * 0.5 + vec2(0.5, 0.5);
  180. screenCoord = aPosition.xy * vec2(uResolution.z, 1.0);
  181. }
  182. </script>
  183. <script id="bg_fsh" type="x-shader/x_fragment">
  184. #ifdef GL_ES
  185. //precision mediump float;
  186. precision highp float;
  187. #endif
  188. uniform vec2 uTimes;
  189. varying vec2 texCoord;
  190. varying vec2 screenCoord;
  191. void main(void) {
  192. vec3 col;
  193. float c;
  194. vec2 tmpv = texCoord * vec2(0.8, 1.0) - vec2(0.95, 1.0);
  195. c = exp(-pow(length(tmpv) * 1.8, 2.0));
  196. col = mix(vec3(0.02, 0.0, 0.03), vec3(0.96, 0.98, 1.0) * 1.5, c);
  197. gl_FragColor = vec4(col * 0.5, 1.0);
  198. }
  199. </script>
  200. <script id="fx_brightbuf_fsh" type="x-shader/x_fragment">
  201. #ifdef GL_ES
  202. // precision mediump float;
  203. precision highp float;
  204. #endif
  205. uniform sampler2D uSrc;
  206. uniform vec2 uDelta;
  207. varying vec2 texCoord;
  208. varying vec2 screenCoord;
  209. void main(void) {
  210. vec4 col = texture2D(uSrc, texCoord);
  211. gl_FragColor = vec4(col.rgb * 2.0 - vec3(0.5), 1.0);
  212. }
  213. </script>
  214. <script id="fx_dirblur_r4_fsh" type="x-shader/x_fragment">
  215. #ifdef GL_ES
  216. //precision mediump float;
  217. precision highp float;
  218. #endif
  219. uniform sampler2D uSrc;
  220. uniform vec2 uDelta;
  221. uniform vec4 uBlurDir; //dir(x, y), stride(z, w);
  222. varying vec2 texCoord;
  223. varying vec2 screenCoord;
  224. void main(void) {
  225. vec4 col = texture2D(uSrc, texCoord);
  226. col = col + texture2D(uSrc, texCoord + uBlurDir.xy * uDelta);
  227. col = col + texture2D(uSrc, texCoord - uBlurDir.xy * uDelta);
  228. col = col + texture2D(uSrc, texCoord + (uBlurDir.xy + uBlurDir.zw) * uDelta);
  229. col = col + texture2D(uSrc, texCoord - (uBlurDir.xy + uBlurDir.zw) * uDelta);
  230. gl_FragColor = col / 5.0;
  231. }
  232. </script>
  233. <!-- effect fragment shader template -->
  234. <script id="fx_common_fsh" type="x-shader/x_fragment">
  235. #ifdef GL_ES
  236. //precision mediump float;
  237. precision highp float;
  238. #endif
  239. uniform sampler2D uSrc;
  240. uniform vec2 uDelta;
  241. varying vec2 texCoord;
  242. varying vec2 screenCoord;
  243. void main(void) {
  244. gl_FragColor = texture2D(uSrc, texCoord);
  245. }
  246. </script>
  247. <!-- post processing -->
  248. <script id="pp_final_vsh" type="x-shader/x_vertex">
  249. uniform vec3 uResolution;
  250. attribute vec2 aPosition;
  251. varying vec2 texCoord;
  252. varying vec2 screenCoord;
  253. void main(void) {
  254. gl_Position = vec4(aPosition, 0.0, 1.0);
  255. texCoord = aPosition.xy * 0.5 + vec2(0.5, 0.5);
  256. screenCoord = aPosition.xy * vec2(uResolution.z, 1.0);
  257. }
  258. </script>
  259. <script id="pp_final_fsh" type="x-shader/x_fragment">
  260. #ifdef GL_ES
  261. //precision mediump float;
  262. precision highp float;
  263. #endif
  264. uniform sampler2D uSrc;
  265. uniform sampler2D uBloom;
  266. uniform vec2 uDelta;
  267. varying vec2 texCoord;
  268. varying vec2 screenCoord;
  269. void main(void) {
  270. vec4 srccol = texture2D(uSrc, texCoord) * 2.0;
  271. vec4 bloomcol = texture2D(uBloom, texCoord);
  272. vec4 col;
  273. col = srccol + bloomcol * (vec4(1.0) + srccol);
  274. col *= smoothstep(1.0, 0.0, pow(length((texCoord - vec2(0.5)) * 2.0), 1.2) * 0.5);
  275. col = pow(col, vec4(0.45454545454545)); //(1.0 / 2.2)
  276. gl_FragColor = vec4(col.rgb, 1.0);
  277. gl_FragColor.a = 1.0;
  278. }
  279. </script>
  280. </body>
  281. <script>
  282. var Vector3 = {};
  283. var Matrix44 = {};
  284. Vector3.create = function (x, y, z) {
  285. return {'x': x, 'y': y, 'z': z};
  286. };
  287. Vector3.dot = function (v0, v1) {
  288. return v0.x * v1.x + v0.y * v1.y + v0.z * v1.z;
  289. };
  290. Vector3.cross = function (v, v0, v1) {
  291. v.x = v0.y * v1.z - v0.z * v1.y;
  292. v.y = v0.z * v1.x - v0.x * v1.z;
  293. v.z = v0.x * v1.y - v0.y * v1.x;
  294. };
  295. Vector3.normalize = function (v) {
  296. var l = v.x * v.x + v.y * v.y + v.z * v.z;
  297. if (l > 0.00001) {
  298. l = 1.0 / Math.sqrt(l);
  299. v.x *= l;
  300. v.y *= l;
  301. v.z *= l;
  302. }
  303. };
  304. Vector3.arrayForm = function (v) {
  305. if (v.array) {
  306. v.array[0] = v.x;
  307. v.array[1] = v.y;
  308. v.array[2] = v.z;
  309. } else {
  310. v.array = new Float32Array([v.x, v.y, v.z]);
  311. }
  312. return v.array;
  313. };
  314. Matrix44.createIdentity = function () {
  315. return new Float32Array([1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0]);
  316. };
  317. Matrix44.loadProjection = function (m, aspect, vdeg, near, far) {
  318. var h = near * Math.tan(vdeg * Math.PI / 180.0 * 0.5) * 2.0;
  319. var w = h * aspect;
  320. m[0] = 2.0 * near / w;
  321. m[1] = 0.0;
  322. m[2] = 0.0;
  323. m[3] = 0.0;
  324. m[4] = 0.0;
  325. m[5] = 2.0 * near / h;
  326. m[6] = 0.0;
  327. m[7] = 0.0;
  328. m[8] = 0.0;
  329. m[9] = 0.0;
  330. m[10] = -(far + near) / (far - near);
  331. m[11] = -1.0;
  332. m[12] = 0.0;
  333. m[13] = 0.0;
  334. m[14] = -2.0 * far * near / (far - near);
  335. m[15] = 0.0;
  336. };
  337. Matrix44.loadLookAt = function (m, vpos, vlook, vup) {
  338. var frontv = Vector3.create(vpos.x - vlook.x, vpos.y - vlook.y, vpos.z - vlook.z);
  339. Vector3.normalize(frontv);
  340. var sidev = Vector3.create(1.0, 0.0, 0.0);
  341. Vector3.cross(sidev, vup, frontv);
  342. Vector3.normalize(sidev);
  343. var topv = Vector3.create(1.0, 0.0, 0.0);
  344. Vector3.cross(topv, frontv, sidev);
  345. Vector3.normalize(topv);
  346. m[0] = sidev.x;
  347. m[1] = topv.x;
  348. m[2] = frontv.x;
  349. m[3] = 0.0;
  350. m[4] = sidev.y;
  351. m[5] = topv.y;
  352. m[6] = frontv.y;
  353. m[7] = 0.0;
  354. m[8] = sidev.z;
  355. m[9] = topv.z;
  356. m[10] = frontv.z;
  357. m[11] = 0.0;
  358. m[12] = -(vpos.x * m[0] + vpos.y * m[4] + vpos.z * m[8]);
  359. m[13] = -(vpos.x * m[1] + vpos.y * m[5] + vpos.z * m[9]);
  360. m[14] = -(vpos.x * m[2] + vpos.y * m[6] + vpos.z * m[10]);
  361. m[15] = 1.0;
  362. };
  363. var timeInfo = {
  364. 'start': 0, 'prev': 0,
  365. 'delta': 0, 'elapsed': 0
  366. };
  367. var gl;
  368. var renderSpec = {
  369. 'width': 0,
  370. 'height': 0,
  371. 'aspect': 1,
  372. 'array': new Float32Array(3),
  373. 'halfWidth': 0,
  374. 'halfHeight': 0,
  375. 'halfArray': new Float32Array(3)
  376. };
  377. renderSpec.setSize = function (w, h) {
  378. renderSpec.width = w;
  379. renderSpec.height = h;
  380. renderSpec.aspect = renderSpec.width / renderSpec.height;
  381. renderSpec.array[0] = renderSpec.width;
  382. renderSpec.array[1] = renderSpec.height;
  383. renderSpec.array[2] = renderSpec.aspect;
  384. renderSpec.halfWidth = Math.floor(w / 2);
  385. renderSpec.halfHeight = Math.floor(h / 2);
  386. renderSpec.halfArray[0] = renderSpec.halfWidth;
  387. renderSpec.halfArray[1] = renderSpec.halfHeight;
  388. renderSpec.halfArray[2] = renderSpec.halfWidth / renderSpec.halfHeight;
  389. };
  390. function deleteRenderTarget(rt) {
  391. gl.deleteFramebuffer(rt.frameBuffer);
  392. gl.deleteRenderbuffer(rt.renderBuffer);
  393. gl.deleteTexture(rt.texture);
  394. }
  395. function createRenderTarget(w, h) {
  396. var ret = {
  397. 'width': w,
  398. 'height': h,
  399. 'sizeArray': new Float32Array([w, h, w / h]),
  400. 'dtxArray': new Float32Array([1.0 / w, 1.0 / h])
  401. };
  402. ret.frameBuffer = gl.createFramebuffer();
  403. ret.renderBuffer = gl.createRenderbuffer();
  404. ret.texture = gl.createTexture();
  405. gl.bindTexture(gl.TEXTURE_2D, ret.texture);
  406. gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, w, h, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
  407. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  408. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
  409. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  410. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  411. gl.bindFramebuffer(gl.FRAMEBUFFER, ret.frameBuffer);
  412. gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, ret.texture, 0);
  413. gl.bindRenderbuffer(gl.RENDERBUFFER, ret.renderBuffer);
  414. gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, w, h);
  415. gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, ret.renderBuffer);
  416. gl.bindTexture(gl.TEXTURE_2D, null);
  417. gl.bindRenderbuffer(gl.RENDERBUFFER, null);
  418. gl.bindFramebuffer(gl.FRAMEBUFFER, null);
  419. return ret;
  420. }
  421. function compileShader(shtype, shsrc) {
  422. var retsh = gl.createShader(shtype);
  423. gl.shaderSource(retsh, shsrc);
  424. gl.compileShader(retsh);
  425. if (!gl.getShaderParameter(retsh, gl.COMPILE_STATUS)) {
  426. var errlog = gl.getShaderInfoLog(retsh);
  427. gl.deleteShader(retsh);
  428. console.error(errlog);
  429. return null;
  430. }
  431. return retsh;
  432. }
  433. function createShader(vtxsrc, frgsrc, uniformlist, attrlist) {
  434. var vsh = compileShader(gl.VERTEX_SHADER, vtxsrc);
  435. var fsh = compileShader(gl.FRAGMENT_SHADER, frgsrc);
  436. if (vsh == null || fsh == null) {
  437. return null;
  438. }
  439. var prog = gl.createProgram();
  440. gl.attachShader(prog, vsh);
  441. gl.attachShader(prog, fsh);
  442. gl.deleteShader(vsh);
  443. gl.deleteShader(fsh);
  444. gl.linkProgram(prog);
  445. if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) {
  446. var errlog = gl.getProgramInfoLog(prog);
  447. console.error(errlog);
  448. return null;
  449. }
  450. if (uniformlist) {
  451. prog.uniforms = {};
  452. for (var i = 0; i < uniformlist.length; i++) {
  453. prog.uniforms[uniformlist[i]] = gl.getUniformLocation(prog, uniformlist[i]);
  454. }
  455. }
  456. if (attrlist) {
  457. prog.attributes = {};
  458. for (var i = 0; i < attrlist.length; i++) {
  459. var attr = attrlist[i];
  460. prog.attributes[attr] = gl.getAttribLocation(prog, attr);
  461. }
  462. }
  463. return prog;
  464. }
  465. function useShader(prog) {
  466. gl.useProgram(prog);
  467. for (var attr in prog.attributes) {
  468. gl.enableVertexAttribArray(prog.attributes[attr]);
  469. }
  470. }
  471. function unuseShader(prog) {
  472. for (var attr in prog.attributes) {
  473. gl.disableVertexAttribArray(prog.attributes[attr]);
  474. }
  475. gl.useProgram(null);
  476. }
  477. var projection = {
  478. 'angle': 60,
  479. 'nearfar': new Float32Array([0.1, 100.0]),
  480. 'matrix': Matrix44.createIdentity()
  481. };
  482. var camera = {
  483. 'position': Vector3.create(0, 0, 100),
  484. 'lookat': Vector3.create(0, 0, 0),
  485. 'up': Vector3.create(0, 1, 0),
  486. 'dof': Vector3.create(10.0, 4.0, 8.0),
  487. 'matrix': Matrix44.createIdentity()
  488. };
  489. var pointFlower = {};
  490. var meshFlower = {};
  491. var sceneStandBy = false;
  492. var BlossomParticle = function () {
  493. this.velocity = new Array(3);
  494. this.rotation = new Array(3);
  495. this.position = new Array(3);
  496. this.euler = new Array(3);
  497. this.size = 1.0;
  498. this.alpha = 1.0;
  499. this.zkey = 0.0;
  500. };
  501. BlossomParticle.prototype.setVelocity = function (vx, vy, vz) {
  502. this.velocity[0] = vx;
  503. this.velocity[1] = vy;
  504. this.velocity[2] = vz;
  505. };
  506. BlossomParticle.prototype.setRotation = function (rx, ry, rz) {
  507. this.rotation[0] = rx;
  508. this.rotation[1] = ry;
  509. this.rotation[2] = rz;
  510. };
  511. BlossomParticle.prototype.setPosition = function (nx, ny, nz) {
  512. this.position[0] = nx;
  513. this.position[1] = ny;
  514. this.position[2] = nz;
  515. };
  516. BlossomParticle.prototype.setEulerAngles = function (rx, ry, rz) {
  517. this.euler[0] = rx;
  518. this.euler[1] = ry;
  519. this.euler[2] = rz;
  520. };
  521. BlossomParticle.prototype.setSize = function (s) {
  522. this.size = s;
  523. };
  524. BlossomParticle.prototype.update = function (dt, et) {
  525. this.position[0] += this.velocity[0] * dt;
  526. this.position[1] += this.velocity[1] * dt;
  527. this.position[2] += this.velocity[2] * dt;
  528. this.euler[0] += this.rotation[0] * dt;
  529. this.euler[1] += this.rotation[1] * dt;
  530. this.euler[2] += this.rotation[2] * dt;
  531. };
  532. function createPointFlowers() {
  533. var prm = gl.getParameter(gl.ALIASED_POINT_SIZE_RANGE);
  534. renderSpec.pointSize = {'min': prm[0], 'max': prm[1]};
  535. var vtxsrc = document.getElementById("sakura_point_vsh").textContent;
  536. var frgsrc = document.getElementById("sakura_point_fsh").textContent;
  537. pointFlower.program = createShader(
  538. vtxsrc, frgsrc,
  539. ['uProjection', 'uModelview', 'uResolution', 'uOffset', 'uDOF', 'uFade'],
  540. ['aPosition', 'aEuler', 'aMisc']
  541. );
  542. useShader(pointFlower.program);
  543. pointFlower.offset = new Float32Array([0.0, 0.0, 0.0]);
  544. pointFlower.fader = Vector3.create(0.0, 10.0, 0.0);
  545. pointFlower.numFlowers = 1600;
  546. pointFlower.particles = new Array(pointFlower.numFlowers);
  547. pointFlower.dataArray = new Float32Array(pointFlower.numFlowers * (3 + 3 + 2));
  548. pointFlower.positionArrayOffset = 0;
  549. pointFlower.eulerArrayOffset = pointFlower.numFlowers * 3;
  550. pointFlower.miscArrayOffset = pointFlower.numFlowers * 6;
  551. pointFlower.buffer = gl.createBuffer();
  552. gl.bindBuffer(gl.ARRAY_BUFFER, pointFlower.buffer);
  553. gl.bufferData(gl.ARRAY_BUFFER, pointFlower.dataArray, gl.DYNAMIC_DRAW);
  554. gl.bindBuffer(gl.ARRAY_BUFFER, null);
  555. unuseShader(pointFlower.program);
  556. for (var i = 0; i < pointFlower.numFlowers; i++) {
  557. pointFlower.particles[i] = new BlossomParticle();
  558. }
  559. }
  560. function initPointFlowers() {
  561. pointFlower.area = Vector3.create(20.0, 20.0, 20.0);
  562. pointFlower.area.x = pointFlower.area.y * renderSpec.aspect;
  563. pointFlower.fader.x = 10.0;
  564. pointFlower.fader.y = pointFlower.area.z;
  565. pointFlower.fader.z = 0.1;
  566. var PI2 = Math.PI * 2.0;
  567. var tmpv3 = Vector3.create(0, 0, 0);
  568. var tmpv = 0;
  569. var symmetryrand = function () {
  570. return (Math.random() * 2.0 - 1.0);
  571. };
  572. for (var i = 0; i < pointFlower.numFlowers; i++) {
  573. var tmpprtcl = pointFlower.particles[i];
  574. tmpv3.x = symmetryrand() * 0.3 + 0.8;
  575. tmpv3.y = symmetryrand() * 0.2 - 1.0;
  576. tmpv3.z = symmetryrand() * 0.3 + 0.5;
  577. Vector3.normalize(tmpv3);
  578. tmpv = 2.0 + Math.random() * 1.0;
  579. tmpprtcl.setVelocity(tmpv3.x * tmpv, tmpv3.y * tmpv, tmpv3.z * tmpv);
  580. tmpprtcl.setRotation(
  581. symmetryrand() * PI2 * 0.5,
  582. symmetryrand() * PI2 * 0.5,
  583. symmetryrand() * PI2 * 0.5
  584. );
  585. tmpprtcl.setPosition(
  586. symmetryrand() * pointFlower.area.x,
  587. symmetryrand() * pointFlower.area.y,
  588. symmetryrand() * pointFlower.area.z
  589. );
  590. tmpprtcl.setEulerAngles(
  591. Math.random() * Math.PI * 2.0,
  592. Math.random() * Math.PI * 2.0,
  593. Math.random() * Math.PI * 2.0
  594. );
  595. tmpprtcl.setSize(0.9 + Math.random() * 0.1);
  596. }
  597. }
  598. function renderPointFlowers() {
  599. var PI2 = Math.PI * 2.0;
  600. var limit = [pointFlower.area.x, pointFlower.area.y, pointFlower.area.z];
  601. var repeatPos = function (prt, cmp, limit) {
  602. if (Math.abs(prt.position[cmp]) - prt.size * 0.5 > limit) {
  603. if (prt.position[cmp] > 0) {
  604. prt.position[cmp] -= limit * 2.0;
  605. } else {
  606. prt.position[cmp] += limit * 2.0;
  607. }
  608. }
  609. };
  610. var repeatEuler = function (prt, cmp) {
  611. prt.euler[cmp] = prt.euler[cmp] % PI2;
  612. if (prt.euler[cmp] < 0.0) {
  613. prt.euler[cmp] += PI2;
  614. }
  615. };
  616. for (var i = 0; i < pointFlower.numFlowers; i++) {
  617. var prtcl = pointFlower.particles[i];
  618. prtcl.update(timeInfo.delta, timeInfo.elapsed);
  619. repeatPos(prtcl, 0, pointFlower.area.x);
  620. repeatPos(prtcl, 1, pointFlower.area.y);
  621. repeatPos(prtcl, 2, pointFlower.area.z);
  622. repeatEuler(prtcl, 0);
  623. repeatEuler(prtcl, 1);
  624. repeatEuler(prtcl, 2);
  625. prtcl.alpha = 1.0;
  626. prtcl.zkey = (camera.matrix[2] * prtcl.position[0]
  627. + camera.matrix[6] * prtcl.position[1]
  628. + camera.matrix[10] * prtcl.position[2]
  629. + camera.matrix[14]);
  630. }
  631. pointFlower.particles.sort(function (p0, p1) {
  632. return p0.zkey - p1.zkey;
  633. });
  634. var ipos = pointFlower.positionArrayOffset;
  635. var ieuler = pointFlower.eulerArrayOffset;
  636. var imisc = pointFlower.miscArrayOffset;
  637. for (var i = 0; i < pointFlower.numFlowers; i++) {
  638. var prtcl = pointFlower.particles[i];
  639. pointFlower.dataArray[ipos] = prtcl.position[0];
  640. pointFlower.dataArray[ipos + 1] = prtcl.position[1];
  641. pointFlower.dataArray[ipos + 2] = prtcl.position[2];
  642. ipos += 3;
  643. pointFlower.dataArray[ieuler] = prtcl.euler[0];
  644. pointFlower.dataArray[ieuler + 1] = prtcl.euler[1];
  645. pointFlower.dataArray[ieuler + 2] = prtcl.euler[2];
  646. ieuler += 3;
  647. pointFlower.dataArray[imisc] = prtcl.size;
  648. pointFlower.dataArray[imisc + 1] = prtcl.alpha;
  649. imisc += 2;
  650. }
  651. gl.enable(gl.BLEND);
  652. gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
  653. var prog = pointFlower.program;
  654. useShader(prog);
  655. gl.uniformMatrix4fv(prog.uniforms.uProjection, false, projection.matrix);
  656. gl.uniformMatrix4fv(prog.uniforms.uModelview, false, camera.matrix);
  657. gl.uniform3fv(prog.uniforms.uResolution, renderSpec.array);
  658. gl.uniform3fv(prog.uniforms.uDOF, Vector3.arrayForm(camera.dof));
  659. gl.uniform3fv(prog.uniforms.uFade, Vector3.arrayForm(pointFlower.fader));
  660. gl.bindBuffer(gl.ARRAY_BUFFER, pointFlower.buffer);
  661. gl.bufferData(gl.ARRAY_BUFFER, pointFlower.dataArray, gl.DYNAMIC_DRAW);
  662. gl.vertexAttribPointer(prog.attributes.aPosition, 3, gl.FLOAT, false, 0, pointFlower.positionArrayOffset * Float32Array.BYTES_PER_ELEMENT);
  663. gl.vertexAttribPointer(prog.attributes.aEuler, 3, gl.FLOAT, false, 0, pointFlower.eulerArrayOffset * Float32Array.BYTES_PER_ELEMENT);
  664. gl.vertexAttribPointer(prog.attributes.aMisc, 2, gl.FLOAT, false, 0, pointFlower.miscArrayOffset * Float32Array.BYTES_PER_ELEMENT);
  665. for (var i = 1; i < 2; i++) {
  666. var zpos = i * -2.0;
  667. pointFlower.offset[0] = pointFlower.area.x * -1.0;
  668. pointFlower.offset[1] = pointFlower.area.y * -1.0;
  669. pointFlower.offset[2] = pointFlower.area.z * zpos;
  670. gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset);
  671. gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers);
  672. pointFlower.offset[0] = pointFlower.area.x * -1.0;
  673. pointFlower.offset[1] = pointFlower.area.y * 1.0;
  674. pointFlower.offset[2] = pointFlower.area.z * zpos;
  675. gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset);
  676. gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers);
  677. pointFlower.offset[0] = pointFlower.area.x * 1.0;
  678. pointFlower.offset[1] = pointFlower.area.y * -1.0;
  679. pointFlower.offset[2] = pointFlower.area.z * zpos;
  680. gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset);
  681. gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers);
  682. pointFlower.offset[0] = pointFlower.area.x * 1.0;
  683. pointFlower.offset[1] = pointFlower.area.y * 1.0;
  684. pointFlower.offset[2] = pointFlower.area.z * zpos;
  685. gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset);
  686. gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers);
  687. }
  688. pointFlower.offset[0] = 0.0;
  689. pointFlower.offset[1] = 0.0;
  690. pointFlower.offset[2] = 0.0;
  691. gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset);
  692. gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers);
  693. gl.bindBuffer(gl.ARRAY_BUFFER, null);
  694. unuseShader(prog);
  695. gl.enable(gl.DEPTH_TEST);
  696. gl.disable(gl.BLEND);
  697. }
  698. function createEffectProgram(vtxsrc, frgsrc, exunifs, exattrs) {
  699. var ret = {};
  700. var unifs = ['uResolution', 'uSrc', 'uDelta'];
  701. if (exunifs) {
  702. unifs = unifs.concat(exunifs);
  703. }
  704. var attrs = ['aPosition'];
  705. if (exattrs) {
  706. attrs = attrs.concat(exattrs);
  707. }
  708. ret.program = createShader(vtxsrc, frgsrc, unifs, attrs);
  709. useShader(ret.program);
  710. ret.dataArray = new Float32Array([
  711. -1.0, -1.0,
  712. 1.0, -1.0,
  713. -1.0, 1.0,
  714. 1.0, 1.0
  715. ]);
  716. ret.buffer = gl.createBuffer();
  717. gl.bindBuffer(gl.ARRAY_BUFFER, ret.buffer);
  718. gl.bufferData(gl.ARRAY_BUFFER, ret.dataArray, gl.STATIC_DRAW);
  719. gl.bindBuffer(gl.ARRAY_BUFFER, null);
  720. unuseShader(ret.program);
  721. return ret;
  722. }
  723. function useEffect(fxobj, srctex) {
  724. var prog = fxobj.program;
  725. useShader(prog);
  726. gl.uniform3fv(prog.uniforms.uResolution, renderSpec.array);
  727. if (srctex != null) {
  728. gl.uniform2fv(prog.uniforms.uDelta, srctex.dtxArray);
  729. gl.uniform1i(prog.uniforms.uSrc, 0);
  730. gl.activeTexture(gl.TEXTURE0);
  731. gl.bindTexture(gl.TEXTURE_2D, srctex.texture);
  732. }
  733. }
  734. function drawEffect(fxobj) {
  735. gl.bindBuffer(gl.ARRAY_BUFFER, fxobj.buffer);
  736. gl.vertexAttribPointer(fxobj.program.attributes.aPosition, 2, gl.FLOAT, false, 0, 0);
  737. gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
  738. }
  739. function unuseEffect(fxobj) {
  740. unuseShader(fxobj.program);
  741. }
  742. var effectLib = {};
  743. function createEffectLib() {
  744. var vtxsrc, frgsrc;
  745. var cmnvtxsrc = document.getElementById("fx_common_vsh").textContent;
  746. frgsrc = document.getElementById("bg_fsh").textContent;
  747. effectLib.sceneBg = createEffectProgram(cmnvtxsrc, frgsrc, ['uTimes'], null);
  748. frgsrc = document.getElementById("fx_brightbuf_fsh").textContent;
  749. effectLib.mkBrightBuf = createEffectProgram(cmnvtxsrc, frgsrc, null, null);
  750. frgsrc = document.getElementById("fx_dirblur_r4_fsh").textContent;
  751. effectLib.dirBlur = createEffectProgram(cmnvtxsrc, frgsrc, ['uBlurDir'], null);
  752. vtxsrc = document.getElementById("pp_final_vsh").textContent;
  753. frgsrc = document.getElementById("pp_final_fsh").textContent;
  754. effectLib.finalComp = createEffectProgram(vtxsrc, frgsrc, ['uBloom'], null);
  755. }
  756. function createBackground() {
  757. }
  758. function initBackground() {
  759. }
  760. function renderBackground() {
  761. gl.disable(gl.DEPTH_TEST)
  762. useEffect(effectLib.sceneBg, null);
  763. gl.uniform2f(effectLib.sceneBg.program.uniforms.uTimes, timeInfo.elapsed, timeInfo.delta);
  764. drawEffect(effectLib.sceneBg);
  765. unuseEffect(effectLib.sceneBg);
  766. gl.enable(gl.DEPTH_TEST);
  767. }
  768. var postProcess = {};
  769. function createPostProcess() {
  770. }
  771. function initPostProcess() {
  772. }
  773. function renderPostProcess() {
  774. gl.enable(gl.TEXTURE_2D);
  775. gl.disable(gl.DEPTH_TEST);
  776. var bindRT = function (rt, isclear) {
  777. gl.bindFramebuffer(gl.FRAMEBUFFER, rt.frameBuffer);
  778. gl.viewport(0, 0, rt.width, rt.height);
  779. if (isclear) {
  780. gl.clearColor(0, 0, 0, 0);
  781. gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
  782. }
  783. };
  784. bindRT(renderSpec.wHalfRT0, true);
  785. useEffect(effectLib.mkBrightBuf, renderSpec.mainRT);
  786. drawEffect(effectLib.mkBrightBuf);
  787. unuseEffect(effectLib.mkBrightBuf);
  788. for (var i = 0; i < 2; i++) {
  789. var p = 1.5 + 1 * i;
  790. var s = 2.0 + 1 * i;
  791. bindRT(renderSpec.wHalfRT1, true);
  792. useEffect(effectLib.dirBlur, renderSpec.wHalfRT0);
  793. gl.uniform4f(effectLib.dirBlur.program.uniforms.uBlurDir, p, 0.0, s, 0.0);
  794. drawEffect(effectLib.dirBlur);
  795. unuseEffect(effectLib.dirBlur);
  796. bindRT(renderSpec.wHalfRT0, true);
  797. useEffect(effectLib.dirBlur, renderSpec.wHalfRT1);
  798. gl.uniform4f(effectLib.dirBlur.program.uniforms.uBlurDir, 0.0, p, 0.0, s);
  799. drawEffect(effectLib.dirBlur);
  800. unuseEffect(effectLib.dirBlur);
  801. }
  802. gl.bindFramebuffer(gl.FRAMEBUFFER, null);
  803. gl.viewport(0, 0, renderSpec.width, renderSpec.height);
  804. gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
  805. useEffect(effectLib.finalComp, renderSpec.mainRT);
  806. gl.uniform1i(effectLib.finalComp.program.uniforms.uBloom, 1);
  807. gl.activeTexture(gl.TEXTURE1);
  808. gl.bindTexture(gl.TEXTURE_2D, renderSpec.wHalfRT0.texture);
  809. drawEffect(effectLib.finalComp);
  810. unuseEffect(effectLib.finalComp);
  811. gl.enable(gl.DEPTH_TEST);
  812. }
  813. var SceneEnv = {};
  814. function createScene() {
  815. createEffectLib();
  816. createBackground();
  817. createPointFlowers();
  818. createPostProcess();
  819. sceneStandBy = true;
  820. }
  821. function initScene() {
  822. initBackground();
  823. initPointFlowers();
  824. initPostProcess();
  825. camera.position.z = pointFlower.area.z + projection.nearfar[0];
  826. projection.angle = Math.atan2(pointFlower.area.y, camera.position.z + pointFlower.area.z) * 180.0 / Math.PI * 2.0;
  827. Matrix44.loadProjection(projection.matrix, renderSpec.aspect, projection.angle, projection.nearfar[0], projection.nearfar[1]);
  828. }
  829. function renderScene() {
  830. Matrix44.loadLookAt(camera.matrix, camera.position, camera.lookat, camera.up);
  831. gl.enable(gl.DEPTH_TEST);
  832. gl.bindFramebuffer(gl.FRAMEBUFFER, renderSpec.mainRT.frameBuffer);
  833. gl.viewport(0, 0, renderSpec.mainRT.width, renderSpec.mainRT.height);
  834. gl.clearColor(0.005, 0, 0.05, 0);
  835. gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
  836. renderBackground();
  837. renderPointFlowers();
  838. renderPostProcess();
  839. }
  840. function onResize(e) {
  841. makeCanvasFullScreen(document.getElementById("sakura"));
  842. setViewports();
  843. if (sceneStandBy) {
  844. initScene();
  845. }
  846. }
  847. function setViewports() {
  848. renderSpec.setSize(gl.canvas.width, gl.canvas.height);
  849. gl.clearColor(0.2, 0.2, 0.5, 1.0);
  850. gl.viewport(0, 0, renderSpec.width, renderSpec.height);
  851. var rtfunc = function (rtname, rtw, rth) {
  852. var rt = renderSpec[rtname];
  853. if (rt) deleteRenderTarget(rt);
  854. renderSpec[rtname] = createRenderTarget(rtw, rth);
  855. };
  856. rtfunc('mainRT', renderSpec.width, renderSpec.height);
  857. rtfunc('wFullRT0', renderSpec.width, renderSpec.height);
  858. rtfunc('wFullRT1', renderSpec.width, renderSpec.height);
  859. rtfunc('wHalfRT0', renderSpec.halfWidth, renderSpec.halfHeight);
  860. rtfunc('wHalfRT1', renderSpec.halfWidth, renderSpec.halfHeight);
  861. }
  862. function render() {
  863. renderScene();
  864. }
  865. var animating = true;
  866. function toggleAnimation(elm) {
  867. animating ^= true;
  868. if (animating) animate();
  869. if (elm) {
  870. elm.innerHTML = animating ? "Stop" : "Start";
  871. }
  872. }
  873. function stepAnimation() {
  874. if (!animating) animate();
  875. }
  876. function animate() {
  877. var curdate = new Date();
  878. timeInfo.elapsed = (curdate - timeInfo.start) / 1000.0;
  879. timeInfo.delta = (curdate - timeInfo.prev) / 1000.0;
  880. timeInfo.prev = curdate;
  881. if (animating) requestAnimationFrame(animate);
  882. render();
  883. }
  884. function makeCanvasFullScreen(canvas) {
  885. var b = document.body;
  886. var d = document.documentElement;
  887. fullw = Math.max(b.clientWidth, b.scrollWidth, d.scrollWidth, d.clientWidth);
  888. fullh = Math.max(b.clientHeight, b.scrollHeight, d.scrollHeight, d.clientHeight);
  889. canvas.width = fullw;
  890. canvas.height = fullh;
  891. }
  892. window.addEventListener('load', function (e) {
  893. var canvas = document.getElementById("sakura");
  894. try {
  895. makeCanvasFullScreen(canvas);
  896. gl = canvas.getContext('experimental-webgl');
  897. } catch (e) {
  898. alert("WebGL not supported." + e);
  899. console.error(e);
  900. return;
  901. }
  902. window.addEventListener('resize', onResize);
  903. setViewports();
  904. createScene();
  905. initScene();
  906. timeInfo.start = new Date();
  907. timeInfo.prev = timeInfo.start;
  908. animate();
  909. });
  910. (function (w, r) {
  911. w['r' + r] = w['r' + r] || w['webkitR' + r] || w['mozR' + r] || w['msR' + r] || w['oR' + r] || function (c) {
  912. w.setTimeout(c, 1000 / 60);
  913. };
  914. })(window, 'equestAnimationFrame');
  915. </script>
  916. </html>

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/603397
推荐阅读
相关标签
  

闽ICP备14008679号