ThreeJS Post-processing Using Pixel Shader Composer

Some trippy pixel shader experiments in WebGL using ThreeJS for 2D post-processing

by blackInk

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r66/three.min.js"></script>
<script src="https://www.airtightinteractive.com/demos/js/badtvshader/lib/postprocessing/EffectComposer.js"></script>
<script src="https://www.airtightinteractive.com/demos/js/badtvshader/lib/postprocessing/RenderPass.js"></script>
<script src="https://www.airtightinteractive.com/demos/js/badtvshader/lib/postprocessing/ShaderPass.js"></script>
<script src="https://www.airtightinteractive.com/demos/js/badtvshader/lib/shaders/CopyShader.js"></script>
<script src="https://www.airtightinteractive.com/demos/js/badtvshader/lib/postprocessing/MaskPass.js"></script>
<script id="trippyMaterialShader" type="x-shader/x-fragment">
	precision mediump float;

	varying vec2 vUv;
	varying vec3 pos;
  varying float vTime;
  uniform vec2 resolution;
  
  float hash(float n) {
    return fract(sin(n)*93942.234);
  }

  float noise(vec2 p) {
    vec2 w = floor(p);
    vec2 k = fract(p);
    k = k*k*(3.-2.*k);
    
    float n = w.x + w.y*57.;
    
    float a = hash(n);
    float b = hash(n+1.);
    float c = hash(n+57.);
    float d = hash(n+58.);
    
    return mix(
      tan(mix(a, b, k.x)),
      tan(mix(c, d, k.x)),
      k.y);
  }

  mat2 m = mat2(0.6,0.8,-0.8,0.6);

  float fbm(vec2 p) {
    float f = 0.;
    f += 0.5000*noise(p); p *= 2.02*m;
    f += 0.2500*noise(p); p *= 2.01*m;
    f += 0.1250*noise(p); p *= 2.03*m;
    f += 0.0625*noise(p);
    f /= 0.9375;
    return f;
  }

  void main() {
    vec2 p = vec2(vec2(pos.x + (sin(vTime*10.) * 300.0), pos.y + (cos(vTime*10.) * 300.0))*0.01)*vec2(resolution.x/resolution.y, 1.);
    float t = vTime;
    
    vec2 a = vec2(fbm(p+t*3.), fbm(p-t*3.+8.1));
    vec2 b = vec2(fbm(p+t*4. + a*7. + 3.1), fbm(p-t*4. + a*7. + 91.1));
    float c = fbm(b*9. + t*20.);
    
    c = smoothstep(0.5,1.,c);
    
    float depth = (-pos.z * 0.01) + 0.35;
    vec3 col = vec3((c + b.x*0.5) * depth, (c + b.y*0.75) * depth, c * depth);

    vec4 color =...

JavaScript

var camera;
var scene;
var renderer;
var renderPass;
var copyPass;
var composer;
var trippyPass;
var pinchPostShader;
var time = 0;

init();
animate();

function init() {
  camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 10000);
  camera.position.set(0, 0, -1000);
  camera.lookAt(new THREE.Vector3(0,0,0));

  scene = new THREE.Scene();
  
  material = new THREE.ShaderMaterial( {
		uniforms: {
      time: { type: "f", value: 0.0 },
      resolution: { type: "v2", value: new THREE.Vector2(window.innerWidth, window.innerHeight) }
    },
		vertexShader: document.getElementById( 'varyingVertexShader' ).textContent,
		fragmentShader: document.getElementById( 'trippyMaterialShader' ).textContent
	} );
  
  torus = new THREE.Mesh(new THREE.TorusGeometry(120, 60, 40, 40),
                         material);
  torus.position.set(0, 0, 0);
  scene.add(torus);

  renderer = new THREE.WebGLRenderer({ antialias: true });
  renderer.context.getProgramInfoLog = function () { return '' };
  renderer.setClearColor(0xffffff, 1)
  renderer.setSize(window.innerWidth, window.innerHeight);
  renderer.domElement.style.zIndex = 5;
  
  composer = new THREE.EffectComposer(renderer);
  
  renderPass = new THREE.RenderPass( scene, camera );
  composer.addPass(renderPass);
  
  trippyPass = new THREE.ShaderPass( {
  				uniforms: {
          	tDiffuse: { type: "t", value: null },
            time: { type: "f", value: 0.0 },
            resolution: { type: "v2", value: new THREE.Vector2(window.innerWidth, window.innerHeight) }
          },
					vertexShader: document.getElementById( 'vertexShader' ).textContent,
					fragmentShader: document.getElementById( 'trippyPostShader' ).textContent
				} );
  composer.addPass( trippyPass );
  /*
  pinchPostShader = new THREE.ShaderPass( {
  				uniforms: {
          	tDiffuse: { type: "t", value: null },
            time: { type: "f", value: 0.0 }
          },
					vertexShader: document.getElementById(...