title: threejs fragment shader using recycled frame buffers
body: <p>I'm trying to make an app that will simulate long exposure photography. The idea is that I grab the current frame from the webcam and composite it onto a canvas. Over time, the photo will 'expose', getting brighter and brighter. (see <a href="http://www.chromeexperiments.com/detail/light-paint-live-mercury/?f=" rel="nofollow noreferrer">http://www.chromeexperiments.com/detail/light-paint-live-mercury/?f=</a>)</p>
  
  <p>I have a shader that works perfectly. It's just like the 'add' blend mode in photoshop. The problem is that I can't get it to recycle the previous frame. </p>
  
  <p>I thought that it would be something simple like <code>renderer.autoClear = false;</code> but that option seems to do nothing in this context.</p>
  
  <p>Here's the code that uses THREE.EffectComposer to apply the shader.</p>
  
  <pre><code>        onWebcamInit: function () {    
              var $stream = $("#user-stream"),
                  width = $stream.width(),
                  height = $stream.height(),
                  near = .1,
                  far = 10000;
  
              this.renderer = new THREE.WebGLRenderer();
              this.renderer.setSize(width, height);
              this.renderer.autoClear = false;
              this.scene = new THREE.Scene();
  
              this.camera = new THREE.OrthographicCamera(width / -2, width / 2, height / 2, height / -2, near, far);
              this.scene.add(this.camera);
  
              this.$el.append(this.renderer.domElement);
  
              this.frameTexture = new THREE.Texture(document.querySelector("#webcam"));
              this.compositeTexture = new THREE.Texture(this.renderer.domElement);
  
              this.composer = new THREE.EffectComposer(this.renderer);
  
              // same effect with or without this line
              // this.composer.addPass(new THREE.RenderPass(this.scene, this.camera));
  
              var addEffect = new THREE.ShaderPass(addShader);
              addEffect.uniforms[ 'exposure' ].value = .5;
              addEffect.uniforms[ 'frameTexture' ].value = this.frameTexture;
              addEffect.renderToScreen = true;
              this.composer.addPass(addEffect);
  
              this.plane = new THREE.Mesh(new THREE.PlaneGeometry(width, height, 1, 1), new THREE.MeshBasicMaterial({map: this.compositeTexture}));
              this.scene.add(this.plane);
  
              this.frameTexture.needsUpdate = true;
              this.compositeTexture.needsUpdate = true;
  
              new FrameImpulse(this.renderFrame);
  
          },
          renderFrame: function () {
              this.frameTexture.needsUpdate = true;
              this.compositeTexture.needsUpdate = true;
              this.composer.render();
          }
  </code></pre>
  
  <p>Here is the shader. Nothing fancy.</p>
  
  <pre><code>        uniforms: {
              "tDiffuse": { type: "t", value: null },
              "frameTexture": { type: "t", value: null },
              "exposure": { type: "f", value: 1.0 }
          },
  
          vertexShader: [
              "varying vec2 vUv;",
              "void main() {",
              "vUv = uv;",
              "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
  
              "}"
          ].join("\n"),
  
          fragmentShader: [
  
              "uniform sampler2D frameTexture;",
              "uniform sampler2D tDiffuse;",
              "uniform float exposure;",
              "varying vec2 vUv;",
  
              "void main() {",
              "vec4 n = texture2D(frameTexture, vUv);",
              "vec4 o = texture2D(tDiffuse, vUv);",
              "vec3 sum = n.rgb + o.rgb;",
              "gl_FragColor = vec4(mix(o.rgb, sum.rgb, exposure), 1.0);",
              "}"
  
          ].join("\n")
  </code></pre>