ThreeJS Post-processing Using Pixel Shader Composer

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

by realhunts

HTML

<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 src="https://threejs.org/build/three.min.js"></script>

<script id="trippyPostShader" type="x-shader/x-fragment">
	precision mediump float;

	varying vec2 vUv;
	varying vec3 pos;
  varying float vTime;
  uniform vec2 resolution;
  uniform sampler2D tDiffuse;

    void main(void) 
    {
        float frequency = 100.0;
        float amplitude = 0.003;
        float distortion = sin(vTime*vUv.y*frequency)*amplitude;
        vec4 color = texture2D(tDiffuse,vec2(vUv.x+distortion, vUv.y));
    	gl_FragColor = color;
    
  }
</script>


<script id="vertexShader" type="x-shader/x-vertex">
	varying vec2 vUv;
	varying vec3 pos;
  varying float vTime;
  uniform float time;

  void main() {
  	vTime = time;
    vUv = uv;
    pos = position;
    gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
  }
</script>

<script src="https://threejs.org/build/three.min.js"></script>

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();
  
  THREE.ImageUtils.crossOrigin = '';
  var texture = THREE.ImageUtils.loadTexture('https://cdn.glitch.com/673d0d01-5f8e-4eea-8711-f4f4f55a29bb%2Fmoss_covered_rock_texture_2_by_fairiegoodmother_d1iqdwc-fullview.jpg?1550359563126');

var debMat = new THREE.MeshBasicMaterial( { color: new THREE.Color("gray"), map: texture, side: THREE.DoubleSide } );
  
  
  
  torus = new THREE.Mesh(new THREE.TorusGeometry(120, 60, 40, 40),debMat);
  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( 'vertexShader'...