Реалистичное пламя на HTML5 Canvas
Шикарное реалистичное пламя для вашего сайта. К сожалению, я не смог вытащить все исходники пламени и в нём осталась зависимость от одного из проектов codepen
Для начала посмотрите ДЕМО
Установка:
1#: В самый низ вашего CSS вставьте:
1 2 3 4 5 |
#view { position: fixed; top: 0; left: 0; } |
2#: На странице, где должен быть данный эффект, после тега head вставьте:
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 |
<canvas id="view"></canvas> <script id="flame-frag" type="x-shader/x-vertex"> /** * Original shader by @kuvkar (https://www.shadertoy.com/view/4tXXRn) */ varying vec2 vTextureCoord; uniform sampler2D uSampler; uniform sampler2D mapSampler; uniform vec4 filterArea; uniform vec2 dimensions; uniform float time; float rand(vec2 co) { return fract(sin(dot(co.xy ,vec2(12.9898, 78.233))) * 43758.5453); } mat2 rotz(float angle) { mat2 m; m[0][0] = cos(angle); m[0][1] = -sin(angle); m[1][0] = sin(angle); m[1][1] = cos(angle); return m; } // Fractal Brownian Motion float fbm(vec2 uv) { float n = (texture2D(mapSampler, uv).r - 0.5) * 0.5; n += (texture2D(mapSampler, uv * 2.0).r - 0.5) * 0.5 * 0.5; n += (texture2D(mapSampler, uv * 3.0).r - 0.5) * 0.5 * 0.5 * 0.5; return n + 0.5; } void main() { vec2 uv = (vTextureCoord * filterArea.xy) / dimensions; uv.y = 1.0 - uv.y; vec2 _uv = uv; uv -= vec2(0.5); uv.y /= dimensions.x / dimensions.y; vec2 centerUV = uv; // height variation from fbm float variationH = fbm(vec2(time * 0.3)) * 1.1; // flame "speed" vec2 offset = vec2(0.0, -time * 0.05); // flame turbulence float f = fbm(uv * 0.1 + offset); // rotation from fbm float l = max(0.1, length(uv)); // rotation amount normalized over distance uv += rotz(((f - 0.5) / l) * smoothstep(-0.2, 0.4, _uv.y) * 0.45) * uv; // flame thickness float flame = 1.3 - length(uv.x) * 5.0; // bottom of flame float blueflame = pow(flame * 0.9, 15.0); blueflame *= smoothstep(0.2, -1.0, _uv.y); blueflame /= abs(uv.x * 2.0); blueflame = clamp(blueflame, 0.0, 1.0); // flame flame *= smoothstep(1.0, variationH * 0.5, _uv.y); flame = clamp(flame, 0.0, 1.0); flame = pow(flame, 3.0); flame /= smoothstep(1.1, -0.1, _uv.y); // colors vec4 col = mix(vec4(1.0, 1.0, 0.0, 0.0), vec4(1.0, 1.0, 0.6, 0.0), flame); col = mix(vec4(1.0, 0.0, 0.0, 0.0), col, smoothstep(0.0, 1.6, flame)); gl_FragColor = col; // a bit blueness on the bottom vec4 bluecolor = mix(vec4(0.0, 0.0, 1.0, 0.0), gl_FragColor, 0.95); gl_FragColor = mix(gl_FragColor, bluecolor, blueflame); // clear bg outside of the flame gl_FragColor *= flame; gl_FragColor.a = flame; // bg halo float haloSize = 0.5; float centerL = 1.0 - (length(centerUV + vec2(0.0, 0.1)) / haloSize); vec4 halo = vec4(0.8, 0.3, 0.3, 0.0) * 1.0 * fbm(vec2(time * 0.035)) * centerL + 0.02; vec4 finalCol = mix(halo, gl_FragColor, gl_FragColor.a); gl_FragColor = finalCol; // just a hint of noise gl_FragColor *= mix(rand(uv) + rand(uv * 0.45), 1.0, 0.9); gl_FragColor = clamp(gl_FragColor, 0.0, 1.0); } </script> <script src='/js/flame.js'></script> |