Чёрный пепел, падающий с раскалённых облаков на Tree Canvas и HTML5
Просто невероятный эффект! Чёрный пепел падает на наблюдателя с раскалённого неба. Всё выглядит будто после какой-то глобальной катастрофы. Пепел подгоняется ветром и уносится прочь. Шикарно!
Для начала посмотрите ДЕМО
Установка:
На странице, где хотите видеть такой эффект сразу после тега 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 |
<script src="/js/three.min.js"></script> <script id="vertexShader" type="x-shader/x-vertex"> void main() { gl_Position = vec4( position, 1.0 ); } </script> <script id="fragmentShader" type="x-shader/x-fragment"> uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; uniform sampler2D u_noise; #define PI 3.141592653589793 #define TAU 6. const float multiplier = 15.5; const float zoomSpeed = 10.; const int layers = 10; const int octaves = 5; vec2 hash2(vec2 p) { vec2 o = texture2D( u_noise, (p+0.5)/256.0, -100.0 ).xy; return o; } mat2 rotate2d(float _angle){ return mat2(cos(_angle),sin(_angle), -sin(_angle),cos(_angle)); } vec3 hsb2rgb( in vec3 c ){ vec3 rgb = clamp(abs(mod(c.x*6.0+vec3(0.0,4.0,2.0), 6.0)-3.0)-1.0, 0.0, 1.0 ); rgb = rgb*rgb*(3.0-2.0*rgb); return c.z * mix( vec3(1.0), rgb, c.y); } float hash(vec2 p) { float o = texture2D( u_noise, (p+0.5)/256.0, -100.0 ).x; return o; } float noise(vec2 uv) { vec2 id = floor(uv); vec2 subuv = fract(uv); vec2 u = subuv * subuv * (3. - 2. * subuv); float a = hash(id); float b = hash(id + vec2(1., 0.)); float c = hash(id + vec2(0., 1.)); float d = hash(id + vec2(1., 1.)); return mix(mix(a, b, u.x), mix(c, d, u.x), u.y); } float fbm(in vec2 uv) { float s = .0; float m = .0; float a = .5; for(int i = 0; i < octaves; i++) { s += a * noise(uv); m += a; a *= .5; uv *= 2.; } return s / m; } vec3 domain(vec2 z){ return vec3(hsb2rgb(vec3(atan(z.y,z.x)/TAU,1.,1.))); } vec3 colour(vec2 z) { return domain(z); } // The render function is where we render the pattern to be added to the layer vec3 render(vec2 uv, float scale, vec3 colour) { vec2 id = floor(uv); vec2 subuv = fract(uv); vec2 rand = hash2(id); float bokeh = abs(scale) * 1.; float particle = 0.; if(length(rand) > 1.3) { vec2 pos = subuv-.5; float field = length(pos); particle = smoothstep(.3, 0., field); particle += smoothstep(.4 * bokeh, 0.34 * bokeh, field); } return vec3(particle*2.); } vec3 renderLayer(int layer, int layers, vec2 uv, inout float opacity, vec3 colour, float n) { vec2 _uv = uv; // Scale // Generating a scale value between zero and 1 based on a mod of u_time // A frequency of 10 dixided by the layer index (10 / layers * layer) float scale = mod((u_time + zoomSpeed / float(layers) * float(layer)) / zoomSpeed, -1.); uv *= 20.; // The initial scale. Increasing this makes the cells smaller and the "speed" apepar faster uv *= scale*scale; // then modifying the overall scale by the generated amount // uv *= 1. + ( ( n*.5 ) * ( length(_uv) ) ); // uv += .5*float(layer); uv = rotate2d(u_time / 10.) * uv; // rotarting uv += vec2(25. + sin(u_time*.1)) * float(layer); // ofsetting the UV by an arbitrary amount to make the layer appear different // render vec3 pass = render(uv * multiplier, scale, colour) * .2; // render the pass // this is the opacity of the layer fading in from the "bottom" opacity = 1. + scale; float _opacity = opacity; // pass += n * .5 * mix(vec3(0., .5, 1.5), vec3(1., .5, 0.), opacity); // This is the opacity of the layer fading out at the top (we want this minimal, hence the smoothstep) float endOpacity = smoothstep(0., 0.4, scale * -1.); opacity += endOpacity; return pass * _opacity * endOpacity; } void main() { vec2 uv = (gl_FragCoord.xy - 0.5 * u_resolution.xy); if(u_resolution.y < u_resolution.x) { uv /= u_resolution.y; } else { uv /= u_resolution.x; } // uv.y += cos(u_time * .1) * .5; // uv.x += sin(u_time * .1) * .5; // float n = fbm(uv * 3. - 2.); float n = fbm((uv + vec2(sin(u_time*.1), u_time*.1)) * 2. - 2.); vec3 colour = vec3(0.); // colour = n * mix(vec3(0., .5, 1.5), vec3(1., .5, -.1), n); colour = n * mix(vec3(0., .5, 1.5)*-1.5, clamp(vec3(1., .5, .25)*2., 0., 1.), n); // colour -= n*n*n*n*.4; // colour += smoothstep(.8, 2.5, sin(n*n*n*8.))*.4; float opacity = 1.; float opacity_sum = 1.; for(int i = 1; i <= layers; i++) { colour -= renderLayer(i, layers, uv, opacity, colour, n); opacity_sum += opacity; } colour /= opacity_sum; gl_FragColor = vec4(clamp(colour * 20., 0., 1.),1.0); } </script> <div id="container" touch-action="none" style="position:fixed;"></div> <script src='/js/ccapture.js'></script> <script type="text/javascript" src="/js/evil.js"></script> |
Осталось лишь залить три JS файла из прикреплённого архива в папку js
Ох нифигасе, я залип. =). Спасибо за скрипт!
Пожалуйста! Я тоже залипал, когда впервые набрёл на него
морг морг морг морг.... черт .. отпусти меня...
Ты случайно не читал "Лабиринт отражений" Сергея Лукьяненко? Там часто использовалось словосочетание "Отпусти меня"