Сфера чистой энергии с протуберанцами из частиц на HTML5 Canvas и Tree Min
Это невероятно красиво! Будто солнце со всей его мощью оживает и извергает сотни тысяч светящихся частичек! Этот пучок энергии ещё и рассматривать можно при помощи курсора мышки и её колёсика
Для начала посмотрите ДЕМО
Установка:
1#: В самый низ вашего CSS вставьте:
1 2 3 4 5 6 7 |
#energy { position: fixed; touch-action: none; z-index: -1; top: 0px; left: 0px; } |
2#: На всех нужных страницах между тегами body и /body поместите:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
<!-- <button>record</button> --> <script id="vertexShaderParticle" type="x-shader/x-vertex"> uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; uniform sampler2D u_noise; attribute vec2 reference; uniform sampler2D texturePosition; uniform bool u_clicked; varying float v_op; void main() { vec3 position = texture2D(texturePosition, reference).xyz; position *= 3.; // position -= 10.; vec3 transformed = vec3( position ); vec4 mvpos = modelViewMatrix * vec4( transformed, 1.0 ); // gl_PointSize = 30.0 * (1.0 / (mvpos.z * mvpos.z)); // gl_PointSize = 1.; gl_PointSize = clamp(3. - length(transformed) * .01, 0., 4.); v_op = 1. / length(position) * 8.; // gl_PointSize = 2.; gl_Position = projectionMatrix * mvpos; } </script> <script id="fragmentShaderParticle" type="x-shader/x-fragment"> uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; uniform sampler2D u_noise; uniform bool u_clicked; varying float v_op; vec2 hash2(vec2 p) { vec2 o = texture2D( u_noise, (p+0.5)/256.0, -100.0 ).xy; return o; } void main() { // vec2 uv = (gl_FragCoord.xy - 0.5 * u_resolution.xy) / min(u_resolution.x, u_resolution.y); vec2 uv = gl_PointCoord.xy - .5; vec3 particlecolour = vec3(.5, .53, .53) * 1.8; vec3 outercolour = vec3(1.); if(u_clicked) { particlecolour = vec3(.05, .15, .2) * .5; outercolour = vec3(0.); } float l = length(uv); vec3 colour = mix(outercolour, particlecolour, smoothstep(.9, -.1, l)); colour = mix(mix(outercolour, vec3(2., 0.5, 0.), smoothstep(.9, -.1, l)), colour, smoothstep(3., 0.15, v_op)); gl_FragColor = vec4(colour, clamp(v_op*2., 0., 1.)); } </script> <script id="fragmentShaderVelocity" type="x-shader/x-fragment"> uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; uniform float u_mousex; varying float v_op; uniform sampler2D u_noise; const float TAU = 6.28318530718; // otaviogood's noise from https://www.shadertoy.com/view/ld2SzK const float nudge = 0.739513; // size of perpendicular vector float normalizer = 1.0 / sqrt(1.0 + nudge*nudge); // pythagorean theorem on that perpendicular to maintain scale float SpiralNoiseC(vec3 p) { float n = 0.0; // noise amount float iter = 1.0; for (int i = 0; i < 8; i++) { // add sin and cos scaled inverse with the frequency n += -abs(sin(p.y*iter) + cos(p.x*iter)) / iter; // abs for a ridged look // rotate by adding perpendicular and scaling down p.xy += vec2(p.y, -p.x) * nudge; p.xy *= normalizer; // rotate on other axis p.xz += vec2(p.z, -p.x) * nudge; p.xz *= normalizer; // increase the frequency iter *= 1.733733; } return n; } vec3 hash3(vec2 p) { vec3 o = texture2D( u_noise, (p+0.5)/256.0, -100.0 ).xyz; return o; } void main() { vec2 uv = gl_FragCoord.xy / resolution.xy; vec3 position = texture2D(v_samplerPosition, uv).xyz; vec3 velocity = texture2D(v_samplerVelocity, uv).xyz; vec3 acceleration = vec3(0.); float t = u_time * 5.; float l = clamp(length(position), 1., 100.); vec3 spherical = vec3(1./l, atan(position.y, position.x) * TAU, acos(position.z / l) * TAU); spherical.x *= length(spherical.yz * TAU * 2.) * .1; acceleration.x = spherical.x * sin(spherical.z) * cos(spherical.y); acceleration.y = spherical.x * sin(spherical.z) * sin(spherical.y); acceleration.z = spherical.x * cos(spherical.z); acceleration *= (1. / l) - (sin(u_time * 15.) * .2 + .5); // acceleration = vec3((1. - clamp(length(position) * .2, 0., 1.)) * .5); // acceleration *= 1. + hash3(position.yz) * .05 - .025; vec3 vel = velocity * .95 + acceleration * .15; if(length(vel) > 3.) { vel *= 1. / length(vel) * 3.; } gl_FragColor = vec4(vel, 1.0); // gl_FragColor = vec4(-.1); } </script> <script id="fragmentShaderPosition" type="x-shader/x-fragment"> uniform float delta; uniform float u_time; uniform sampler2D v_samplerPosition_orig; uniform sampler2D u_noise; vec3 hash3(vec2 p) { vec3 o = texture2D( u_noise, (p+0.5)/256.0, -100.0 ).xyz; return o; } void main() { vec2 uv = gl_FragCoord.xy / resolution.xy; vec3 position_original = texture2D(v_samplerPosition_orig, uv).xyz; vec3 position = texture2D(v_samplerPosition, uv).xyz; vec3 velocity = texture2D(v_samplerVelocity, uv).xyz; // velocity -= .5; // velocity *= 3.; // velocity = velocity * 2. - 1.; vec3 pos = position + velocity * delta; // This just adds a little touch more randomness to the motion. // This is incredibly subtle but has the effect of making the particles // look more "separate" in motion vec3 hash = hash3(position_original.xy * position_original.zx * 20.); // pos *= 1. + (hash - .5) * .0005; pos += (hash - .5) * .0001; // // vec2 p = vec2(atan(pos.y, pos.x), length(pos.xy)); // p.x -= velocity.x * .001 + .0001; // pos.x = cos(p.x) * p.y; // pos.y = sin(p.x) * p.y; // pos.z += .005; if(length(pos) > 20.) { pos = position_original; } gl_FragColor = vec4(pos, 1.0); } </script> <div id="energy" touch-action="none"></div> <script type="text/javascript" src="/js/three.min_new.js"></script> <script type="text/javascript" src="/js/GPUComputationRenderer.js"></script> <script type="text/javascript" src="/js/OrbitControls.js"></script> <script type="text/javascript" src="/js/ccapture.js"></script> <script type="text/javascript" src="/js/energy.js"></script> |
Осталось лишь залить все JS файлы из прикреплённого архива в папку js
Залипательно
Вау!