WebGL "Blue spilled paint interactive"by Software RVG

HTML
<html><head> <title>WebGL "Blue spilled paint" by Software RVG</title> <html style="" class=" js flexbox canvas canvastext webgl no-touch geolocation postmessage no-websqldatabase indexeddb hashchange history draganddrop websockets rgba hsla multiplebgs backgroundsize borderimage borderradius boxshadow textshadow opacity cssanimations csscolumns cssgradients no-cssreflections csstransforms csstransforms3d csstransitions fontface generatedcontent video audio localstorage sessionstorage webworkers applicationcache svg inlinesvg smil svgclippaths -moz- js flexbox canvas canvastext webgl no-touch geolocation postmessage no-websqldatabase indexeddb hashchange history draganddrop websockets rgba hsla multiplebgs backgroundsize borderimage borderradius boxshadow textshadow opacity cssanimations csscolumns cssgradients no-cssreflections csstransforms csstransforms3d csstransitions fontface generatedcontent video audio localstorage sessionstorage webworkers applicationcache svg inlinesvg smil svgclippaths -moz-"><head> <style class="cp-pen-styles">@charset "UTF-8"; @import url("//fonts.googleapis.com/css?family=Roboto:500&text=Softw@re "); @import url("//fonts.googleapis.com/css?family=Roboto:500&text=RVG"); @import url("//fonts.googleapis.com/css?family=Roboto:100&text=CSS3 "); body { min-height: 450px; height: 100vh; margin: 0; background: radial-gradient(circle, #0077ea, #1f4f96, #1b2949, #000000); } .stage { height: 300px; width: 500px; margin: auto; position: absolute; top: 0; right: 0; bottom: 0; left: 0; perspective: 9999px; transform-style: preserve-3d; } .layer { width: 100%; height: 100%; position: absolute; transform-style: preserve-3d; opacity: 0; animation: ಠ_ಠ 5s infinite alternate ease-in-out -7.5s, o_O 0.1s 1; animation-fill-mode: forwards; transform: rotateY(40deg) rotateX(33deg) translateZ(0); } .layer:after { font: 100px/0.65 'Pacifico', 'Kaushan Script', Futura, 'Roboto', 'Trebuchet MS', Helvetica, sans-serif; content: 'Softw@re\A RVG'; white-space: pre; text-align: center; height: 100%; width: 100%; position: absolute; top: 50px; color: whitesmoke; letter-spacing: -5px; text-shadow: 4px 0 10px rgba(0, 0, 0, 0.13); } .layer:nth-child(1):after { transform: translateZ(0px); } .layer:nth-child(2):after { transform: translateZ(-2px); } .layer:nth-child(3):after { transform: translateZ(-4px); } .layer:nth-child(4):after { transform: translateZ(-6px); } .layer:nth-child(5):after { transform: translateZ(-8px); } .layer:nth-child(6):after { transform: translateZ(-10px); } .layer:nth-child(7):after { transform: translateZ(-12px); } .layer:nth-child(8):after { transform: translateZ(-14px); } .layer:nth-child(9):after { transform: translateZ(-16px); } .layer:nth-child(10):after { transform: translateZ(-18px); } .layer:nth-child(11):after { transform: translateZ(-20px); } .layer:nth-child(12):after { transform: translateZ(-22px); } .layer:nth-child(13):after { transform: translateZ(-24px); } .layer:nth-child(14):after { transform: translateZ(-26px); } .layer:nth-child(15):after { transform: translateZ(-28px); } .layer:nth-child(16):after { transform: translateZ(-30px); } .layer:nth-child(17):after { transform: translateZ(-32px); } .layer:nth-child(18):after { transform: translateZ(-34px); } .layer:nth-child(19):after { transform: translateZ(-36px); } .layer:nth-child(20):after { transform: translateZ(-38px); } .layer:nth-child(n+10):after { -webkit-text-stroke: 3px rgba(0, 0, 0, 0.25); } .layer:nth-child(n+11):after { -webkit-text-stroke: 15px dodgerblue; text-shadow: 6px 0 6px #00366b, 5px 5px 5px #002951, 0 6px 6px #00366b; } .layer:nth-child(n+12):after { -webkit-text-stroke: 15px #0077ea; } .layer:last-child:after { -webkit-text-stroke: 17px rgba(0, 0, 0, 0.1); } .layer:first-child:after { color: #fff; text-shadow: none; } @keyframes ಠ_ಠ { 100% { transform: rotateY(-40deg) rotateX(-43deg); } } @keyframes o_O { 100% { opacity: 1; } } </style></head><body> <div class="stage"> <div class="layer"></div> <div class="layer"></div> <div class="layer"></div> <div class="layer"></div> <div class="layer"></div> <div class="layer"></div> <div class="layer"></div> <div class="layer"></div> <div class="layer"></div> <div class="layer"></div> <div class="layer"></div> <div class="layer"></div> <div class="layer"></div> <div class="layer"></div> <div class="layer"></div> <div class="layer"></div> <div class="layer"></div> <div class="layer"></div> <div class="layer"></div> <div class="layer"></div> </div> <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> <meta charset="utf-8"> </body></html> <script id="shader-vs" type="x-shader/x-vertex"> attribute vec3 aPos; attribute vec2 aTexCoord; varying vec2 pixel; void main(void) { gl_Position = vec4(aPos, 1.); pixel = aTexCoord; } </script> <script id="shader-fs-blur-horizontal" type="x-shader/x-fragment"> #ifdef GL_ES precision highp float; #endif // original shader from http://www.gamerendering.com/2008/10/11/gaussian-blur-filter-shader/ // horizontal blur fragment shader uniform sampler2D src_tex; varying vec2 pixel; uniform vec2 pixelSize; void main(void) // fragment { float h = pixelSize.x; vec4 sum = vec4(0.0); sum += texture2D(src_tex, vec2(pixel.x - 4.0*h, pixel.y) ) * 0.05; sum += texture2D(src_tex, vec2(pixel.x - 3.0*h, pixel.y) ) * 0.09; sum += texture2D(src_tex, vec2(pixel.x - 2.0*h, pixel.y) ) * 0.12; sum += texture2D(src_tex, vec2(pixel.x - 1.0*h, pixel.y) ) * 0.15; sum += texture2D(src_tex, vec2(pixel.x + 0.0*h, pixel.y) ) * 0.16; sum += texture2D(src_tex, vec2(pixel.x + 1.0*h, pixel.y) ) * 0.15; sum += texture2D(src_tex, vec2(pixel.x + 2.0*h, pixel.y) ) * 0.12; sum += texture2D(src_tex, vec2(pixel.x + 3.0*h, pixel.y) ) * 0.09; sum += texture2D(src_tex, vec2(pixel.x + 4.0*h, pixel.y) ) * 0.05; gl_FragColor.xyz = sum.xyz/0.98; // normalize gl_FragColor.a = 1.; } </script> <script id="shader-fs-blur-vertical" type="x-shader/x-fragment"> #ifdef GL_ES precision highp float; #endif // original shader from http://www.gamerendering.com/2008/10/11/gaussian-blur-filter-shader/ // vertical blur fragment shader uniform sampler2D src_tex; varying vec2 pixel; uniform vec2 pixelSize; void main(void) // fragment { float v = pixelSize.y; vec4 sum = vec4(0.0); sum += texture2D(src_tex, vec2(pixel.x, - 4.0*v + pixel.y) ) * 0.05; sum += texture2D(src_tex, vec2(pixel.x, - 3.0*v + pixel.y) ) * 0.09; sum += texture2D(src_tex, vec2(pixel.x, - 2.0*v + pixel.y) ) * 0.12; sum += texture2D(src_tex, vec2(pixel.x, - 1.0*v + pixel.y) ) * 0.15; sum += texture2D(src_tex, vec2(pixel.x, + 0.0*v + pixel.y) ) * 0.16; sum += texture2D(src_tex, vec2(pixel.x, + 1.0*v + pixel.y) ) * 0.15; sum += texture2D(src_tex, vec2(pixel.x, + 2.0*v + pixel.y) ) * 0.12; sum += texture2D(src_tex, vec2(pixel.x, + 3.0*v + pixel.y) ) * 0.09; sum += texture2D(src_tex, vec2(pixel.x, + 4.0*v + pixel.y) ) * 0.05; gl_FragColor.xyz = sum.xyz/0.98; gl_FragColor.a = 1.; } </script> <script id="shader-fs-advance" type="x-shader/x-fragment"> #ifdef GL_ES precision highp float; #endif uniform sampler2D sampler_prev; uniform sampler2D sampler_prev_n; uniform sampler2D sampler_blur; uniform sampler2D sampler_noise; uniform sampler2D sampler_noise_n; varying vec2 pixel; uniform vec2 pixelSize; uniform vec4 rnd; uniform vec2 mouse; uniform float time; uniform float fps; void main(void) { // grabbing the blurred gradients vec2 d = pixelSize*4.; vec4 dx = (texture2D(sampler_blur, pixel + vec2(1,0)*d) - texture2D(sampler_blur, pixel - vec2(1,0)*d))*0.5; vec4 dy = (texture2D(sampler_blur, pixel + vec2(0,1)*d) - texture2D(sampler_blur, pixel - vec2(0,1)*d))*0.5; vec2 zoom_in = pixel + vec2(dx.x,dy.x)*pixelSize*8.; // adding the traveling wave front vec2 rand_noise = texture2D(sampler_noise, zoom_in + vec2(rnd.x, rnd.y)).xy; gl_FragColor.x = texture2D(sampler_prev, zoom_in).x + (rand_noise.x-0.5)*0.0025 - 0.002; // decay with error diffusion gl_FragColor.x -= (texture2D(sampler_blur, zoom_in + (rand_noise-0.5)*pixelSize).x - texture2D(sampler_prev, zoom_in + (rand_noise-0.5)*pixelSize)).x*0.047; // reaction-diffusion gl_FragColor.a = 1.; } </script> <script id="shader-fs-composite" type="x-shader/x-fragment"> #ifdef GL_ES precision highp float; #endif uniform sampler2D sampler_prev; uniform sampler2D sampler_prev_n; uniform sampler2D sampler_blur; uniform sampler2D sampler_noise; uniform sampler2D sampler_noise_n; varying vec2 pixel; uniform vec2 pixelSize; uniform vec2 aspect; uniform vec4 rnd; uniform vec2 mouse; uniform float time; void main(void) { vec2 lightSize=vec2(4.); // grabbing the blurred gradients vec2 d = pixelSize*2.; vec4 dx = (texture2D(sampler_blur, pixel + vec2(1,0)*d) - texture2D(sampler_blur, pixel - vec2(1,0)*d))*0.5; vec4 dy = (texture2D(sampler_blur, pixel + vec2(0,1)*d) - texture2D(sampler_blur, pixel - vec2(0,1)*d))*0.5; // adding the pixel gradients d = pixelSize*1.; dx += texture2D(sampler_prev, pixel + vec2(1,0)*d) - texture2D(sampler_prev, pixel - vec2(1,0)*d); dy += texture2D(sampler_prev, pixel + vec2(0,1)*d) - texture2D(sampler_prev, pixel - vec2(0,1)*d); vec2 displacement = vec2(dx.x,dy.x)*lightSize; // using only the red gradient as displacement vector float light = pow(max(1.-distance(0.5+(pixel-0.5)*aspect*lightSize + displacement,0.5+(mouse-0.5)*aspect*lightSize),0.),4.); // vec4 rd = 0.85-(1.-texture2D(sampler_prev,pixel-vec2(dx.x,dy.x)*pixelSize*2.5).x) + light*0.18; //rd = mix(rd, 1., light*(1.-texture2D(sampler_blur,pixel-vec2(dx.x,dy.x)*pixelSize*4.)).x); // recoloring the lit up red channel vec4 rd = vec4(texture2D(sampler_prev,pixel+vec2(dx.x,dy.x)*pixelSize*8.).x)*vec4(0.7,1.5,2.0,1.0)-vec4(0.3,1.0,1.0,1.0); gl_FragColor = mix(rd,vec4(8.0,6.,2.,1.), light*0.75*vec4(1.-texture2D(sampler_prev,pixel+vec2(dx.x,dy.x)*pixelSize*8.).x)); //gl_FragColor = texture2D(sampler_prev, pixel); // bypass gl_FragColor.a = 1.; } </script> <script type="text/javascript"> function getShader(gl, id) { var shaderScript = document.getElementById(id); var str = ""; var k = shaderScript.firstChild; while (k) { if (k.nodeType == 3) str += k.textContent; k = k.nextSibling; } var shader; if (shaderScript.type == "x-shader/x-fragment") shader = gl.createShader(gl.FRAGMENT_SHADER); else if (shaderScript.type == "x-shader/x-vertex") shader = gl.createShader(gl.VERTEX_SHADER); else return null; gl.shaderSource(shader, str); gl.compileShader(shader); if (gl.getShaderParameter(shader, gl.COMPILE_STATUS) == 0) alert(gl.getShaderInfoLog(shader)); return shader; } requestAnimFrame = (function() { return window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback, element) { setTimeout(callback, 1000 / 60); }; })(); var gl; var prog_advance; var prog_composite; var prog_blur_horizontal; var prog_blur_vertical; var FBO_main; var FBO_main2; var FBO_helper; var FBO_blur; var FBO_noise; var texture_main_l; // main, linear var texture_main_n; // main, nearest (accurate pixel access on the same buffer) var texture_main2_l; // main double buffer, linear var texture_main2_n; // main double buffer, nearest (accurate pixel access on the same buffer) var texture_helper; // to be used when a buffer for multi-pass shader programs is needed (2-pass Gaussian blur) var texture_blur; // blur result var texture_noise_n; // noise pixel accurate var texture_noise_l; // noise interpolated pixel access var halted = false; var delay = 3; var it = 1; var frames = 0; var fps = 60; // no hurdle for DX10 graphics cards var time; var mouseX = 0.5; var mouseY = 0.5; var animation; var timer; // texture size (must be powers of two, remember 2048x1024 flat could also be a 128x128x128 voxel) var sizeX = 1024; var sizeY = 1024; // 2048x1024 flat or 128x128x128 cube // viewport size var viewX = 1024; var viewY = 1024; function load() { clearInterval(timer); var c = document.getElementById("c"); try { gl = c.getContext("experimental-webgl", { depth : false }); } catch (e) { } if (!gl) { alert("Your browser does not support WebGL"); return; } document.onmousemove = function(evt) { mouseX = evt.pageX / viewX; mouseY = 1 - evt.pageY / viewY; }; document.onclick = function(evt) { halted = !halted; }; c.width = viewX; c.height = viewY; prog_advance = gl.createProgram(); gl.attachShader(prog_advance, getShader(gl, "shader-vs")); gl.attachShader(prog_advance, getShader(gl, "shader-fs-advance")); gl.linkProgram(prog_advance); prog_composite = gl.createProgram(); gl.attachShader(prog_composite, getShader(gl, "shader-vs")); gl.attachShader(prog_composite, getShader(gl, "shader-fs-composite")); gl.linkProgram(prog_composite); prog_blur_horizontal = gl.createProgram(); gl.attachShader(prog_blur_horizontal, getShader(gl, "shader-vs")); gl.attachShader(prog_blur_horizontal, getShader(gl, "shader-fs-blur-horizontal")); gl.linkProgram(prog_blur_horizontal); prog_blur_vertical = gl.createProgram(); gl.attachShader(prog_blur_vertical, getShader(gl, "shader-vs")); gl.attachShader(prog_blur_vertical, getShader(gl, "shader-fs-blur-vertical")); gl.linkProgram(prog_blur_vertical); var posBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, posBuffer); var vertices = new Float32Array([ -1, -1, 0, 1, -1, 0, -1, 1, 0, 1, 1, 0 ]); var aPosLoc = gl.getAttribLocation(prog_advance, "aPos"); gl.enableVertexAttribArray(aPosLoc); var aTexLoc = gl.getAttribLocation(prog_advance, "aTexCoord"); gl.enableVertexAttribArray(aTexLoc); var texCoords = new Float32Array([ 0, 0, 1, 0, 0, 1, 1, 1 ]); var texCoordOffset = vertices.byteLength; gl.bufferData(gl.ARRAY_BUFFER, texCoordOffset + texCoords.byteLength, gl.STATIC_DRAW); gl.bufferSubData(gl.ARRAY_BUFFER, 0, vertices); gl.bufferSubData(gl.ARRAY_BUFFER, texCoordOffset, texCoords); gl.vertexAttribPointer(aPosLoc, 3, gl.FLOAT, gl.FALSE, 0, 0); gl.vertexAttribPointer(aTexLoc, 2, gl.FLOAT, gl.FALSE, 0, texCoordOffset); var noisepixels = []; var pixels = []; for ( var i = 0; i < sizeX; i++) { for ( var j = 0; j < sizeY; j++) { noisepixels.push(Math.random() * 255, Math.random() * 255, Math.random() * 255, 255); pixels.push(0, 0, 0, 255); } } /* * if (Math.random() > density) pixels.push(0, 0, 0, 0); else pixels.push(255, 0, 0, 0); */ var rawData = new Uint8Array(noisepixels); texture_main_l = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, texture_main_l); gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, sizeX, sizeY, 0, gl.RGBA, gl.UNSIGNED_BYTE, rawData); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); texture_main_n = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, texture_main_n); gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, sizeX, sizeY, 0, gl.RGBA, gl.UNSIGNED_BYTE, rawData); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); rawData = new Uint8Array(noisepixels); rawData = new Uint8Array(noisepixels); texture_main2_l = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, texture_main2_l); gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, sizeX, sizeY, 0, gl.RGBA, gl.UNSIGNED_BYTE, rawData); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); texture_main2_n = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, texture_main2_n); gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, sizeX, sizeY, 0, gl.RGBA, gl.UNSIGNED_BYTE, rawData); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); rawData = new Uint8Array(pixels); texture_helper = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, texture_helper); gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, sizeX, sizeY, 0, gl.RGBA, gl.UNSIGNED_BYTE, rawData); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); rawData = new Uint8Array(pixels); texture_blur = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, texture_blur); gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, sizeX, sizeY, 0, gl.RGBA, gl.UNSIGNED_BYTE, rawData); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); rawData = new Uint8Array(noisepixels); texture_noise_l = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, texture_noise_l); gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, sizeX, sizeY, 0, gl.RGBA, gl.UNSIGNED_BYTE, rawData); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); texture_noise_n = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, texture_noise_n); gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, sizeX, sizeY, 0, gl.RGBA, gl.UNSIGNED_BYTE, rawData); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); // gl.uniform1i(gl.getUniformLocation(prog, "uTexSamp"), 0); FBO_main = gl.createFramebuffer(); gl.bindFramebuffer(gl.FRAMEBUFFER, FBO_main); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture_main_l, 0); FBO_main2 = gl.createFramebuffer(); gl.bindFramebuffer(gl.FRAMEBUFFER, FBO_main2); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture_main2_l, 0); FBO_helper = gl.createFramebuffer(); gl.bindFramebuffer(gl.FRAMEBUFFER, FBO_helper); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture_helper, 0); FBO_blur = gl.createFramebuffer(); gl.bindFramebuffer(gl.FRAMEBUFFER, FBO_blur); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture_blur, 0); FBO_noise = gl.createFramebuffer(); gl.bindFramebuffer(gl.FRAMEBUFFER, FBO_noise); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture_noise_l, 0); gl.useProgram(prog_advance); setUniforms(prog_advance); gl.useProgram(prog_blur_horizontal); gl.uniform2f(gl.getUniformLocation(prog_blur_horizontal, "pixelSize"), 1. / sizeX, 1. / sizeY); gl.uniform1i(gl.getUniformLocation(prog_blur_horizontal, "src_tex"), 0); gl.useProgram(prog_blur_vertical); gl.uniform2f(gl.getUniformLocation(prog_blur_vertical, "pixelSize"), 1. / sizeX, 1. / sizeY); gl.uniform1i(gl.getUniformLocation(prog_blur_vertical, "src_tex"), 0); gl.useProgram(prog_composite); setUniforms(prog_composite); gl.activeTexture(gl.TEXTURE2); gl.bindTexture(gl.TEXTURE_2D, texture_blur); gl.activeTexture(gl.TEXTURE3); gl.bindTexture(gl.TEXTURE_2D, texture_noise_l); gl.activeTexture(gl.TEXTURE4); gl.bindTexture(gl.TEXTURE_2D, texture_noise_n); calculateBlurTexture(); timer = setInterval(fr, 500); time = new Date().getTime(); animation = "animate"; anim(); } function setUniforms(program) { gl.uniform2f(gl.getUniformLocation(program, "pixelSize"), 1. / sizeX, 1. / sizeY); gl.uniform4f(gl.getUniformLocation(program, "rnd"), Math.random(), Math.random(), Math.random(), Math.random()); gl.uniform1f(gl.getUniformLocation(program, "fps"), fps); gl.uniform1f(gl.getUniformLocation(program, "time"), time); gl.uniform2f(gl.getUniformLocation(program, "aspect"), Math.max(1, viewX / viewY), Math.max(1, viewY / viewX)); gl.uniform2f(gl.getUniformLocation(program, "mouse"), mouseX, mouseY); gl.uniform1i(gl.getUniformLocation(program, "sampler_prev"), 0); gl.uniform1i(gl.getUniformLocation(program, "sampler_prev_n"), 1); gl.uniform1i(gl.getUniformLocation(program, "sampler_blur"), 2); gl.uniform1i(gl.getUniformLocation(program, "sampler_noise"), 3); gl.uniform1i(gl.getUniformLocation(program, "sampler_noise_n"), 4); } function calculateBlurTexture() { // horizontal gl.viewport(0, 0, sizeX, sizeY); gl.useProgram(prog_blur_horizontal); gl.activeTexture(gl.TEXTURE0); if (it < 0) { gl.bindTexture(gl.TEXTURE_2D, texture_main2_l); gl.bindFramebuffer(gl.FRAMEBUFFER, FBO_helper); } else { gl.bindTexture(gl.TEXTURE_2D, texture_main_l); gl.bindFramebuffer(gl.FRAMEBUFFER, FBO_helper); } gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); gl.flush(); // vertical gl.viewport(0, 0, sizeX, sizeY); gl.useProgram(prog_blur_vertical); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, texture_helper); gl.bindFramebuffer(gl.FRAMEBUFFER, FBO_blur); gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); gl.flush(); gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); gl.flush(); } function advance() { gl.viewport(0, 0, sizeX, sizeY); gl.useProgram(prog_advance); setUniforms(prog_advance); if (it > 0) { gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, texture_main_l); // interpolated input gl.activeTexture(gl.TEXTURE1); gl.bindTexture(gl.TEXTURE_2D, texture_main_n); // "nearest" input gl.bindFramebuffer(gl.FRAMEBUFFER, FBO_main2); // write to buffer } else { gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, texture_main2_l); // interpolated gl.activeTexture(gl.TEXTURE1); gl.bindTexture(gl.TEXTURE_2D, texture_main2_n); // "nearest" gl.bindFramebuffer(gl.FRAMEBUFFER, FBO_main); // write to buffer } gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); gl.flush(); calculateBlurTexture(); it = -it; } function composite() { gl.viewport(0, 0, viewX, viewY); gl.useProgram(prog_composite); setUniforms(prog_composite); if (it < 0) { gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, texture_main_l); gl.activeTexture(gl.TEXTURE1); gl.bindTexture(gl.TEXTURE_2D, texture_main_n); } else { gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, texture_main2_l); gl.activeTexture(gl.TEXTURE1); gl.bindTexture(gl.TEXTURE_2D, texture_main2_n); } gl.bindFramebuffer(gl.FRAMEBUFFER, null); gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); gl.flush(); frames++; } function anim() { if (!halted) advance(); composite(); switch (animation) { case "animate": setTimeout("requestAnimFrame(anim)", delay); break; case "reset": load(); break; } } function setDelay(v) { delay = parseInt(v); } function fr() { var ti = new Date().getTime(); fps = Math.round(1000 * frames / (ti - time)); document.getElementById("fps").textContent = fps; frames = 0; time = ti; } </script> <style type="text/css"> body { background-color: #000000; color: #FFFFFF; text-shadow: #000000; } #c { position: absolute; top: 0; left: 0; z-index: -1; } </style> </head> <body onload="load()"> <canvas height="1024" width="1024" id="c"></canvas> </p></body></html>
CSS
body { min-height: 450px; height: 100vh; margin: 0; background: radial-gradient(circle, #0077ea, #1f4f96, #1b2949, #000000); } .stage { height: 300px; width: 500px; margin: auto; position: absolute; top: 0; right: 0; bottom: 0; left: 0; perspective: 9999px; transform-style: preserve-3d; } .layer { width: 100%; height: 100%; position: absolute; transform-style: preserve-3d; opacity: 0; animation: ಠ_ಠ 5s infinite alternate ease-in-out -7.5s, o_O 0.1s 1; animation-fill-mode: forwards; transform: rotateY(40deg) rotateX(33deg) translateZ(0); } .layer:after { font: 200px/0.65 metabold; content: 'mozilla \A \A '; white-space: pre; text-align: center; height: 100%; width: 100%; position: absolute; top: 50px; color: whitesmoke; letter-spacing: -5px; text-shadow: 4px 0 10px rgba(0, 0, 0, 0.13); } .layer:nth-child(1):after { transform: translateZ(0px); } .layer:nth-child(2):after { transform: translateZ(-2px); } .layer:nth-child(3):after { transform: translateZ(-4px); } .layer:nth-child(4):after { transform: translateZ(-6px); } .layer:nth-child(5):after { transform: translateZ(-8px); } .layer:nth-child(6):after { transform: translateZ(-10px); } .layer:nth-child(7):after { transform: translateZ(-12px); } .layer:nth-child(8):after { transform: translateZ(-14px); } .layer:nth-child(9):after { transform: translateZ(-16px); } .layer:nth-child(10):after { transform: translateZ(-18px); } .layer:nth-child(11):after { transform: translateZ(-20px); } .layer:nth-child(12):after { transform: translateZ(-22px); } .layer:nth-child(13):after { transform: translateZ(-24px); } .layer:nth-child(14):after { transform: translateZ(-26px); } .layer:nth-child(15):after { transform: translateZ(-28px); } .layer:nth-child(16):after { transform: translateZ(-30px); } .layer:nth-child(17):after { transform: translateZ(-32px); } .layer:nth-child(18):after { transform: translateZ(-34px); } .layer:nth-child(19):after { transform: translateZ(-36px); } .layer:nth-child(20):after { transform: translateZ(-38px); } .layer:nth-child(n+10):after { -webkit-text-stroke: 3px rgba(0, 0, 0, 0.25); } .layer:nth-child(n+11):after { -webkit-text-stroke: 15px dodgerblue; text-shadow: 3px 0 3px #ff4000, 2px 2px 2px #ff4000, 0 3px 3px #ff4000; } .layer:nth-child(n+12):after { -webkit-text-stroke: 15px #0077ea; } .layer:last-child:after { -webkit-text-stroke: 17px rgba(0, 0, 0, 0.1); } .layer:first-child:after { color: #fff; text-shadow: none; } @keyframes ಠ_ಠ { 100% { transform: rotateY(-40deg) rotateX(-43deg); } } @keyframes o_O { 100% { opacity: 1; } } .layer { width: 100%; height: 100%; position: absolute; transform-style: preserve-3d; opacity: 0; animation: ಠ_ಠ 5s infinite alternate ease-in-out -7.5s, o_O 0.1s 1; animation-fill-mode: forwards; transform: rotateY(40deg) rotateX(33deg) translateZ(0); }
JAVASCRIPT
<script id="shader-fs-blur-horizontal" type="x-shader/x-fragment"> #ifdef GL_ES precision highp float; #endif uniform sampler2D src_tex; varying vec2 pixel; uniform vec2 pixelSize; void main(void) // fragment { float h = pixelSize.x; vec4 sum = vec4(0.0); sum += texture2D(src_tex, vec2(pixel.x - 4.0*h, pixel.y) ) * 0.05; sum += texture2D(src_tex, vec2(pixel.x - 3.0*h, pixel.y) ) * 0.09; sum += texture2D(src_tex, vec2(pixel.x - 2.0*h, pixel.y) ) * 0.12; sum += texture2D(src_tex, vec2(pixel.x - 1.0*h, pixel.y) ) * 0.15; sum += texture2D(src_tex, vec2(pixel.x + 0.0*h, pixel.y) ) * 0.16; sum += texture2D(src_tex, vec2(pixel.x + 1.0*h, pixel.y) ) * 0.15; sum += texture2D(src_tex, vec2(pixel.x + 2.0*h, pixel.y) ) * 0.12; sum += texture2D(src_tex, vec2(pixel.x + 3.0*h, pixel.y) ) * 0.09; sum += texture2D(src_tex, vec2(pixel.x + 4.0*h, pixel.y) ) * 0.05; gl_FragColor.xyz = sum.xyz/0.98; // normalize gl_FragColor.a = 1.; } </script>
Expand for more options Login