GLSL sandbox (fullscreen)

to create original (fullscreen) effects

HTML

<script src="http://mrdoob.github.com/three.js/build/three.min.js"></script>
<script id="vertexShader" type="x-shader/x-vertex">
    void main() {
        gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
    }
</script>
<script id="fragmentShader" type="x-shader/x-fragment">
    precision mediump float;
precision mediump int;

out vec4 glFragColor;

uniform sampler2D tex_velocity;
uniform sampler2D tex_source;
uniform sampler2D tex_obstacleC;

uniform vec2  wh_inv;
uniform float timestep;
uniform float rdx;
uniform float dissipation;

void main(){
  vec2 posn = gl_FragCoord.xy * wh_inv;
  
  float oC = texture(tex_obstacleC, posn).x;
  if (oC == 1.0) {
    glFragColor = vec4(0);
  } else {
    vec2 velocity = texture(tex_velocity, posn).xy;
    vec2 posn_back = posn - timestep * rdx * velocity * wh_inv;
    glFragColor = dissipation * texture(tex_source, posn_back);
  }
}
</script>

CSS

body {
    overflow:hidden;
}

JavaScript

var camera, scene, renderer;
var clock = new THREE.Clock();
var meshMaterial;

init();
animate();

function init() {
    /*
    camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 3000);
    camera.position.z = 500;

*/
    // orthographic camera (for full-screen plane)
    camera = new THREE.OrthographicCamera(-100, 100, 100, -100, -500, 500);
    camera.position.z = 300;

    var geometry = new THREE.PlaneGeometry(200, 200);

    meshMaterial = new THREE.ShaderMaterial({
        uniforms: {
            time: {
                type: 'f',
                value: 1.0
            }
        },
        vertexShader: document.getElementById('vertexShader').textContent,
        fragmentShader: document.getElementById('fragmentShader').textContent
    });

    var mesh = new THREE.Mesh(geometry, meshMaterial);

    scene = new THREE.Scene();
    scene.add(mesh);

    renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);
    window.addEventListener('resize', onWindowResize, false);
}

function onWindowResize(event) {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();

    renderer.setSize(window.innerWidth, window.innerHeight);
}

function animate() {
    requestAnimationFrame(animate);
    render();
}

function render() {
    var delta = clock.getDelta();

    meshMaterial.uniforms.time.value += delta * 2;
    renderer.render(scene, camera);
}