<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
<!------ Include the above in your HEAD tag ---------->
<!DOCTYPE html><html lang='en' class=''>
<head><script src='//production-assets.codepen.io/assets/editor/live/console_runner-079c09a0e3b9ff743e39ee2d5637b9216b3545af0de366d4b9aad9dc87e26bfd.js'></script><script src='//production-assets.codepen.io/assets/editor/live/events_runner-73716630c22bbc8cff4bd0f07b135f00a0bdc5d14629260c3ec49e5606f98fdd.js'></script><script src='//production-assets.codepen.io/assets/editor/live/css_live_reload_init-2c0dc5167d60a5af3ee189d570b1835129687ea2a61bee3513dee3a50c115a77.js'></script><meta charset='UTF-8'><meta name="robots" content="noindex"><link rel="shortcut icon" type="image/x-icon" href="//production-assets.codepen.io/assets/favicon/favicon-8ea04875e70c4b0bb41da869e81236e54394d63638a1ef12fa558a4a835f1164.ico" /><link rel="mask-icon" type="" href="//production-assets.codepen.io/assets/favicon/logo-pin-f2d2b6d2c61838f7e76325261b7195c27224080bc099486ddd6dccb469b8e8e6.svg" color="#111" /><link rel="canonical" href="https://codepen.io/peterhry/pen/egzjGR" />
<link rel='stylesheet prefetch' href='https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css'>
<style class="cp-pen-styles">body{
background: #000;
}
canvas{
display: block;
}</style></head><body>
<script src='//production-assets.codepen.io/assets/common/stopExecutionOnTimeout-b2a7b3fe212eaa732349046d8416e00a9dec26eb7fd347590fbced3ab38af52e.js'></script><script src='https://unpkg.com/three'></script><script src='https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.5.1/dat.gui.min.js'></script><script src='https://unpkg.com/three@0.83.0/examples/js/shaders/CopyShader.js'></script><script src='https://unpkg.com/three@0.83.0/examples/js/postprocessing/EffectComposer.js'></script><script src='https://unpkg.com/three@0.83.0/examples/js/postprocessing/RenderPass.js'></script><script src='https://unpkg.com/three@0.83.0/examples/js/postprocessing/ShaderPass.js'></script><script src='https://unpkg.com/three@0.83.0/examples/js/shaders/HorizontalBlurShader.js'></script><script src='https://unpkg.com/three@0.83.0/examples/js/shaders/VerticalBlurShader.js'></script><script src='https://unpkg.com/three@0.83.0/examples/js/shaders/FilmShader.js'></script><script src='https://unpkg.com/three@0.83.0/examples/js/shaders/LuminosityHighPassShader.js'></script><script src='https://unpkg.com/three@0.83.0/examples/js/postprocessing/UnrealBloomPass.js'></script><script src='https://cdn.rawgit.com/felixturner/bad-tv-shader/master/BadTVShader.js'></script>
<script >THREE.VolumetericLightShader = {
uniforms: {
tDiffuse: { value: null },
lightPosition: { value: new THREE.Vector2(0.5, 0.5) },
exposure: { value: 1 },
decay: { value: 1 },
density: { value: 6 },
weight: { value: 0.57 },
samples: { value: 30 }
},
vertexShader: ["varying vec2 vUv;", "void main() {", "vUv = uv;", "gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);", "}"].join("\n"),
fragmentShader: ["varying vec2 vUv;", "uniform sampler2D tDiffuse;", "uniform vec2 lightPosition;", "uniform float exposure;", "uniform float decay;", "uniform float density;", "uniform float weight;", "uniform int samples;", "const int MAX_SAMPLES = 100;", "void main()", "{", "vec2 texCoord = vUv;", "vec2 deltaTextCoord = texCoord - lightPosition;", "deltaTextCoord *= 1.0 / float(samples) * density;", "vec4 color = texture2D(tDiffuse, texCoord);", "float illuminationDecay = 1.0;", "for(int i=0; i < MAX_SAMPLES; i++)", "{", "if(i == samples) {", "break;", "}", "texCoord += deltaTextCoord;", "vec4 sample = texture2D(tDiffuse, texCoord);", "sample *= illuminationDecay * weight;", "color += sample;", "illuminationDecay *= decay;", "}", "gl_FragColor = color * exposure;", "}"].join("\n")
};
THREE.AdditiveBlendingShader = {
uniforms: {
tDiffuse: { value: null },
tAdd: { value: null }
},
vertexShader: ["varying vec2 vUv;", "void main() {", "vUv = uv;", "gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);", "}"].join("\n"),
fragmentShader: ["uniform sampler2D tDiffuse;", "uniform sampler2D tAdd;", "varying vec2 vUv;", "void main() {", "vec4 color = texture2D(tDiffuse, vUv);", "vec4 add = texture2D(tAdd, vUv);", "gl_FragColor = color + add;", "}"].join("\n")
};
THREE.PassThroughShader = {
uniforms: {
tDiffuse: { value: null }
},
vertexShader: ["varying vec2 vUv;", "void main() {", "vUv = uv;", "gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);", "}"].join("\n"),
fragmentShader: ["uniform sampler2D tDiffuse;", "varying vec2 vUv;", "void main() {", "gl_FragColor = texture2D(tDiffuse, vec2(vUv.x, vUv.y));", "}"].join("\n")
};
var getImageTexture = function getImageTexture(image) {
var density = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
var width = image.width,
height = image.height;
canvas.setAttribute('width', width * density);
canvas.setAttribute('height', height * density);
canvas.style.width = width + "px";
canvas.style.height = height + "px";
ctx.drawImage(image, 0, 0, width * density, height * density);
return canvas;
};
var width = 1280;
var height = 720;
var lightColor = 0x0099ff;
var DEFAULT_LAYER = 0;
var OCCLUSION_LAYER = 1;
var renderScale = .25;
var gui = new dat.GUI();
var clock = new THREE.Clock();
var composer = void 0,
filmPass = void 0,
badTVPass = void 0,
bloomPass = void 0,
occlusionComposer = void 0,
itemMesh = void 0,
occMesh = void 0,
occRenderTarget = void 0,
lightSource = void 0,
vlShaderUniforms = void 0;
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000);
var renderer = new THREE.WebGLRenderer({
antialias: false
});
renderer.setSize(width, height);
document.body.appendChild(renderer.domElement);
function setupScene() {
lightSource = new THREE.Object3D();
lightSource.position.x = 0;
lightSource.position.y = -15;
lightSource.position.z = -15;
var itemGeo = new THREE.PlaneGeometry(9, 2.1);
var itemMaterial = new THREE.MeshBasicMaterial({ transparent: true, opacity: 0.7 });
var img = new Image();
img.src = 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/13307/blaster.png';
img.crossOrigin = 'Anonymous';
img.onload = function () {
var itemTexture = new THREE.Texture(getImageTexture(img), null, THREE.ClampToEdgeWrapping, THREE.ClampToEdgeWrapping, null, THREE.LinearFilter);
itemTexture.needsUpdate = true;
itemMaterial.map = itemTexture;
itemMesh = new THREE.Mesh(itemGeo, itemMaterial);
scene.add(itemMesh);
var occItemMaterial = new THREE.MeshBasicMaterial({ color: lightColor });
occItemMaterial.map = itemTexture;
occMesh = new THREE.Mesh(itemGeo, occItemMaterial);
occMesh.layers.set(OCCLUSION_LAYER);
scene.add(occMesh);
};
camera.position.z = 4.5;
}
function setupPostprocessing() {
occRenderTarget = new THREE.WebGLRenderTarget(width * renderScale, height * renderScale);
// Blur passes
var hBlur = new THREE.ShaderPass(THREE.HorizontalBlurShader);
var vBlur = new THREE.ShaderPass(THREE.VerticalBlurShader);
var bluriness = 7;
hBlur.uniforms.h.value = bluriness / width;
vBlur.uniforms.v.value = bluriness / height;
// Bad TV Pass
badTVPass = new THREE.ShaderPass(THREE.BadTVShader);
badTVPass.uniforms.distortion.value = 1.9;
badTVPass.uniforms.distortion2.value = 1.2;
badTVPass.uniforms.speed.value = 0.1;
badTVPass.uniforms.rollSpeed.value = 0;
// Volumetric Light Pass
var vlPass = new THREE.ShaderPass(THREE.VolumetericLightShader);
vlShaderUniforms = vlPass.uniforms;
vlPass.needsSwap = false;
// Occlusion Composer
occlusionComposer = new THREE.EffectComposer(renderer, occRenderTarget);
occlusionComposer.addPass(new THREE.RenderPass(scene, camera));
occlusionComposer.addPass(hBlur);
occlusionComposer.addPass(vBlur);
occlusionComposer.addPass(hBlur);
occlusionComposer.addPass(vBlur);
occlusionComposer.addPass(hBlur);
occlusionComposer.addPass(badTVPass);
occlusionComposer.addPass(vlPass);
// Bloom pass
bloomPass = new THREE.UnrealBloomPass(width / height, 0.5, .8, .3);
// Film pass
filmPass = new THREE.ShaderPass(THREE.FilmShader);
filmPass.uniforms.sCount.value = 1200;
filmPass.uniforms.grayscale.value = false;
filmPass.uniforms.sIntensity.value = 1.5;
filmPass.uniforms.nIntensity.value = 0.2;
// Blend occRenderTarget into main render target
var blendPass = new THREE.ShaderPass(THREE.AdditiveBlendingShader);
blendPass.uniforms.tAdd.value = occRenderTarget.texture;
blendPass.renderToScreen = true;
// Main Composer
composer = new THREE.EffectComposer(renderer);
composer.addPass(new THREE.RenderPass(scene, camera));
composer.addPass(bloomPass);
composer.addPass(badTVPass);
composer.addPass(filmPass);
composer.addPass(blendPass);
}
function onFrame() {
requestAnimationFrame(onFrame);
update();
render();
}
function update() {
var timeDelta = clock.getDelta();
var elapsed = clock.getElapsedTime();
filmPass.uniforms.time.value += timeDelta;
badTVPass.uniforms.time.value += 0.01;
if (itemMesh) {
itemMesh.rotation.y = Math.sin(elapsed / 2) / 15;
itemMesh.rotation.z = Math.cos(elapsed / 2) / 50;
occMesh.rotation.copy(itemMesh.rotation);
}
}
function render() {
camera.layers.set(OCCLUSION_LAYER);
//renderer.setClearColor(0x000000);
occlusionComposer.render();
camera.layers.set(DEFAULT_LAYER);
//renderer.setClearColor(0x000000);
composer.render();
}
function setupGUI() {
var folder = void 0,
min = void 0,
max = void 0,
step = void 0,
updateShaderLight = function updateShaderLight() {
var p = lightSource.position.clone(),
vector = p.project(camera),
x = (vector.x + 1) / 2,
y = (vector.y + 1) / 2;
vlShaderUniforms.lightPosition.value.set(x, y);
};
updateShaderLight();
// Bloom Controls
folder = gui.addFolder('Bloom');
folder.add(bloomPass, 'radius').min(0).max(10).name('Radius');
folder.add(bloomPass, 'threshold').min(0).max(1).name('Threshold');
folder.add(bloomPass, 'strength').min(0).max(10).name('Strength');
folder.open();
// Bad TV Controls
folder = gui.addFolder('TV');
folder.add(badTVPass.uniforms.distortion, 'value').min(0).max(10).name('Distortion 1');
folder.add(badTVPass.uniforms.distortion2, 'value').min(0).max(10).name('Distortion 2');
folder.add(badTVPass.uniforms.speed, 'value').min(0).max(1).name('Speed');
folder.add(badTVPass.uniforms.rollSpeed, 'value').min(0).max(10).name('Roll Speed');
folder.open();
// Light Controls
folder = gui.addFolder('Light Position');
folder.add(lightSource.position, 'x').min(-50).max(50).onChange(updateShaderLight);
folder.add(lightSource.position, 'y').min(-50).max(50).onChange(updateShaderLight);
folder.add(lightSource.position, 'z').min(-50).max(50).onChange(updateShaderLight);
folder.open();
// Volumetric Light Controls
folder = gui.addFolder('Volumeteric Light Shader');
folder.add(vlShaderUniforms.exposure, 'value').min(0).max(1).name('Exposure');
folder.add(vlShaderUniforms.decay, 'value').min(0).max(1).name('Decay');
folder.add(vlShaderUniforms.density, 'value').min(0).max(10).name('Density');
folder.add(vlShaderUniforms.weight, 'value').min(0).max(1).name('Weight');
folder.add(vlShaderUniforms.samples, 'value').min(1).max(100).name('Samples');
folder.open();
}
function addRenderTargetImage() {
var material = new THREE.ShaderMaterial(THREE.PassThroughShader);
material.uniforms.tDiffuse.value = occRenderTarget.texture;
var mesh = new THREE.Mesh(new THREE.PlaneBufferGeometry(2, 2), material);
composer.passes[1].scene.add(mesh);
mesh.visible = false;
var folder = gui.addFolder('Light Pass Render Image');
folder.add(mesh, 'visible');
folder.open();
}
setupScene();
setupPostprocessing();
onFrame();
setupGUI();
addRenderTargetImage();
//# sourceURL=pen.js
</script>
</body></html>