diff --git a/examples/gpgpu/fragment-shaders/copy-fs.glsl b/examples/gpgpu/fragment-shaders/copy-fs.glsl
new file mode 100644
index 0000000..cc5cd99
--- /dev/null
+++ b/examples/gpgpu/fragment-shaders/copy-fs.glsl
@@ -0,0 +1,8 @@
+varying vec2 vUv;
+uniform sampler2D tInput;
+
+void main() {
+
+ gl_FragColor = texture2D( tInput, vUv );
+
+}
\ No newline at end of file
diff --git a/examples/gpgpu/fragment-shaders/position-fs.glsl b/examples/gpgpu/fragment-shaders/position-fs.glsl
new file mode 100644
index 0000000..0776f44
--- /dev/null
+++ b/examples/gpgpu/fragment-shaders/position-fs.glsl
@@ -0,0 +1,16 @@
+varying vec2 vUv;
+
+uniform float time;
+uniform sampler2D tVel;
+uniform sampler2D tPos;
+
+void main( void ) {
+
+ vec3 p = texture2D( tPos, vUv ).rgb;
+ vec3 v = texture2D( tVel, vUv ).rgb;
+
+ vec3 new_p=p+v;
+
+ gl_FragColor = vec4( new_p, 1.0 );
+
+}
\ No newline at end of file
diff --git a/examples/gpgpu/fragment-shaders/velocity-fs.glsl b/examples/gpgpu/fragment-shaders/velocity-fs.glsl
new file mode 100644
index 0000000..c636c16
--- /dev/null
+++ b/examples/gpgpu/fragment-shaders/velocity-fs.glsl
@@ -0,0 +1,25 @@
+varying vec2 vUv;
+uniform sampler2D tVel;
+uniform sampler2D tPos;
+uniform float limitToBounce;
+
+void main() {
+
+ vec3 pos = texture2D( tPos, vUv ).xyz;
+ vec3 vel = texture2D( tVel, vUv ).xyz;
+
+ if ((pos.x > limitToBounce) || (pos.x < -limitToBounce)) {
+ vel.x *= -1.0;
+ }
+
+ if ((pos.y > limitToBounce) || (pos.y < -limitToBounce)) {
+ vel.y *= -1.0;
+ }
+
+ if ((pos.z > limitToBounce) || (pos.z < -limitToBounce)) {
+ vel.z *= -1.0;
+ }
+
+ gl_FragColor = vec4(vel, 1.0);
+
+}
\ No newline at end of file
diff --git a/examples/gpgpu/index.html b/examples/gpgpu/index.html
new file mode 100644
index 0000000..bdc6ac1
--- /dev/null
+++ b/examples/gpgpu/index.html
@@ -0,0 +1,223 @@
+
+
+
+ Wagner - Minefield!
+
+
+
+
+
+
+
+
+Go fullscreen
+
+Wagner GPGPU Velocity + Position Pass
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/gpgpu/js/WagnerPositionPass.js b/examples/gpgpu/js/WagnerPositionPass.js
new file mode 100644
index 0000000..3b91c32
--- /dev/null
+++ b/examples/gpgpu/js/WagnerPositionPass.js
@@ -0,0 +1,18 @@
+WAGNER.PositionPass = function () {
+
+ WAGNER.Pass.call( this );
+ WAGNER.log( 'PositionPass Pass constructor' );
+
+ this.loadShader( 'position-fs.glsl' );
+
+}
+
+WAGNER.PositionPass.prototype = Object.create( WAGNER.Pass.prototype );
+
+WAGNER.PositionPass.prototype.run = function ( c ) {
+
+ this.shader.uniforms.tVel.value = this.params.tVel;
+ this.shader.uniforms.tPos.value = c.output;
+ c.pass( this.shader );
+
+}
\ No newline at end of file
diff --git a/examples/gpgpu/js/WagnerVelocityPass.js b/examples/gpgpu/js/WagnerVelocityPass.js
new file mode 100644
index 0000000..430de55
--- /dev/null
+++ b/examples/gpgpu/js/WagnerVelocityPass.js
@@ -0,0 +1,22 @@
+WAGNER.VelocityPass = function () {
+
+ WAGNER.Pass.call( this );
+ WAGNER.log( 'VelocityPass Pass constructor' );
+
+ this.loadShader( 'velocity-fs.glsl', function () {
+
+ this.shader.uniforms.limitToBounce.value = this.params.limitToBounce;
+
+ } );
+
+}
+
+WAGNER.VelocityPass.prototype = Object.create( WAGNER.Pass.prototype );
+
+WAGNER.VelocityPass.prototype.run = function ( c ) {
+
+ this.shader.uniforms.tPos.value = this.params.tPos;
+ this.shader.uniforms.tVel.value = c.output;
+ c.pass( this.shader );
+
+}
\ No newline at end of file
diff --git a/examples/gpgpu/js/main.js b/examples/gpgpu/js/main.js
new file mode 100644
index 0000000..763bf17
--- /dev/null
+++ b/examples/gpgpu/js/main.js
@@ -0,0 +1,117 @@
+'use strict'
+
+var container, renderer, scene, camera, mesh, material, fov = 70;
+var numParticles = 64; //power fo 2
+var limitToBounce = 512;
+var composerPos, composerVel;
+var velPass, posPass;
+var controls;
+
+var links = document.querySelectorAll( 'a[rel=external]' );
+for ( var j = 0; j < links.length; j++ ) {
+ var a = links[j];
+ a.addEventListener( 'click', function ( e ) {
+ window.open( this.href, '_blank' );
+ e.preventDefault();
+ }, false );
+}
+
+var c = document.body;
+document.getElementById( 'fullscreenBtn' ).addEventListener( 'click', function ( e ) {
+ c.onwebkitfullscreenchange = function ( e ) {
+ c.onwebkitfullscreenchange = function () {
+ };
+ };
+ c.onmozfullscreenchange = function ( e ) {
+ c.onmozfullscreenchange = function () {
+ };
+ };
+ if ( c.webkitRequestFullScreen ) c.webkitRequestFullScreen();
+ if ( c.mozRequestFullScreen ) c.mozRequestFullScreen();
+ e.preventDefault();
+}, false );
+
+window.addEventListener( 'load', function () {
+
+ init();
+
+} );
+
+function init() {
+
+ container = document.getElementById( 'container' );
+ scene = new THREE.Scene();
+
+ camera = new THREE.PerspectiveCamera( fov, window.innerWidth / window.innerHeight, 1, 10000 );
+ camera.position.z = 1000;
+ scene.add( camera );
+
+ controls = new THREE.OrbitControls( camera );
+
+ material = new THREE.ShaderMaterial( {
+
+ uniforms: {
+
+ "texture": { type: "t", value: null },
+ "textureSize": { type: "f", value: numParticles },
+ "pointSize": { type: "f", value: 3.0 }
+
+ },
+ vertexShader: document.getElementById( 'vs-particles' ).textContent,
+ fragmentShader: document.getElementById( 'fs-particles' ).textContent,
+ depthWrite: false,
+ depthTest: false
+
+ } );
+
+ var geometry = new THREE.Geometry();
+
+ for ( var i = 0, l = numParticles * numParticles; i < l; i++ ) {
+
+ var vertex = new THREE.Vector3();
+ vertex.x = ( i % numParticles ) / numParticles;
+ vertex.y = Math.floor( i / numParticles ) / numParticles;
+ vertex.z = 0;
+ geometry.vertices.push( vertex );
+
+ }
+
+ var particles = new THREE.PointCloud( geometry, material );
+ particles.sortParticles = false;
+ scene.add( particles );
+
+ renderer = new THREE.WebGLRenderer( { antialias: true, alpha: false } );
+ renderer.setSize( window.innerWidth, window.innerHeight );
+ renderer.setPixelRatio( window.devicePixelRatio );
+ container.appendChild( renderer.domElement );
+
+ window.addEventListener( 'resize', onWindowResize, false );
+
+ initPass();
+
+ onWindowResize();
+
+ render();
+
+}
+
+function onWindowResize() {
+
+ var s = 1,
+ w = window.innerWidth,
+ h = window.innerHeight;
+
+ renderer.setSize( s * w, s * h );
+ camera.projectionMatrix.makePerspective( fov, w / h, camera.near, camera.far );
+
+ resizePass();
+
+}
+
+function render() {
+
+ requestAnimationFrame( render );
+
+ renderPass();
+
+}
\ No newline at end of file
diff --git a/examples/gpgpu/vertex-shaders/orto-vs.glsl b/examples/gpgpu/vertex-shaders/orto-vs.glsl
new file mode 100644
index 0000000..7d059de
--- /dev/null
+++ b/examples/gpgpu/vertex-shaders/orto-vs.glsl
@@ -0,0 +1,8 @@
+varying vec2 vUv;
+
+void main() {
+
+ vUv = uv;
+ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+}
\ No newline at end of file