var container = document.getElementById('c');
var startTime=+new Date();
var scene, camera, renderer, composer, composerScene, effectRadioNoise, effectPerturbation;
var WIDTH=400, HEIGHT=300;
var damages = 0;
var Shaders;
function setup () {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(75, WIDTH/HEIGHT, 1, 10000);
camera.position.z = 150;
camera.rotation.x = Math.PI/2;
camera.rotation.y = 0;
camera.rotation.z = 0;
/// Scene code
scene.add(camera);
scene.add(createTank(new THREE.Vector3(1000, 1000, 0)));
scene.add(createTank(new THREE.Vector3(1000, -1000, 0)));
scene.add(createTank(new THREE.Vector3(-1000, 1000, 0)));
scene.add(createTank(new THREE.Vector3(-1000, -1000, 0)));
///
renderer = new THREE.WebGLRenderer();
renderer.setSize(WIDTH, HEIGHT);
container.appendChild(renderer.domElement);
// Add effects
var rtParameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBuffer: true };
var renderModel = new THREE.RenderPass(scene, camera);
renderModel.clear = false;
composerScene = new THREE.EffectComposer(renderer, new THREE.WebGLRenderTarget(WIDTH, HEIGHT, rtParameters));
composerScene.addPass(renderModel);
var renderScene = new THREE.TexturePass(composerScene.renderTarget2);
renderScene.uniforms["tDiffuse"].texture = composerScene.renderTarget2;
// create your effects
effectRadioNoise = new THREE.ShaderPass( Shaders[ "radionoise" ] );
effectPerturbation = new THREE.ShaderPass( Shaders[ "perturbation" ] );
effectPerturbation.renderToScreen = true; // set to the last pass
updateEffects();
// Add effects to the composer pass
composer = new THREE.EffectComposer( renderer, new THREE.WebGLRenderTarget(WIDTH, HEIGHT, rtParameters) );
composer.addPass( renderScene );
composer.addPass( effectRadioNoise );
composer.addPass( effectPerturbation );
}
// Update your effects
function updateEffects () {
var now = +new Date();
var t = now-startTime;
effectRadioNoise.uniforms[ "amount" ].value = 0.2; // change it through time / increase with tank damages
effectRadioNoise.uniforms[ "width" ].value = WIDTH/4;
effectRadioNoise.uniforms[ "height" ].value = HEIGHT/4;
effectRadioNoise.uniforms[ "time" ].value = t/1000.;
effectPerturbation.uniforms[ "lines" ].value = HEIGHT/4;
effectPerturbation.uniforms[ "amount" ].value = damages/100; // damages = how many damage the tank get the last second
if (damages) {
effectPerturbation.uniforms["p"].value = Math.sin(t/150.);
effectPerturbation.uniforms[ "seed" ].value = Math.random();
}
}
function render () {
var delta = 0.01;
renderer.setViewport(0, 0, WIDTH, HEIGHT);
renderer.clear();
composerScene.render(delta);
renderer.setViewport(0, 0, WIDTH, HEIGHT);
composer.render(delta);
}
function createTank (p) {
var merged = new THREE.Geometry(),
base = new THREE.CubeGeometry(300, 450, 160),
turret = new THREE.CubeGeometry(200, 200, 120),
barrel = new THREE.CubeGeometry(40, 200, 40);
var mesh = null,
material = new THREE.MeshBasicMaterial({ color: 0x00FF00, wireframe: true, wireframeLinewidth: 2 });
mesh = new THREE.Mesh(base, material);
THREE.GeometryUtils.merge(merged, mesh);
mesh.position.z = 80;
mesh = new THREE.Mesh(turret, material);
mesh.position.z = 170;
THREE.GeometryUtils.merge(merged, mesh);
mesh = new THREE.Mesh(barrel, material);
mesh.position.z = 180;
mesh.position.y = -200;
THREE.GeometryUtils.merge(merged, mesh);
merged.computeFaceNormals();
merged.computeBoundingBox();
mesh = new THREE.Mesh(merged, material);
mesh.position = p;
return mesh;
}
// Updates for the demo
var lastDamageUpdate = 0;
function update () {
var now = +new Date();
var t = now-startTime;
camera.rotation.y = t/1000;
if (t-lastDamageUpdate > 1000) {
lastDamageUpdate = t;
if (Math.random()<0.3) {
damages = Math.random()*100;
}
else {
damages = 0;
}
}
}
// Define the shaders
var Shaders = {
'radionoise' : {
uniforms: {
tDiffuse: { type: "t", value: 0, texture: null },
amount: { type: "f", value: 0.1 },
time: { type: "f", value: 0 },
width: { type: "f", value: 300},
height: { type: "f", value: 300}
},
vertexShader: [
"varying vec2 vUv;",
"void main() {",
"vUv = vec2( uv.x, 1.0 - uv.y );",
"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
"}"
].join("\n"),
fragmentShader: [
"uniform float amount;",
"uniform float time;",
"uniform float width;",
"uniform float height;",
"uniform sampler2D tDiffuse;",
"varying vec2 vUv;",
"float rand(vec2 co){",
" return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);",
"}",
"void main( void ) {",
" vec2 position = vUv;",
"vec4 colorInput = texture2D( tDiffuse, vUv );",
"vec2 roundPos = vec2(floor(width*position.x)/width,",
"floor(height*position.y)/height);",
"vec3 color = vec3(0.1, 1.0, 0.1)*vec3(rand(roundPos+time/1000.));",
"float d2 = 1.;",
"if (cos(position.y*40.+time*3.)<-0.95)",
" color += vec3(0,0.07,0);",
"if (0.99999+cos(position.y*1.+time*0.8)<0.)",
" color += vec3(0,0.15,0);",
" gl_FragColor = colorInput*(1.0-amount)+amount*vec4( color, 1. );",
"}"
].join("\n")
},
'perturbation' : {
uniforms: {
tDiffuse: { type: "t", value: 0, texture: null },
p: { type: "f", value: 0 },
seed: { type: "f", value: 0 },
amount: { type: "f", value: 0 },
lines: { type: "f", value: 300 }
},
vertexShader: [
"varying vec2 vUv;",
"void main() {",
"vUv = vec2( uv.x, 1.0 - uv.y );",
"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
"}"
].join("\n"),
fragmentShader: [
"uniform float p;",
"uniform float amount;",
"uniform float seed;",
"uniform float lines;",
"uniform sampler2D tDiffuse;",
"varying vec2 vUv;",
"float rand(vec2 co){",
" return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);",
"}",
"void main( void ) {",
"vec2 position = vUv;",
"float y = floor(lines*position.y)/lines;",
"float disf = 0.01*(cos(position.y*130.+p*10.)+sin(position.y*183.+p*80.));",
"float parity = 0.; if(mod(y*lines, 2.)>0.5) parity=1.; else parity=-1.;",
"float a = smoothstep(0., 1.0, p);",
"position.x = amount*a*(y*0.3+disf)+position.x+",
"amount*0.5*parity*smoothstep(0.6, 0.65, p)*(sin(position.y*(12.+40.*seed))+smoothstep(0.64, 0.65, p));",
"vec4 colorInput = texture2D( tDiffuse, position );",
"gl_FragColor = colorInput;",
"}"
].join("\n")
}
};
setup();
requestAnimationFrame(function loop () {
requestAnimationFrame(loop);
update();
updateEffects();
render();
});
<div id="c"></div>
External resources loaded into this fiddle: