Don't like ads? PRO users don't see any ads ;-)
Guest

Untitled

By: a guest on May 22nd, 2012  |  syntax: None  |  size: 30.47 KB  |  hits: 14  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>WebGL Shader Lab</title>
  5. <script id="shader-vs" type="x-shader/x-vertex">
  6.  
  7.   attribute vec3 aPos;
  8.   attribute vec2 aTexCoord;
  9.   varying   vec2 pixel;
  10. void main(void) {
  11.    gl_Position = vec4(aPos, 1.);
  12.    pixel = aTexCoord;
  13. }
  14. </script>
  15.  
  16. <script id="shader-fs-blur-horizontal" type="x-shader/x-fragment">
  17. #ifdef GL_ES
  18. precision highp float;
  19. #endif
  20. // original shader from http://www.gamerendering.com/2008/10/11/gaussian-blur-filter-shader/
  21. // horizontal blur fragment shader
  22. uniform sampler2D src_tex;
  23. varying vec2 pixel;
  24. uniform vec2 pixelSize;
  25. void main(void) // fragment
  26. {
  27.         float h = pixelSize.x;
  28.         vec4 sum = vec4(0.0);
  29.         sum += texture2D(src_tex, vec2(pixel.x - 4.0*h, pixel.y) ) * 0.05;
  30.         sum += texture2D(src_tex, vec2(pixel.x - 3.0*h, pixel.y) ) * 0.09;
  31.         sum += texture2D(src_tex, vec2(pixel.x - 2.0*h, pixel.y) ) * 0.12;
  32.         sum += texture2D(src_tex, vec2(pixel.x - 1.0*h, pixel.y) ) * 0.15;
  33.         sum += texture2D(src_tex, vec2(pixel.x + 0.0*h, pixel.y) ) * 0.16;
  34.         sum += texture2D(src_tex, vec2(pixel.x + 1.0*h, pixel.y) ) * 0.15;
  35.         sum += texture2D(src_tex, vec2(pixel.x + 2.0*h, pixel.y) ) * 0.12;
  36.         sum += texture2D(src_tex, vec2(pixel.x + 3.0*h, pixel.y) ) * 0.09;
  37.         sum += texture2D(src_tex, vec2(pixel.x + 4.0*h, pixel.y) ) * 0.05;
  38.     gl_FragColor.xyz = sum.xyz/0.98; // normalize
  39.         gl_FragColor.a = 1.;
  40. }
  41. </script>
  42.  
  43. <script id="shader-fs-blur-vertical" type="x-shader/x-fragment">
  44. #ifdef GL_ES
  45. precision highp float;
  46. #endif
  47. // original shader from http://www.gamerendering.com/2008/10/11/gaussian-blur-filter-shader/
  48. // vertical blur fragment shader
  49. uniform sampler2D src_tex;
  50. varying vec2 pixel;
  51. uniform vec2 pixelSize;
  52. void main(void) // fragment
  53. {
  54.         float v = pixelSize.y;
  55.         vec4 sum = vec4(0.0);
  56.         sum += texture2D(src_tex, vec2(pixel.x, - 4.0*v + pixel.y) ) * 0.05;
  57.         sum += texture2D(src_tex, vec2(pixel.x, - 3.0*v + pixel.y) ) * 0.09;
  58.         sum += texture2D(src_tex, vec2(pixel.x, - 2.0*v + pixel.y) ) * 0.12;
  59.         sum += texture2D(src_tex, vec2(pixel.x, - 1.0*v + pixel.y) ) * 0.15;
  60.         sum += texture2D(src_tex, vec2(pixel.x, + 0.0*v + pixel.y) ) * 0.16;
  61.         sum += texture2D(src_tex, vec2(pixel.x, + 1.0*v + pixel.y) ) * 0.15;
  62.         sum += texture2D(src_tex, vec2(pixel.x, + 2.0*v + pixel.y) ) * 0.12;
  63.         sum += texture2D(src_tex, vec2(pixel.x, + 3.0*v + pixel.y) ) * 0.09;
  64.         sum += texture2D(src_tex, vec2(pixel.x, + 4.0*v + pixel.y) ) * 0.05;
  65.     gl_FragColor.xyz = sum.xyz/0.98;
  66.         gl_FragColor.a = 1.;
  67. }
  68. </script>
  69.  
  70. <script id="shader-fs-advance" type="x-shader/x-fragment">
  71. #ifdef GL_ES
  72. precision highp float;
  73. #endif
  74.  
  75.         uniform sampler2D sampler_prev;
  76.         uniform sampler2D sampler_prev_n;
  77.         uniform sampler2D sampler_blur;
  78.         uniform sampler2D sampler_blur2;
  79.         uniform sampler2D sampler_blur3;
  80.         uniform sampler2D sampler_blur4;
  81.         uniform sampler2D sampler_noise;
  82.         uniform sampler2D sampler_noise_n;
  83.  
  84.         varying vec2 pixel;
  85.         uniform vec2 pixelSize;
  86.         uniform vec4 rnd;
  87.         uniform vec2 mouse;
  88.         uniform float time;
  89.         uniform float fps;
  90.  
  91.         uniform float x1;
  92.         uniform float y1;
  93.         uniform float d1;
  94.         uniform float x2;
  95.         uniform float y2;
  96.         uniform float d2;
  97.  
  98. float line_segment(vec2 domain, vec2 p1, float d1, vec2 p2, float d2){
  99.         float h = 1./(p2.x-p1.x); // helper registers
  100.         float h1 = (p2.y-p1.y)*h;
  101.         float h2 = 1./h1;
  102.         float xs = (-p1.y+h1*p1.x+h2*domain.x+domain.y)/(h2+h1);// coordinates of the point on the line between p1 and p2,
  103.         float ys = -h2*(xs-domain.x)+domain.y;                                  // ^ orthogonally to the given point in the domain
  104.         float d = length(domain-vec2(xs,ys));           // the orthogonal distance from the domain point to the line (unlimited)
  105.         float s = 0.; // distance from domain point to p1 relative to p2
  106.         if(p2.x == p1.x){       // division by zero fix
  107.                 d = abs(domain.x - p1.x);
  108.                 s = (p1.y-ys)/(p1.y-p2.y);
  109.         }else{
  110.                 s = (xs-p1.x)*h;                                                 
  111.         }
  112.         d = clamp(d*(d1*(1.-s)+d2*s),0., 1.);   // adjusting the line thickness using a linear interpolation with s
  113.         float m1 = 0.; if(s > 0.) m1 = 1.;              // masking out the segment between p1 and p2
  114.         float m2 = 0.; if(s < 1.) m2 = 1.;
  115.         float result = clamp( m1*m2-d, 0., 1.); // return result as 1-distance in the range [0..1]
  116.         result = clamp(1.-length(domain-vec2(p1.x,p1.y))*d1-m1, result, 1.);    // round corners if you will (half circles)
  117.         //result = clamp(1.-length(domain-vec2(p2.x,p2.y))*d2-m2, result, 1.);
  118.          
  119.         return result;
  120. }
  121.  
  122.         uniform float sin1;
  123.         uniform float cos1;
  124.         uniform float scale1;
  125.  
  126.         uniform float sin2;
  127.         uniform float cos2;
  128.         uniform float scale2;
  129.  
  130.         uniform float sin3;
  131.         uniform float cos3;
  132.  
  133.  
  134. vec2 complex_mul(vec2 factorA, vec2 factorB){
  135.    return vec2( factorA.x*factorB.x - factorA.y*factorB.y, factorA.x*factorB.y + factorA.y*factorB.x);
  136. }
  137.  
  138. float square_mask(vec2 domain){
  139.         return (domain.x <= 1. && domain.x >= 0. && domain.y <= 1. && domain.y >= 0.) ? 1. : 0.;
  140. }
  141.  
  142. void main(void) {
  143.  
  144.         vec3 color_increment =vec3(0.004,0.008,0.);
  145.  
  146.         vec2 pos1 = vec2(x1,y1);
  147.         vec2 pos2 = vec2(x2,y2);
  148.         vec2 c = vec2(0.5);
  149.  
  150.         gl_FragColor.xyz = vec3(1.-line_segment(pixel, pos1, d1, pos2, d2));
  151.  
  152.         // complex multiplication to rotate
  153.         vec2 uv_stem_feedback = complex_mul((pixel-pos2),vec2(cos1,sin1)*vec2(scale1)) + pos1;
  154.         vec3 stem_feedback = texture2D( sampler_prev, uv_stem_feedback).xyz + color_increment;
  155.         vec3 stem_feedback_mask = vec3(square_mask(uv_stem_feedback));
  156.         stem_feedback *= stem_feedback_mask;
  157.         stem_feedback += vec3(1.)-stem_feedback_mask;
  158.        
  159.         vec2 uv_left_arm_feedback = complex_mul((pixel-pos2),vec2(cos2,sin2)*vec2(scale2)) + pos1;
  160.         vec3 left_arm_feedback = texture2D( sampler_prev, uv_left_arm_feedback).xyz + color_increment;
  161.         vec3 left_arm_feedback_mask = vec3(square_mask(uv_left_arm_feedback));
  162.         left_arm_feedback *= left_arm_feedback_mask;
  163.         left_arm_feedback += vec3(1.)-left_arm_feedback_mask;
  164.        
  165.         vec2 uv_right_arm_feedback = complex_mul((pixel-pos2),vec2(cos3,sin3)*vec2(scale2)) + pos1;
  166.         vec3 right_arm_feedback = texture2D( sampler_prev, uv_right_arm_feedback).xyz + color_increment;
  167.         vec3 right_arm_feedback_mask = vec3(square_mask(uv_right_arm_feedback));
  168.         right_arm_feedback *= right_arm_feedback_mask;
  169.         right_arm_feedback += vec3(1.)-right_arm_feedback_mask;
  170.        
  171.         gl_FragColor.xyz = min( gl_FragColor.xyz, min(stem_feedback, min(left_arm_feedback, right_arm_feedback)));
  172.  
  173.         gl_FragColor.xyz = mix( gl_FragColor.xyz, texture2D(sampler_prev, pixel).xyz, vec3(0.42)); // sort of a motion blur
  174.        
  175.         gl_FragColor.a = 1.;
  176. }
  177. </script>
  178.  
  179. <script id="shader-fs-composite" type="x-shader/x-fragment">
  180. #ifdef GL_ES
  181. precision highp float;
  182. #endif
  183.  
  184.         uniform sampler2D sampler_prev;
  185.         uniform sampler2D sampler_prev_n;
  186.         uniform sampler2D sampler_blur;
  187.         uniform sampler2D sampler_blur2;
  188.         uniform sampler2D sampler_blur3;
  189.         uniform sampler2D sampler_blur4;
  190.         uniform sampler2D sampler_noise;
  191.         uniform sampler2D sampler_noise_n;
  192.  
  193.         varying vec2 pixel;
  194.         uniform vec2 pixelSize;
  195.         uniform vec4 rnd;
  196.         uniform vec2 mouse;
  197.         uniform float time;
  198.         uniform float fps;
  199.  
  200. void main(void) {
  201.         gl_FragColor = texture2D(sampler_prev, pixel); // copy
  202.         gl_FragColor.a = 1.;
  203. }
  204. </script>
  205.  
  206. <script id="shader-fs-copy" type="x-shader/x-fragment">
  207. #ifdef GL_ES
  208. precision highp float;
  209. #endif
  210.         uniform sampler2D sampler_prev;
  211.         varying vec2 pixel;
  212. void main(void) {
  213.         gl_FragColor = texture2D(sampler_prev, pixel);
  214.         gl_FragColor.a = 1.;
  215. }
  216. </script>
  217.  
  218. <script type="text/javascript">
  219. function BrowserSize() {
  220.         if (typeof (window.innerWidth) == 'number') {
  221.                 //Non-IE
  222.                 this.width = window.innerWidth;
  223.                 this.height = window.innerHeight;
  224.         } else if (document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) {
  225.                 //IE 6+ in 'standards compliant mode'
  226.                 this.width = document.documentElement.clientWidth;
  227.                 this.height = document.documentElement.clientHeight;
  228.         } else if (document.body && (document.body.clientWidth || document.body.clientHeight)) {
  229.                 //IE 4 compatible
  230.                 this.width = document.body.clientWidth;
  231.                 this.height = document.body.clientHeight;
  232.         }
  233. }
  234. BrowserSize.prototype.width;
  235. BrowserSize.prototype.height;
  236.  
  237.         function getShader(gl, id) {
  238.                 var shaderScript = document.getElementById(id);
  239.                 var str = "";
  240.                 var k = shaderScript.firstChild;
  241.                 while (k) {
  242.                         if (k.nodeType == 3)
  243.                                 str += k.textContent;
  244.                         k = k.nextSibling;
  245.                 }
  246.                 var shader;
  247.                 if (shaderScript.type == "x-shader/x-fragment")
  248.                         shader = gl.createShader(gl.FRAGMENT_SHADER);
  249.                 else if (shaderScript.type == "x-shader/x-vertex")
  250.                         shader = gl.createShader(gl.VERTEX_SHADER);
  251.                 else
  252.                         return null;
  253.                 gl.shaderSource(shader, str);
  254.                 gl.compileShader(shader);
  255.                 if (gl.getShaderParameter(shader, gl.COMPILE_STATUS) == 0)
  256.                         alert(gl.getShaderInfoLog(shader));
  257.                 return shader;
  258.         }
  259.  
  260.         requestAnimFrame = (function() {
  261.                 return window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback, element) {
  262.                         setTimeout(callback, 1000 / 60);
  263.                 };
  264.         })();
  265.  
  266.         var gl;
  267.         var prog_copy;
  268.         var prog_advance;
  269.         var prog_composite;
  270.         var prog_blur_horizontal;
  271.         var prog_blur_vertical;
  272.         var FBO_main;
  273.         var FBO_main2;
  274.         var FBO_noise;
  275.         var FBO_blur;
  276.         var FBO_blur2;
  277.         var FBO_blur3;
  278.         var FBO_blur4;
  279.         var FBO_helper;
  280.         var FBO_helper2;
  281.         var FBO_helper3;
  282.         var FBO_helper4;
  283.         var texture_main_l; // main, linear
  284.         var texture_main_n; // main, nearest (accurate pixel access on the same buffer)
  285.         var texture_main2_l; // main double buffer, linear
  286.         var texture_main2_n; // main double buffer, nearest (accurate pixel access on the same buffer)
  287.         var texture_helper; // needed for multi-pass shader programs (2-pass Gaussian blur)
  288.         var texture_helper2; // (1/4 resolution )
  289.         var texture_helper3; // (1/16 resolution )
  290.         var texture_helper4; // (1/256 resolution )
  291.         var texture_blur; // full resolution blur result
  292.         var texture_blur2; // double blur
  293.         var texture_blur3; // quad blur
  294.         var texture_blur4; // really low resolution - use wisely ^^
  295.         var texture_noise_n; // noise pixel accurate
  296.         var texture_noise_l; // noise interpolated pixel access
  297.  
  298.         var halted = false;
  299.         var delay = 3;
  300.         var it = 1;
  301.         var frames = 0;
  302.         var fps = 60; // no hurdle for DX10 graphics cards
  303.         var time = 0;
  304.         var mouseX = 0.5;
  305.         var mouseY = 0.5;
  306.         var animation;
  307.         var timer;
  308.         // texture size (must be powers of two, remember 2048x1024 flat could also be a 128x128x128 voxel)
  309.         var sizeX = 2048;
  310.         var sizeY = 1024; // 2048x1024 flat or 128x128x128 cube
  311.         // viewport size
  312.         var viewX = 1024;
  313.         var viewY = 1024;
  314.  
  315.         var basetime = new Date().getTime();
  316.  
  317.         var c;
  318.         function setMaximalSize() {
  319.                 browserSize = new BrowserSize();
  320.                 c.width = viewX = browserSize.width;
  321.                 c.height = viewY = browserSize.height;
  322.         }
  323.  
  324.         function load() {
  325.                 clearInterval(timer);
  326.                 c = document.getElementById("c");
  327.                 try {
  328.                         gl = c.getContext("experimental-webgl", { depth : false });
  329.                 } catch (e) {
  330.                 }
  331.                 if (!gl) {
  332.                         alert("Your browser does not support WebGL");
  333.                         return;
  334.                 }
  335.                 document.onmousemove = function(evt) {
  336.                         mouseX = evt.pageX / viewX;
  337.                         mouseY = 1 - evt.pageY / viewY;
  338.  
  339.                 };
  340.                 document.onclick = function(evt) {
  341.                 //      halted = !halted;
  342.                 };
  343.  
  344.                 window.onresize = setMaximalSize;
  345.                 setMaximalSize();
  346.                
  347.                 c.width = viewX;
  348.                 c.height = viewY;
  349.  
  350.                 prog_copy = gl.createProgram();
  351.                 gl.attachShader(prog_copy, getShader(gl, "shader-vs"));
  352.                 gl.attachShader(prog_copy, getShader(gl, "shader-fs-copy"));
  353.                 gl.linkProgram(prog_copy);
  354.  
  355.                 prog_advance = gl.createProgram();
  356.                 gl.attachShader(prog_advance, getShader(gl, "shader-vs"));
  357.                 gl.attachShader(prog_advance, getShader(gl, "shader-fs-advance"));
  358.                 gl.linkProgram(prog_advance);
  359.  
  360.                 prog_composite = gl.createProgram();
  361.                 gl.attachShader(prog_composite, getShader(gl, "shader-vs"));
  362.                 gl.attachShader(prog_composite, getShader(gl, "shader-fs-composite"));
  363.                 gl.linkProgram(prog_composite);
  364.  
  365.                 prog_blur_horizontal = gl.createProgram();
  366.                 gl.attachShader(prog_blur_horizontal, getShader(gl, "shader-vs"));
  367.                 gl.attachShader(prog_blur_horizontal, getShader(gl, "shader-fs-blur-horizontal"));
  368.                 gl.linkProgram(prog_blur_horizontal);
  369.  
  370.                 prog_blur_vertical = gl.createProgram();
  371.                 gl.attachShader(prog_blur_vertical, getShader(gl, "shader-vs"));
  372.                 gl.attachShader(prog_blur_vertical, getShader(gl, "shader-fs-blur-vertical"));
  373.                 gl.linkProgram(prog_blur_vertical);
  374.  
  375.                 var posBuffer = gl.createBuffer();
  376.                 gl.bindBuffer(gl.ARRAY_BUFFER, posBuffer);
  377.  
  378.                 var vertices = new Float32Array([ -1, -1, 0, 1, -1, 0, -1, 1, 0, 1, 1, 0 ]);
  379.  
  380.                 var aPosLoc = gl.getAttribLocation(prog_advance, "aPos");
  381.                 gl.enableVertexAttribArray(aPosLoc);
  382.  
  383.                 var aTexLoc = gl.getAttribLocation(prog_advance, "aTexCoord");
  384.                 gl.enableVertexAttribArray(aTexLoc);
  385.  
  386.                 var texCoords = new Float32Array([ 0, 0, 1, 0, 0, 1, 1, 1 ]);
  387.  
  388.                 var texCoordOffset = vertices.byteLength;
  389.  
  390.                 gl.bufferData(gl.ARRAY_BUFFER, texCoordOffset + texCoords.byteLength, gl.STATIC_DRAW);
  391.                 gl.bufferSubData(gl.ARRAY_BUFFER, 0, vertices);
  392.                 gl.bufferSubData(gl.ARRAY_BUFFER, texCoordOffset, texCoords);
  393.                 gl.vertexAttribPointer(aPosLoc, 3, gl.FLOAT, gl.FALSE, 0, 0);
  394.                 gl.vertexAttribPointer(aTexLoc, 2, gl.FLOAT, gl.FALSE, 0, texCoordOffset);
  395.  
  396.                 var noisepixels = [];
  397.                 var pixels = [];
  398.                 for ( var i = 0; i < sizeX; i++) {
  399.                         for ( var j = 0; j < sizeY; j++) {
  400.                                 noisepixels.push(Math.random() * 255, Math.random() * 255, Math.random() * 255, 255);
  401.                                 pixels.push(0, 0, 0, 255);
  402.                         }
  403.                 }
  404.                 var pixels2 = [];
  405.                 for ( var i = 0; i < sizeX / 2; i++) {
  406.                         for ( var j = 0; j < sizeY / 2; j++) {
  407.                                 pixels2.push(0, 0, 0, 255);
  408.                         }
  409.                 }
  410.                 var pixels3 = [];
  411.                 for ( var i = 0; i < sizeX / 4; i++) {
  412.                         for ( var j = 0; j < sizeY / 4; j++) {
  413.                                 pixels3.push(0, 0, 0, 255);
  414.                         }
  415.                 }
  416.                 var pixels4 = [];
  417.                 for ( var i = 0; i < sizeX / 8; i++) {
  418.                         for ( var j = 0; j < sizeY / 8; j++) {
  419.                                 pixels4.push(0, 0, 0, 255);
  420.                         }
  421.                 }
  422.                
  423.                 var rawData = new Uint8Array(noisepixels);
  424.                 texture_main_l = gl.createTexture();
  425.                 gl.bindTexture(gl.TEXTURE_2D, texture_main_l);
  426.                 gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
  427.                 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, sizeX, sizeY, 0, gl.RGBA, gl.UNSIGNED_BYTE, rawData);
  428.                 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  429.                 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  430.  
  431.                 rawData = new Uint8Array(noisepixels);
  432.                 texture_main_n = gl.createTexture();
  433.                 gl.bindTexture(gl.TEXTURE_2D, texture_main_n);
  434.                 gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
  435.                 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, sizeX, sizeY, 0, gl.RGBA, gl.UNSIGNED_BYTE, rawData);
  436.                 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
  437.                 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
  438.  
  439.                 rawData = new Uint8Array(noisepixels);
  440.                 texture_main2_l = gl.createTexture();
  441.                 gl.bindTexture(gl.TEXTURE_2D, texture_main2_l);
  442.                 gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
  443.                 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, sizeX, sizeY, 0, gl.RGBA, gl.UNSIGNED_BYTE, rawData);
  444.                 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  445.                 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  446.  
  447.                 rawData = new Uint8Array(noisepixels);
  448.                 texture_main2_n = gl.createTexture();
  449.                 gl.bindTexture(gl.TEXTURE_2D, texture_main2_n);
  450.                 gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
  451.                 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, sizeX, sizeY, 0, gl.RGBA, gl.UNSIGNED_BYTE, rawData);
  452.                 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
  453.                 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
  454.  
  455.                 rawData = new Uint8Array(pixels);
  456.                 texture_helper = gl.createTexture();
  457.                 gl.bindTexture(gl.TEXTURE_2D, texture_helper);
  458.                 gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
  459.                 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, sizeX, sizeY, 0, gl.RGBA, gl.UNSIGNED_BYTE, rawData);
  460.                 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  461.                 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  462.  
  463.                 rawData = new Uint8Array(pixels2);
  464.                 texture_helper2 = gl.createTexture();
  465.                 gl.bindTexture(gl.TEXTURE_2D, texture_helper2);
  466.                 gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
  467.                 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, sizeX / 2, sizeY / 2, 0, gl.RGBA, gl.UNSIGNED_BYTE, rawData);
  468.                 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  469.                 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  470.  
  471.                 rawData = new Uint8Array(pixels3);
  472.                 texture_helper3 = gl.createTexture();
  473.                 gl.bindTexture(gl.TEXTURE_2D, texture_helper3);
  474.                 gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
  475.                 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, sizeX / 4, sizeY / 4, 0, gl.RGBA, gl.UNSIGNED_BYTE, rawData);
  476.                 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  477.                 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  478.  
  479.                 rawData = new Uint8Array(pixels4);
  480.                 texture_helper4 = gl.createTexture();
  481.                 gl.bindTexture(gl.TEXTURE_2D, texture_helper4);
  482.                 gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
  483.                 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, sizeX / 8, sizeY / 8, 0, gl.RGBA, gl.UNSIGNED_BYTE, rawData);
  484.                 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  485.                 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  486.  
  487.                 rawData = new Uint8Array(pixels);
  488.                 texture_blur = gl.createTexture();
  489.                 gl.bindTexture(gl.TEXTURE_2D, texture_blur);
  490.                 gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
  491.                 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, sizeX, sizeY, 0, gl.RGBA, gl.UNSIGNED_BYTE, rawData);
  492.                 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  493.                 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  494.  
  495.                 rawData = new Uint8Array(pixels2);
  496.                 texture_blur2 = gl.createTexture();
  497.                 gl.bindTexture(gl.TEXTURE_2D, texture_blur2);
  498.                 gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
  499.                 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, sizeX / 2, sizeY / 2, 0, gl.RGBA, gl.UNSIGNED_BYTE, rawData);
  500.                 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  501.                 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  502.  
  503.                 rawData = new Uint8Array(pixels3);
  504.                 texture_blur3 = gl.createTexture();
  505.                 gl.bindTexture(gl.TEXTURE_2D, texture_blur3);
  506.                 gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
  507.                 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, sizeX / 4, sizeY / 4, 0, gl.RGBA, gl.UNSIGNED_BYTE, rawData);
  508.                 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  509.                 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  510.  
  511.                 rawData = new Uint8Array(pixels4);
  512.                 texture_blur4 = gl.createTexture();
  513.                 gl.bindTexture(gl.TEXTURE_2D, texture_blur4);
  514.                 gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
  515.                 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, sizeX / 8, sizeY / 8, 0, gl.RGBA, gl.UNSIGNED_BYTE, rawData);
  516.                 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  517.                 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  518.  
  519.                 rawData = new Uint8Array(noisepixels);
  520.                 texture_noise_l = gl.createTexture();
  521.                 gl.bindTexture(gl.TEXTURE_2D, texture_noise_l);
  522.                 gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
  523.                 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, sizeX, sizeY, 0, gl.RGBA, gl.UNSIGNED_BYTE, rawData);
  524.                 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  525.                 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  526.  
  527.                 texture_noise_n = gl.createTexture();
  528.                 gl.bindTexture(gl.TEXTURE_2D, texture_noise_n);
  529.                 gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
  530.                 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, sizeX, sizeY, 0, gl.RGBA, gl.UNSIGNED_BYTE, rawData);
  531.                 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
  532.                 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
  533.  
  534.                 FBO_main = gl.createFramebuffer();
  535.                 gl.bindFramebuffer(gl.FRAMEBUFFER, FBO_main);
  536.                 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture_main_l, 0);
  537.  
  538.                 FBO_main2 = gl.createFramebuffer();
  539.                 gl.bindFramebuffer(gl.FRAMEBUFFER, FBO_main2);
  540.                 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture_main2_l, 0);
  541.  
  542.                 FBO_helper = gl.createFramebuffer();
  543.                 gl.bindFramebuffer(gl.FRAMEBUFFER, FBO_helper);
  544.                 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture_helper, 0);
  545.  
  546.                 FBO_helper2 = gl.createFramebuffer();
  547.                 gl.bindFramebuffer(gl.FRAMEBUFFER, FBO_helper2);
  548.                 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture_helper2, 0);
  549.  
  550.                 FBO_helper3 = gl.createFramebuffer();
  551.                 gl.bindFramebuffer(gl.FRAMEBUFFER, FBO_helper3);
  552.                 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture_helper3, 0);
  553.  
  554.                 FBO_helper4 = gl.createFramebuffer();
  555.                 gl.bindFramebuffer(gl.FRAMEBUFFER, FBO_helper4);
  556.                 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture_helper4, 0);
  557.  
  558.                 FBO_blur = gl.createFramebuffer();
  559.                 gl.bindFramebuffer(gl.FRAMEBUFFER, FBO_blur);
  560.                 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture_blur, 0);
  561.  
  562.                 FBO_blur2 = gl.createFramebuffer();
  563.                 gl.bindFramebuffer(gl.FRAMEBUFFER, FBO_blur2);
  564.                 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture_blur2, 0);
  565.  
  566.                 FBO_blur3 = gl.createFramebuffer();
  567.                 gl.bindFramebuffer(gl.FRAMEBUFFER, FBO_blur3);
  568.                 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture_blur3, 0);
  569.  
  570.                 FBO_blur4 = gl.createFramebuffer();
  571.                 gl.bindFramebuffer(gl.FRAMEBUFFER, FBO_blur4);
  572.                 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture_blur4, 0);
  573.  
  574.                 FBO_noise = gl.createFramebuffer();
  575.                 gl.bindFramebuffer(gl.FRAMEBUFFER, FBO_noise);
  576.                 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture_noise_l, 0);
  577.  
  578.                 gl.activeTexture(gl.TEXTURE2);
  579.                 gl.bindTexture(gl.TEXTURE_2D, texture_blur);
  580.  
  581.                 gl.activeTexture(gl.TEXTURE3);
  582.                 gl.bindTexture(gl.TEXTURE_2D, texture_blur2);
  583.  
  584.                 gl.activeTexture(gl.TEXTURE4);
  585.                 gl.bindTexture(gl.TEXTURE_2D, texture_blur3);
  586.  
  587.                 gl.activeTexture(gl.TEXTURE5);
  588.                 gl.bindTexture(gl.TEXTURE_2D, texture_blur4);
  589.  
  590.                 gl.activeTexture(gl.TEXTURE6);
  591.                 gl.bindTexture(gl.TEXTURE_2D, texture_noise_l);
  592.  
  593.                 gl.activeTexture(gl.TEXTURE7);
  594.                 gl.bindTexture(gl.TEXTURE_2D, texture_noise_n);
  595.  
  596.                 calculateBlurTexture();
  597.  
  598.                 posX1 = 0.5;
  599.                 posY1 = 0.4;
  600.                 scale1 = 1.23;
  601.                 var w1 = 0;
  602.                 sinW1 = Math.sin(w1);
  603.                 cosW1 = Math.cos(w1);
  604.  
  605.                 posX2 = 0.5;
  606.                 posY2 = 0.6;
  607.                 scale2 = 2.5;
  608.                 var w2 = 0.1;
  609.                 w2 *= Math.PI;
  610.                 sinW2 = Math.sin(w2);
  611.                 cosW2 = Math.cos(w2);
  612.  
  613.                 timer = setInterval(fr, 500);
  614.                 time = new Date().getTime();
  615.                 animation = "animate";
  616.                 anim();
  617.         }
  618.  
  619.         var x1 = 0.5;
  620.         var y1 = 0.03;
  621.  
  622.         var x2 = 0.5;
  623.         var y2 = 0.15;
  624.  
  625.         var thickness = 1. / 0.01; // inverse actually, keeping the shader calculation low
  626.  
  627.         var w1 = 0.2;
  628.         var w2 = 0.9;
  629.  
  630.         var scale1 = 1.23;
  631.         var scale2 = 2.5;
  632.  
  633.         function setUniforms(program) {
  634.                 gl.uniform2f(gl.getUniformLocation(program, "pixelSize"), 1. / sizeX, 1. / sizeY);
  635.                 gl.uniform4f(gl.getUniformLocation(program, "rnd"), Math.random(), Math.random(), Math.random(), Math.random());
  636.                 gl.uniform1f(gl.getUniformLocation(program, "fps"), fps);
  637.                 gl.uniform1f(gl.getUniformLocation(program, "time"), (new Date().getTime() - basetime) / 1000);
  638.                 gl.uniform2f(gl.getUniformLocation(program, "aspect"), Math.max(1, viewX / viewY), Math.max(1, viewY / viewX));
  639.                 gl.uniform2f(gl.getUniformLocation(program, "mouse"), mouseX, mouseY);
  640.                 gl.uniform1i(gl.getUniformLocation(program, "sampler_prev"), 0);
  641.                 gl.uniform1i(gl.getUniformLocation(program, "sampler_prev_n"), 1);
  642.                 gl.uniform1i(gl.getUniformLocation(program, "sampler_blur"), 2);
  643.                 gl.uniform1i(gl.getUniformLocation(program, "sampler_blur2"), 3);
  644.                 gl.uniform1i(gl.getUniformLocation(program, "sampler_blur3"), 4);
  645.                 gl.uniform1i(gl.getUniformLocation(program, "sampler_blur4"), 5);
  646.                 gl.uniform1i(gl.getUniformLocation(program, "sampler_noise"), 6);
  647.                 gl.uniform1i(gl.getUniformLocation(program, "sampler_noise_n"), 7);
  648.  
  649.                 gl.uniform1f(gl.getUniformLocation(program, "x1"), x1);
  650.                 gl.uniform1f(gl.getUniformLocation(program, "y1"), y1);
  651.                 gl.uniform1f(gl.getUniformLocation(program, "d1"), thickness);
  652.  
  653.                 gl.uniform1f(gl.getUniformLocation(program, "x2"), x2);
  654.                 gl.uniform1f(gl.getUniformLocation(program, "y2"), y2);
  655.                 gl.uniform1f(gl.getUniformLocation(program, "d2"), thickness * scale1);
  656.  
  657.                 gl.uniform1f(gl.getUniformLocation(program, "sin1"), Math.sin(w1));
  658.                 gl.uniform1f(gl.getUniformLocation(program, "cos1"), Math.cos(w1));
  659.  
  660.                 gl.uniform1f(gl.getUniformLocation(program, "sin2"), Math.sin(w1 - w2));
  661.                 gl.uniform1f(gl.getUniformLocation(program, "cos2"), Math.cos(w1 - w2));
  662.  
  663.                 gl.uniform1f(gl.getUniformLocation(program, "sin3"), Math.sin(w1 + w2));
  664.                 gl.uniform1f(gl.getUniformLocation(program, "cos3"), Math.cos(w1 + w2));
  665.  
  666.                 gl.uniform1f(gl.getUniformLocation(program, "scale1"), scale1);
  667.                 gl.uniform1f(gl.getUniformLocation(program, "scale2"), scale2);
  668.         }
  669.         function calculateBlurTexture() {
  670.                 // simple blur
  671.  
  672.                 // horizontal
  673.                 gl.viewport(0, 0, sizeX, sizeY);
  674.                 gl.useProgram(prog_blur_horizontal);
  675.                 gl.uniform2f(gl.getUniformLocation(prog_blur_horizontal, "pixelSize"), 1. / sizeX, 1. / sizeY);
  676.                 gl.activeTexture(gl.TEXTURE0);
  677.                 if (it < 0) {
  678.                         gl.bindTexture(gl.TEXTURE_2D, texture_main2_l);
  679.                         gl.bindFramebuffer(gl.FRAMEBUFFER, FBO_helper);
  680.                 } else {
  681.                         gl.bindTexture(gl.TEXTURE_2D, texture_main_l);
  682.                         gl.bindFramebuffer(gl.FRAMEBUFFER, FBO_helper);
  683.                 }
  684.                 gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
  685.                 gl.flush();
  686.  
  687.                 // vertical
  688.                 gl.viewport(0, 0, sizeX, sizeY);
  689.                 gl.useProgram(prog_blur_vertical);
  690.                 gl.uniform2f(gl.getUniformLocation(prog_blur_vertical, "pixelSize"), 1. / sizeX, 1. / sizeY);
  691.                 gl.activeTexture(gl.TEXTURE0);
  692.                 gl.bindTexture(gl.TEXTURE_2D, texture_helper);
  693.                 gl.bindFramebuffer(gl.FRAMEBUFFER, FBO_blur);
  694.                 gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
  695.                 gl.flush();
  696.  
  697.                 // double blur
  698.                 // copy previous blur level to lower resolution texture
  699.                 gl.viewport(0, 0, sizeX / 2, sizeY / 2);
  700.                 gl.useProgram(prog_copy);
  701.                 gl.activeTexture(gl.TEXTURE0);
  702.                 gl.bindTexture(gl.TEXTURE_2D, texture_blur);
  703.                 gl.bindFramebuffer(gl.FRAMEBUFFER, FBO_blur2);
  704.                 gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
  705.                 gl.flush();
  706.  
  707.                 // blur2 vertical
  708.                 gl.viewport(0, 0, sizeX / 2, sizeY / 2);
  709.                 gl.useProgram(prog_blur_vertical);
  710.                 gl.uniform2f(gl.getUniformLocation(prog_blur_vertical, "pixelSize"), 2. / sizeX, 2. / sizeY);
  711.                 gl.activeTexture(gl.TEXTURE0);
  712.                 gl.bindTexture(gl.TEXTURE_2D, texture_blur2);
  713.                 gl.bindFramebuffer(gl.FRAMEBUFFER, FBO_helper2);
  714.                 gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
  715.                 gl.flush();
  716.  
  717.                 // blur2 horizontal
  718.                 gl.viewport(0, 0, sizeX / 2, sizeY / 2);
  719.                 gl.useProgram(prog_blur_horizontal);
  720.                 gl.uniform2f(gl.getUniformLocation(prog_blur_horizontal, "pixelSize"), 2. / sizeX, 2. / sizeY);
  721.                 gl.activeTexture(gl.TEXTURE0);
  722.                 gl.bindTexture(gl.TEXTURE_2D, texture_helper2);
  723.                 gl.bindFramebuffer(gl.FRAMEBUFFER, FBO_blur2);
  724.                 gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
  725.                 gl.flush();
  726.  
  727.                 // blur3
  728.                 // copy previous blur level to lower resolution texture
  729.                 gl.viewport(0, 0, sizeX / 4, sizeY / 4);
  730.                 gl.useProgram(prog_copy);
  731.                 gl.activeTexture(gl.TEXTURE0);
  732.                 gl.bindTexture(gl.TEXTURE_2D, texture_blur2);
  733.                 gl.bindFramebuffer(gl.FRAMEBUFFER, FBO_blur3);
  734.                 gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
  735.                 gl.flush();
  736.  
  737.                 // blur3 vertical
  738.                 gl.viewport(0, 0, sizeX / 4, sizeY / 4);
  739.                 gl.useProgram(prog_blur_vertical);
  740.                 gl.uniform2f(gl.getUniformLocation(prog_blur_vertical, "pixelSize"), 4. / sizeX, 4. / sizeY);
  741.                 gl.activeTexture(gl.TEXTURE0);
  742.                 gl.bindTexture(gl.TEXTURE_2D, texture_blur3);
  743.                 gl.bindFramebuffer(gl.FRAMEBUFFER, FBO_helper3);
  744.                 gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
  745.                 gl.flush();
  746.  
  747.                 // blur3 horizontal
  748.                 gl.viewport(0, 0, sizeX / 4, sizeY / 4);
  749.                 gl.useProgram(prog_blur_horizontal);
  750.                 gl.uniform2f(gl.getUniformLocation(prog_blur_horizontal, "pixelSize"), 4. / sizeX, 4. / sizeY);
  751.                 gl.activeTexture(gl.TEXTURE0);
  752.                 gl.bindTexture(gl.TEXTURE_2D, texture_helper3);
  753.                 gl.bindFramebuffer(gl.FRAMEBUFFER, FBO_blur3);
  754.                 gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
  755.                 gl.flush();
  756.  
  757.                 // blur4
  758.                 // copy previous blur level to lower resolution texture
  759.                 gl.viewport(0, 0, sizeX / 8, sizeY / 8);
  760.                 gl.useProgram(prog_copy);
  761.                 gl.activeTexture(gl.TEXTURE0);
  762.                 gl.bindTexture(gl.TEXTURE_2D, texture_blur3);
  763.                 gl.bindFramebuffer(gl.FRAMEBUFFER, FBO_blur4);
  764.                 gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
  765.                 gl.flush();
  766.  
  767.                 // blur4 vertical
  768.                 gl.viewport(0, 0, sizeX / 8, sizeY / 8);
  769.                 gl.useProgram(prog_blur_vertical);
  770.                 gl.uniform2f(gl.getUniformLocation(prog_blur_vertical, "pixelSize"), 8. / sizeX, 8. / sizeY);
  771.                 gl.activeTexture(gl.TEXTURE0);
  772.                 gl.bindTexture(gl.TEXTURE_2D, texture_blur4);
  773.                 gl.bindFramebuffer(gl.FRAMEBUFFER, FBO_helper4);
  774.                 gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
  775.                 gl.flush();
  776.  
  777.                 // blur4 horizontal
  778.                 gl.viewport(0, 0, sizeX / 8, sizeY / 8);
  779.                 gl.useProgram(prog_blur_horizontal);
  780.                 gl.uniform2f(gl.getUniformLocation(prog_blur_horizontal, "pixelSize"), 8. / sizeX, 8. / sizeY);
  781.                 gl.activeTexture(gl.TEXTURE0);
  782.                 gl.bindTexture(gl.TEXTURE_2D, texture_helper4);
  783.                 gl.bindFramebuffer(gl.FRAMEBUFFER, FBO_blur4);
  784.                 gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
  785.                 gl.flush();
  786.  
  787.         }
  788.  
  789.         function advance() {
  790.  
  791.                 x1 = 0.5;
  792.                 thickness = (2 - mouseY * 1.) / 0.025;
  793.                 y1 = 0.035;
  794.  
  795.                 x2 = 0.5 + (mouseX - 0.5) * 0.25;
  796.                 y2 = 0.07 + mouseY * 0.14;
  797.                 w1 = (0.5 - mouseX) * 0.15;
  798.  
  799.                 gl.viewport(0, 0, sizeX, sizeY);
  800.                 gl.useProgram(prog_advance);
  801.                 setUniforms(prog_advance);
  802.                 if (it > 0) {
  803.                         gl.activeTexture(gl.TEXTURE0);
  804.                         gl.bindTexture(gl.TEXTURE_2D, texture_main_l); // interpolated input
  805.                         gl.activeTexture(gl.TEXTURE1);
  806.                         gl.bindTexture(gl.TEXTURE_2D, texture_main_n); // "nearest" input
  807.                         gl.bindFramebuffer(gl.FRAMEBUFFER, FBO_main2); // write to buffer
  808.                 } else {
  809.                         gl.activeTexture(gl.TEXTURE0);
  810.                         gl.bindTexture(gl.TEXTURE_2D, texture_main2_l); // interpolated
  811.                         gl.activeTexture(gl.TEXTURE1);
  812.                         gl.bindTexture(gl.TEXTURE_2D, texture_main2_n); // "nearest"
  813.                         gl.bindFramebuffer(gl.FRAMEBUFFER, FBO_main); // write to buffer
  814.                 }
  815.                 gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
  816.                 gl.flush();
  817.  
  818.                 calculateBlurTexture();
  819.                 it = -it;
  820.         }
  821.  
  822.         function composite() {
  823.                 gl.viewport(0, 0, viewX, viewY);
  824.                 gl.useProgram(prog_composite);
  825.                 setUniforms(prog_composite);
  826.                 if (it < 0) {
  827.                         gl.activeTexture(gl.TEXTURE0);
  828.                         gl.bindTexture(gl.TEXTURE_2D, texture_main_l);
  829.                         gl.activeTexture(gl.TEXTURE1);
  830.                         gl.bindTexture(gl.TEXTURE_2D, texture_main_n);
  831.                 } else {
  832.                         gl.activeTexture(gl.TEXTURE0);
  833.                         gl.bindTexture(gl.TEXTURE_2D, texture_main2_l);
  834.                         gl.activeTexture(gl.TEXTURE1);
  835.                         gl.bindTexture(gl.TEXTURE_2D, texture_main2_n);
  836.                 }
  837.                 gl.bindFramebuffer(gl.FRAMEBUFFER, null);
  838.                 gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
  839.                 gl.flush();
  840.                 frames++;
  841.         }
  842.  
  843.         function anim() {
  844.                 if (!halted)
  845.                         advance();
  846.                 composite();
  847.                 switch (animation) {
  848.                 case "animate":
  849.                         setTimeout("requestAnimFrame(anim)", delay);
  850.                         break;
  851.                 case "reset":
  852.                         load();
  853.                         break;
  854.                 }
  855.         }
  856.         function setDelay(v) {
  857.                 delay = parseInt(v);
  858.         }
  859.         function fr() {
  860.                 var ti = new Date().getTime();
  861.                 fps = Math.round(1000 * frames / (ti - time));
  862.                 document.getElementById("fps").textContent = fps;
  863.                 frames = 0;
  864.                 time = ti;
  865.         }
  866. </script>
  867. <style type="text/css">
  868. body {
  869.         background-color: #FFFFFF;
  870.         color: #000000;
  871. }
  872. a {
  873.         color: #666666;
  874.         text-decoration: none;
  875. }
  876. #c {
  877.         position: absolute;
  878.         top: 0;
  879.         left: 0;
  880.         z-index: -1;
  881. }
  882.  
  883. #desc {
  884.         background-color: rgba(255, 255, 255, 0.2);
  885. }
  886. </style>
  887. </head>
  888. <body onload="load()">
  889.         <div id="desc">
  890.                 <b><i>Progressive <a href="http://en.wikipedia.org/wiki/L-system" target=new>Lindenmayer</a> tree fractal</i> </b><br />
  891.                 Fps: <span id="fps"></span>
  892.         </div>
  893.         <canvas id="c"></canvas>
  894. </body>
  895. </html>