first commit
This commit is contained in:
+115
@@ -0,0 +1,115 @@
|
|||||||
|
/**
|
||||||
|
* @author alteredq / http://alteredqualia.com/
|
||||||
|
*/
|
||||||
|
|
||||||
|
THREE.BloomPass = function ( strength, kernelSize, sigma, resolution ) {
|
||||||
|
|
||||||
|
strength = ( strength !== undefined ) ? strength : 1;
|
||||||
|
kernelSize = ( kernelSize !== undefined ) ? kernelSize : 25;
|
||||||
|
sigma = ( sigma !== undefined ) ? sigma : 4.0;
|
||||||
|
resolution = ( resolution !== undefined ) ? resolution : 256;
|
||||||
|
|
||||||
|
// render targets
|
||||||
|
|
||||||
|
var pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat };
|
||||||
|
|
||||||
|
this.renderTargetX = new THREE.WebGLRenderTarget( resolution, resolution, pars );
|
||||||
|
this.renderTargetY = new THREE.WebGLRenderTarget( resolution, resolution, pars );
|
||||||
|
|
||||||
|
// copy material
|
||||||
|
|
||||||
|
if ( THREE.CopyShader === undefined )
|
||||||
|
console.error( "THREE.BloomPass relies on THREE.CopyShader" );
|
||||||
|
|
||||||
|
var copyShader = THREE.CopyShader;
|
||||||
|
|
||||||
|
this.copyUniforms = THREE.UniformsUtils.clone( copyShader.uniforms );
|
||||||
|
|
||||||
|
this.copyUniforms[ "opacity" ].value = strength;
|
||||||
|
|
||||||
|
this.materialCopy = new THREE.ShaderMaterial( {
|
||||||
|
|
||||||
|
uniforms: this.copyUniforms,
|
||||||
|
vertexShader: copyShader.vertexShader,
|
||||||
|
fragmentShader: copyShader.fragmentShader,
|
||||||
|
blending: THREE.AdditiveBlending,
|
||||||
|
transparent: true
|
||||||
|
|
||||||
|
} );
|
||||||
|
|
||||||
|
// convolution material
|
||||||
|
|
||||||
|
if ( THREE.ConvolutionShader === undefined )
|
||||||
|
console.error( "THREE.BloomPass relies on THREE.ConvolutionShader" );
|
||||||
|
|
||||||
|
var convolutionShader = THREE.ConvolutionShader;
|
||||||
|
|
||||||
|
this.convolutionUniforms = THREE.UniformsUtils.clone( convolutionShader.uniforms );
|
||||||
|
|
||||||
|
this.convolutionUniforms[ "uImageIncrement" ].value = THREE.BloomPass.blurx;
|
||||||
|
this.convolutionUniforms[ "cKernel" ].value = THREE.ConvolutionShader.buildKernel( sigma );
|
||||||
|
|
||||||
|
this.materialConvolution = new THREE.ShaderMaterial( {
|
||||||
|
|
||||||
|
uniforms: this.convolutionUniforms,
|
||||||
|
vertexShader: convolutionShader.vertexShader,
|
||||||
|
fragmentShader: convolutionShader.fragmentShader,
|
||||||
|
defines: {
|
||||||
|
"KERNEL_SIZE_FLOAT": kernelSize.toFixed( 1 ),
|
||||||
|
"KERNEL_SIZE_INT": kernelSize.toFixed( 0 )
|
||||||
|
}
|
||||||
|
|
||||||
|
} );
|
||||||
|
|
||||||
|
this.enabled = true;
|
||||||
|
this.needsSwap = false;
|
||||||
|
this.clear = false;
|
||||||
|
|
||||||
|
|
||||||
|
this.camera = new THREE.OrthographicCamera( -1, 1, 1, -1, 0, 1 );
|
||||||
|
this.scene = new THREE.Scene();
|
||||||
|
|
||||||
|
this.quad = new THREE.Mesh( new THREE.PlaneGeometry( 2, 2 ), null );
|
||||||
|
this.scene.add( this.quad );
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
THREE.BloomPass.prototype = {
|
||||||
|
|
||||||
|
render: function ( renderer, writeBuffer, readBuffer, delta, maskActive ) {
|
||||||
|
|
||||||
|
if ( maskActive ) renderer.context.disable( renderer.context.STENCIL_TEST );
|
||||||
|
|
||||||
|
// Render quad with blured scene into texture (convolution pass 1)
|
||||||
|
|
||||||
|
this.quad.material = this.materialConvolution;
|
||||||
|
|
||||||
|
this.convolutionUniforms[ "tDiffuse" ].value = readBuffer;
|
||||||
|
this.convolutionUniforms[ "uImageIncrement" ].value = THREE.BloomPass.blurX;
|
||||||
|
|
||||||
|
renderer.render( this.scene, this.camera, this.renderTargetX, true );
|
||||||
|
|
||||||
|
|
||||||
|
// Render quad with blured scene into texture (convolution pass 2)
|
||||||
|
|
||||||
|
this.convolutionUniforms[ "tDiffuse" ].value = this.renderTargetX;
|
||||||
|
this.convolutionUniforms[ "uImageIncrement" ].value = THREE.BloomPass.blurY;
|
||||||
|
|
||||||
|
renderer.render( this.scene, this.camera, this.renderTargetY, true );
|
||||||
|
|
||||||
|
// Render original scene with superimposed blur to texture
|
||||||
|
|
||||||
|
this.quad.material = this.materialCopy;
|
||||||
|
|
||||||
|
this.copyUniforms[ "tDiffuse" ].value = this.renderTargetY;
|
||||||
|
|
||||||
|
if ( maskActive ) renderer.context.enable( renderer.context.STENCIL_TEST );
|
||||||
|
|
||||||
|
renderer.render( this.scene, this.camera, readBuffer, this.clear );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
THREE.BloomPass.blurX = new THREE.Vector2( 0.001953125, 0.0 );
|
||||||
|
THREE.BloomPass.blurY = new THREE.Vector2( 0.0, 0.001953125 );
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
/**
|
||||||
|
* @author alteredq / http://alteredqualia.com/
|
||||||
|
*
|
||||||
|
* Convolution shader
|
||||||
|
* ported from o3d sample to WebGL / GLSL
|
||||||
|
* http://o3d.googlecode.com/svn/trunk/samples/convolution.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
THREE.ConvolutionShader = {
|
||||||
|
|
||||||
|
defines: {
|
||||||
|
|
||||||
|
"KERNEL_SIZE_FLOAT": "25.0",
|
||||||
|
"KERNEL_SIZE_INT": "25",
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
uniforms: {
|
||||||
|
|
||||||
|
"tDiffuse": { type: "t", value: null },
|
||||||
|
"uImageIncrement": { type: "v2", value: new THREE.Vector2( 0.001953125, 0.0 ) },
|
||||||
|
"cKernel": { type: "fv1", value: [] }
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
vertexShader: [
|
||||||
|
|
||||||
|
"uniform vec2 uImageIncrement;",
|
||||||
|
|
||||||
|
"varying vec2 vUv;",
|
||||||
|
|
||||||
|
"void main() {",
|
||||||
|
|
||||||
|
"vUv = uv - ( ( KERNEL_SIZE_FLOAT - 1.0 ) / 2.0 ) * uImageIncrement;",
|
||||||
|
"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
|
||||||
|
|
||||||
|
"}"
|
||||||
|
|
||||||
|
].join("\n"),
|
||||||
|
|
||||||
|
fragmentShader: [
|
||||||
|
|
||||||
|
"uniform float cKernel[ KERNEL_SIZE_INT ];",
|
||||||
|
|
||||||
|
"uniform sampler2D tDiffuse;",
|
||||||
|
"uniform vec2 uImageIncrement;",
|
||||||
|
|
||||||
|
"varying vec2 vUv;",
|
||||||
|
|
||||||
|
"void main() {",
|
||||||
|
|
||||||
|
"vec2 imageCoord = vUv;",
|
||||||
|
"vec4 sum = vec4( 0.0, 0.0, 0.0, 0.0 );",
|
||||||
|
|
||||||
|
"for( int i = 0; i < KERNEL_SIZE_INT; i ++ ) {",
|
||||||
|
|
||||||
|
"sum += texture2D( tDiffuse, imageCoord ) * cKernel[ i ];",
|
||||||
|
"imageCoord += uImageIncrement;",
|
||||||
|
|
||||||
|
"}",
|
||||||
|
|
||||||
|
"gl_FragColor = sum;",
|
||||||
|
|
||||||
|
"}"
|
||||||
|
|
||||||
|
|
||||||
|
].join("\n"),
|
||||||
|
|
||||||
|
buildKernel: function ( sigma ) {
|
||||||
|
|
||||||
|
// We lop off the sqrt(2 * pi) * sigma term, since we're going to normalize anyway.
|
||||||
|
|
||||||
|
function gauss( x, sigma ) {
|
||||||
|
|
||||||
|
return Math.exp( - ( x * x ) / ( 2.0 * sigma * sigma ) );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var i, values, sum, halfWidth, kMaxKernelSize = 25, kernelSize = 2 * Math.ceil( sigma * 3.0 ) + 1;
|
||||||
|
|
||||||
|
if ( kernelSize > kMaxKernelSize ) kernelSize = kMaxKernelSize;
|
||||||
|
halfWidth = ( kernelSize - 1 ) * 0.5;
|
||||||
|
|
||||||
|
values = new Array( kernelSize );
|
||||||
|
sum = 0.0;
|
||||||
|
for ( i = 0; i < kernelSize; ++i ) {
|
||||||
|
|
||||||
|
values[ i ] = gauss( i - halfWidth, sigma );
|
||||||
|
sum += values[ i ];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// normalize the kernel
|
||||||
|
|
||||||
|
for ( i = 0; i < kernelSize; ++i ) values[ i ] /= sum;
|
||||||
|
|
||||||
|
return values;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
/**
|
||||||
|
* @author alteredq / http://alteredqualia.com/
|
||||||
|
*
|
||||||
|
* Full-screen textured quad shader
|
||||||
|
*/
|
||||||
|
|
||||||
|
THREE.CopyShader = {
|
||||||
|
|
||||||
|
uniforms: {
|
||||||
|
|
||||||
|
"tDiffuse": { type: "t", value: null },
|
||||||
|
"opacity": { 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 float opacity;",
|
||||||
|
|
||||||
|
"uniform sampler2D tDiffuse;",
|
||||||
|
|
||||||
|
"varying vec2 vUv;",
|
||||||
|
|
||||||
|
"void main() {",
|
||||||
|
|
||||||
|
"vec4 texel = texture2D( tDiffuse, vUv );",
|
||||||
|
"gl_FragColor = opacity * texel;",
|
||||||
|
|
||||||
|
"}"
|
||||||
|
|
||||||
|
].join("\n")
|
||||||
|
|
||||||
|
};
|
||||||
+59
@@ -0,0 +1,59 @@
|
|||||||
|
/**
|
||||||
|
* @author alteredq / http://alteredqualia.com/
|
||||||
|
* @author mr.doob / http://mrdoob.com/
|
||||||
|
*/
|
||||||
|
|
||||||
|
var Detector = {
|
||||||
|
|
||||||
|
canvas: !! window.CanvasRenderingContext2D,
|
||||||
|
webgl: ( function () { try { var canvas = document.createElement( 'canvas' ); return !! window.WebGLRenderingContext && ( canvas.getContext( 'webgl' ) || canvas.getContext( 'experimental-webgl' ) ); } catch( e ) { return false; } } )(),
|
||||||
|
workers: !! window.Worker,
|
||||||
|
fileapi: window.File && window.FileReader && window.FileList && window.Blob,
|
||||||
|
|
||||||
|
getWebGLErrorMessage: function () {
|
||||||
|
|
||||||
|
var element = document.createElement( 'div' );
|
||||||
|
element.id = 'webgl-error-message';
|
||||||
|
element.style.fontFamily = 'monospace';
|
||||||
|
element.style.fontSize = '13px';
|
||||||
|
element.style.fontWeight = 'normal';
|
||||||
|
element.style.textAlign = 'center';
|
||||||
|
element.style.background = '#fff';
|
||||||
|
element.style.color = '#000';
|
||||||
|
element.style.padding = '1.5em';
|
||||||
|
element.style.width = '400px';
|
||||||
|
element.style.margin = '5em auto 0';
|
||||||
|
|
||||||
|
if ( ! this.webgl ) {
|
||||||
|
|
||||||
|
element.innerHTML = window.WebGLRenderingContext ? [
|
||||||
|
'Your graphics card does not seem to support <a href="http://khronos.org/webgl/wiki/Getting_a_WebGL_Implementation" style="color:#000">WebGL</a>.<br />',
|
||||||
|
'Find out how to get it <a href="http://get.webgl.org/" style="color:#000">here</a>.'
|
||||||
|
].join( '\n' ) : [
|
||||||
|
'Your browser does not seem to support <a href="http://khronos.org/webgl/wiki/Getting_a_WebGL_Implementation" style="color:#000">WebGL</a>.<br/>',
|
||||||
|
'Find out how to get it <a href="http://get.webgl.org/" style="color:#000">here</a>.'
|
||||||
|
].join( '\n' );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return element;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
addGetWebGLMessage: function ( parameters ) {
|
||||||
|
|
||||||
|
var parent, id, element;
|
||||||
|
|
||||||
|
parameters = parameters || {};
|
||||||
|
|
||||||
|
parent = parameters.parent !== undefined ? parameters.parent : document.body;
|
||||||
|
id = parameters.id !== undefined ? parameters.id : 'oldie';
|
||||||
|
|
||||||
|
element = Detector.getWebGLErrorMessage();
|
||||||
|
element.id = id;
|
||||||
|
|
||||||
|
parent.appendChild( element );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
@@ -0,0 +1,135 @@
|
|||||||
|
/**
|
||||||
|
* @author alteredq / http://alteredqualia.com/
|
||||||
|
*/
|
||||||
|
|
||||||
|
THREE.EffectComposer = function ( renderer, renderTarget ) {
|
||||||
|
|
||||||
|
this.renderer = renderer;
|
||||||
|
|
||||||
|
if ( renderTarget === undefined ) {
|
||||||
|
|
||||||
|
var width = window.innerWidth || 1;
|
||||||
|
var height = window.innerHeight || 1;
|
||||||
|
var parameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBuffer: false };
|
||||||
|
|
||||||
|
renderTarget = new THREE.WebGLRenderTarget( width, height, parameters );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
this.renderTarget1 = renderTarget;
|
||||||
|
this.renderTarget2 = renderTarget.clone();
|
||||||
|
|
||||||
|
this.writeBuffer = this.renderTarget1;
|
||||||
|
this.readBuffer = this.renderTarget2;
|
||||||
|
|
||||||
|
this.passes = [];
|
||||||
|
|
||||||
|
if ( THREE.CopyShader === undefined )
|
||||||
|
console.error( "THREE.EffectComposer relies on THREE.CopyShader" );
|
||||||
|
|
||||||
|
this.copyPass = new THREE.ShaderPass( THREE.CopyShader );
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
THREE.EffectComposer.prototype = {
|
||||||
|
|
||||||
|
swapBuffers: function() {
|
||||||
|
|
||||||
|
var tmp = this.readBuffer;
|
||||||
|
this.readBuffer = this.writeBuffer;
|
||||||
|
this.writeBuffer = tmp;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
addPass: function ( pass ) {
|
||||||
|
|
||||||
|
this.passes.push( pass );
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
insertPass: function ( pass, index ) {
|
||||||
|
|
||||||
|
this.passes.splice( index, 0, pass );
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function ( delta ) {
|
||||||
|
|
||||||
|
this.writeBuffer = this.renderTarget1;
|
||||||
|
this.readBuffer = this.renderTarget2;
|
||||||
|
|
||||||
|
var maskActive = false;
|
||||||
|
|
||||||
|
var pass, i, il = this.passes.length;
|
||||||
|
|
||||||
|
for ( i = 0; i < il; i ++ ) {
|
||||||
|
|
||||||
|
pass = this.passes[ i ];
|
||||||
|
|
||||||
|
if ( !pass.enabled ) continue;
|
||||||
|
|
||||||
|
pass.render( this.renderer, this.writeBuffer, this.readBuffer, delta, maskActive );
|
||||||
|
|
||||||
|
if ( pass.needsSwap ) {
|
||||||
|
|
||||||
|
if ( maskActive ) {
|
||||||
|
|
||||||
|
var context = this.renderer.context;
|
||||||
|
|
||||||
|
context.stencilFunc( context.NOTEQUAL, 1, 0xffffffff );
|
||||||
|
|
||||||
|
this.copyPass.render( this.renderer, this.writeBuffer, this.readBuffer, delta );
|
||||||
|
|
||||||
|
context.stencilFunc( context.EQUAL, 1, 0xffffffff );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
this.swapBuffers();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( pass instanceof THREE.MaskPass ) {
|
||||||
|
|
||||||
|
maskActive = true;
|
||||||
|
|
||||||
|
} else if ( pass instanceof THREE.ClearMaskPass ) {
|
||||||
|
|
||||||
|
maskActive = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
reset: function ( renderTarget ) {
|
||||||
|
|
||||||
|
if ( renderTarget === undefined ) {
|
||||||
|
|
||||||
|
renderTarget = this.renderTarget1.clone();
|
||||||
|
|
||||||
|
renderTarget.width = window.innerWidth;
|
||||||
|
renderTarget.height = window.innerHeight;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
this.renderTarget1 = renderTarget;
|
||||||
|
this.renderTarget2 = renderTarget.clone();
|
||||||
|
|
||||||
|
this.writeBuffer = this.renderTarget1;
|
||||||
|
this.readBuffer = this.renderTarget2;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
setSize: function ( width, height ) {
|
||||||
|
|
||||||
|
var renderTarget = this.renderTarget1.clone();
|
||||||
|
|
||||||
|
renderTarget.width = width;
|
||||||
|
renderTarget.height = height;
|
||||||
|
|
||||||
|
this.reset( renderTarget );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
+137
@@ -0,0 +1,137 @@
|
|||||||
|
/**
|
||||||
|
* @author Felix Turner / www.airtight.cc / @felixturner
|
||||||
|
*
|
||||||
|
* Bad TV Shader
|
||||||
|
* Simulates a bad TV via horizontal distortion and vertical roll
|
||||||
|
* Uses Ashima WebGl Noise: https://github.com/ashima/webgl-noise
|
||||||
|
*
|
||||||
|
* time: steadily increasing float passed in
|
||||||
|
* distortion: amount of thick distortion
|
||||||
|
* distortion2: amount of fine grain distortion
|
||||||
|
* speed: distortion vertical travel speed
|
||||||
|
* rollSpeed: vertical roll speed
|
||||||
|
*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2014 Felix Turner
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
THREE.BadTVShader = {
|
||||||
|
uniforms: {
|
||||||
|
"tDiffuse": { type: "t", value: null },
|
||||||
|
"time": { type: "f", value: 0.0 },
|
||||||
|
"distortion": { type: "f", value: 3.0 },
|
||||||
|
"distortion2": { type: "f", value: 5.0 },
|
||||||
|
"speed": { type: "f", value: 0.2 },
|
||||||
|
"rollSpeed": { type: "f", value: 0.1 },
|
||||||
|
},
|
||||||
|
|
||||||
|
vertexShader: [
|
||||||
|
"varying vec2 vUv;",
|
||||||
|
"void main() {",
|
||||||
|
"vUv = uv;",
|
||||||
|
"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
|
||||||
|
"}"
|
||||||
|
|
||||||
|
].join("\n"),
|
||||||
|
|
||||||
|
fragmentShader: [
|
||||||
|
|
||||||
|
"uniform sampler2D tDiffuse;",
|
||||||
|
"uniform float time;",
|
||||||
|
"uniform float distortion;",
|
||||||
|
"uniform float distortion2;",
|
||||||
|
"uniform float speed;",
|
||||||
|
"uniform float rollSpeed;",
|
||||||
|
"varying vec2 vUv;",
|
||||||
|
|
||||||
|
// Start Ashima 2D Simplex Noise
|
||||||
|
|
||||||
|
"vec3 mod289(vec3 x) {",
|
||||||
|
" return x - floor(x * (1.0 / 289.0)) * 289.0;",
|
||||||
|
"}",
|
||||||
|
|
||||||
|
"vec2 mod289(vec2 x) {",
|
||||||
|
" return x - floor(x * (1.0 / 289.0)) * 289.0;",
|
||||||
|
"}",
|
||||||
|
|
||||||
|
"vec3 permute(vec3 x) {",
|
||||||
|
" return mod289(((x*34.0)+1.0)*x);",
|
||||||
|
"}",
|
||||||
|
|
||||||
|
"float snoise(vec2 v)",
|
||||||
|
" {",
|
||||||
|
" const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0",
|
||||||
|
" 0.366025403784439, // 0.5*(sqrt(3.0)-1.0)",
|
||||||
|
" -0.577350269189626, // -1.0 + 2.0 * C.x",
|
||||||
|
" 0.024390243902439); // 1.0 / 41.0",
|
||||||
|
" vec2 i = floor(v + dot(v, C.yy) );",
|
||||||
|
" vec2 x0 = v - i + dot(i, C.xx);",
|
||||||
|
|
||||||
|
" vec2 i1;",
|
||||||
|
" i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);",
|
||||||
|
" vec4 x12 = x0.xyxy + C.xxzz;",
|
||||||
|
" x12.xy -= i1;",
|
||||||
|
|
||||||
|
" i = mod289(i); // Avoid truncation effects in permutation",
|
||||||
|
" vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 ))",
|
||||||
|
" + i.x + vec3(0.0, i1.x, 1.0 ));",
|
||||||
|
|
||||||
|
" vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0);",
|
||||||
|
" m = m*m ;",
|
||||||
|
" m = m*m ;",
|
||||||
|
|
||||||
|
" vec3 x = 2.0 * fract(p * C.www) - 1.0;",
|
||||||
|
" vec3 h = abs(x) - 0.5;",
|
||||||
|
" vec3 ox = floor(x + 0.5);",
|
||||||
|
" vec3 a0 = x - ox;",
|
||||||
|
|
||||||
|
" m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h );",
|
||||||
|
|
||||||
|
" vec3 g;",
|
||||||
|
" g.x = a0.x * x0.x + h.x * x0.y;",
|
||||||
|
" g.yz = a0.yz * x12.xz + h.yz * x12.yw;",
|
||||||
|
" return 130.0 * dot(m, g);",
|
||||||
|
"}",
|
||||||
|
|
||||||
|
// End Ashima 2D Simplex Noise
|
||||||
|
|
||||||
|
"void main() {",
|
||||||
|
|
||||||
|
"vec2 p = vUv;",
|
||||||
|
"float ty = time*speed;",
|
||||||
|
"float yt = p.y - ty;",
|
||||||
|
|
||||||
|
//smooth distortion
|
||||||
|
"float offset = snoise(vec2(yt*3.0,0.0))*0.2;",
|
||||||
|
// boost distortion
|
||||||
|
"offset = pow( offset*distortion,3.0)/distortion;",
|
||||||
|
//add fine grain distortion
|
||||||
|
"offset += snoise(vec2(yt*50.0,0.0))*distortion2*0.001;",
|
||||||
|
//combine distortion on X with roll on Y
|
||||||
|
"gl_FragColor = texture2D(tDiffuse, vec2(fract(p.x + offset),fract(p.y-time*rollSpeed) ));",
|
||||||
|
|
||||||
|
"}"
|
||||||
|
|
||||||
|
].join("\n")
|
||||||
|
|
||||||
|
};
|
||||||
+61
@@ -0,0 +1,61 @@
|
|||||||
|
/**
|
||||||
|
* @author alteredq / http://alteredqualia.com/
|
||||||
|
*/
|
||||||
|
|
||||||
|
THREE.FilmPass = function ( noiseIntensity, scanlinesIntensity, scanlinesCount, grayscale ) {
|
||||||
|
|
||||||
|
if ( THREE.FilmShader === undefined )
|
||||||
|
console.error( "THREE.FilmPass relies on THREE.FilmShader" );
|
||||||
|
|
||||||
|
var shader = THREE.FilmShader;
|
||||||
|
|
||||||
|
this.uniforms = THREE.UniformsUtils.clone( shader.uniforms );
|
||||||
|
|
||||||
|
this.material = new THREE.ShaderMaterial( {
|
||||||
|
|
||||||
|
uniforms: this.uniforms,
|
||||||
|
vertexShader: shader.vertexShader,
|
||||||
|
fragmentShader: shader.fragmentShader
|
||||||
|
|
||||||
|
} );
|
||||||
|
|
||||||
|
if ( grayscale !== undefined ) this.uniforms.grayscale.value = grayscale;
|
||||||
|
if ( noiseIntensity !== undefined ) this.uniforms.nIntensity.value = noiseIntensity;
|
||||||
|
if ( scanlinesIntensity !== undefined ) this.uniforms.sIntensity.value = scanlinesIntensity;
|
||||||
|
if ( scanlinesCount !== undefined ) this.uniforms.sCount.value = scanlinesCount;
|
||||||
|
|
||||||
|
this.enabled = true;
|
||||||
|
this.renderToScreen = false;
|
||||||
|
this.needsSwap = true;
|
||||||
|
|
||||||
|
|
||||||
|
this.camera = new THREE.OrthographicCamera( -1, 1, 1, -1, 0, 1 );
|
||||||
|
this.scene = new THREE.Scene();
|
||||||
|
|
||||||
|
this.quad = new THREE.Mesh( new THREE.PlaneGeometry( 2, 2 ), null );
|
||||||
|
this.scene.add( this.quad );
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
THREE.FilmPass.prototype = {
|
||||||
|
|
||||||
|
render: function ( renderer, writeBuffer, readBuffer, delta ) {
|
||||||
|
|
||||||
|
this.uniforms[ "tDiffuse" ].value = readBuffer;
|
||||||
|
this.uniforms[ "time" ].value += delta;
|
||||||
|
|
||||||
|
this.quad.material = this.material;
|
||||||
|
|
||||||
|
if ( this.renderToScreen ) {
|
||||||
|
|
||||||
|
renderer.render( this.scene, this.camera );
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
renderer.render( this.scene, this.camera, writeBuffer, false );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
+104
@@ -0,0 +1,104 @@
|
|||||||
|
/**
|
||||||
|
* @author alteredq / http://alteredqualia.com/
|
||||||
|
*
|
||||||
|
* Film grain & scanlines shader
|
||||||
|
*
|
||||||
|
* - ported from HLSL to WebGL / GLSL
|
||||||
|
* http://www.truevision3d.com/forums/showcase/staticnoise_colorblackwhite_scanline_shaders-t18698.0.html
|
||||||
|
*
|
||||||
|
* Screen Space Static Postprocessor
|
||||||
|
*
|
||||||
|
* Produces an analogue noise overlay similar to a film grain / TV static
|
||||||
|
*
|
||||||
|
* Original implementation and noise algorithm
|
||||||
|
* Pat 'Hawthorne' Shearon
|
||||||
|
*
|
||||||
|
* Optimized scanlines + noise version with intensity scaling
|
||||||
|
* Georg 'Leviathan' Steinrohder
|
||||||
|
*
|
||||||
|
* This version is provided under a Creative Commons Attribution 3.0 License
|
||||||
|
* http://creativecommons.org/licenses/by/3.0/
|
||||||
|
*/
|
||||||
|
|
||||||
|
THREE.FilmShader = {
|
||||||
|
|
||||||
|
uniforms: {
|
||||||
|
|
||||||
|
"tDiffuse": { type: "t", value: null },
|
||||||
|
"time": { type: "f", value: 0.0 },
|
||||||
|
"nIntensity": { type: "f", value: 0.5 },
|
||||||
|
"sIntensity": { type: "f", value: 0.05 },
|
||||||
|
"sCount": { type: "f", value: 4096 },
|
||||||
|
"grayscale": { type: "i", value: 1 }
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
vertexShader: [
|
||||||
|
|
||||||
|
"varying vec2 vUv;",
|
||||||
|
|
||||||
|
"void main() {",
|
||||||
|
|
||||||
|
"vUv = uv;",
|
||||||
|
"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
|
||||||
|
|
||||||
|
"}"
|
||||||
|
|
||||||
|
].join("\n"),
|
||||||
|
|
||||||
|
fragmentShader: [
|
||||||
|
|
||||||
|
// control parameter
|
||||||
|
"uniform float time;",
|
||||||
|
|
||||||
|
"uniform bool grayscale;",
|
||||||
|
|
||||||
|
// noise effect intensity value (0 = no effect, 1 = full effect)
|
||||||
|
"uniform float nIntensity;",
|
||||||
|
|
||||||
|
// scanlines effect intensity value (0 = no effect, 1 = full effect)
|
||||||
|
"uniform float sIntensity;",
|
||||||
|
|
||||||
|
// scanlines effect count value (0 = no effect, 4096 = full effect)
|
||||||
|
"uniform float sCount;",
|
||||||
|
|
||||||
|
"uniform sampler2D tDiffuse;",
|
||||||
|
|
||||||
|
"varying vec2 vUv;",
|
||||||
|
|
||||||
|
"void main() {",
|
||||||
|
|
||||||
|
// sample the source
|
||||||
|
"vec4 cTextureScreen = texture2D( tDiffuse, vUv );",
|
||||||
|
|
||||||
|
// make some noise
|
||||||
|
"float x = vUv.x * vUv.y * time * 1000.0;",
|
||||||
|
"x = mod( x, 13.0 ) * mod( x, 123.0 );",
|
||||||
|
"float dx = mod( x, 0.01 );",
|
||||||
|
|
||||||
|
// add noise
|
||||||
|
"vec3 cResult = cTextureScreen.rgb + cTextureScreen.rgb * clamp( 0.1 + dx * 100.0, 0.0, 1.0 );",
|
||||||
|
|
||||||
|
// get us a sine and cosine
|
||||||
|
"vec2 sc = vec2( sin( vUv.y * sCount ), cos( vUv.y * sCount ) );",
|
||||||
|
|
||||||
|
// add scanlines
|
||||||
|
"cResult += cTextureScreen.rgb * vec3( sc.x, sc.y, sc.x ) * sIntensity;",
|
||||||
|
|
||||||
|
// interpolate between source and result by intensity
|
||||||
|
"cResult = cTextureScreen.rgb + clamp( nIntensity, 0.0,1.0 ) * ( cResult - cTextureScreen.rgb );",
|
||||||
|
|
||||||
|
// convert to grayscale if desired
|
||||||
|
"if( grayscale ) {",
|
||||||
|
|
||||||
|
"cResult = vec3( cResult.r * 0.3 + cResult.g * 0.59 + cResult.b * 0.11 );",
|
||||||
|
|
||||||
|
"}",
|
||||||
|
|
||||||
|
"gl_FragColor = vec4( cResult, cTextureScreen.a );",
|
||||||
|
|
||||||
|
"}"
|
||||||
|
|
||||||
|
].join("\n")
|
||||||
|
|
||||||
|
};
|
||||||
+86
@@ -0,0 +1,86 @@
|
|||||||
|
/**
|
||||||
|
* @author alteredq / http://alteredqualia.com/
|
||||||
|
*/
|
||||||
|
|
||||||
|
THREE.MaskPass = function ( scene, camera ) {
|
||||||
|
|
||||||
|
this.scene = scene;
|
||||||
|
this.camera = camera;
|
||||||
|
|
||||||
|
this.enabled = true;
|
||||||
|
this.clear = true;
|
||||||
|
this.needsSwap = false;
|
||||||
|
|
||||||
|
this.inverse = false;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
THREE.MaskPass.prototype = {
|
||||||
|
|
||||||
|
render: function ( renderer, writeBuffer, readBuffer, delta ) {
|
||||||
|
|
||||||
|
var context = renderer.context;
|
||||||
|
|
||||||
|
// don't update color or depth
|
||||||
|
|
||||||
|
context.colorMask( false, false, false, false );
|
||||||
|
context.depthMask( false );
|
||||||
|
|
||||||
|
// set up stencil
|
||||||
|
|
||||||
|
var writeValue, clearValue;
|
||||||
|
|
||||||
|
if ( this.inverse ) {
|
||||||
|
|
||||||
|
writeValue = 0;
|
||||||
|
clearValue = 1;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
writeValue = 1;
|
||||||
|
clearValue = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
context.enable( context.STENCIL_TEST );
|
||||||
|
context.stencilOp( context.REPLACE, context.REPLACE, context.REPLACE );
|
||||||
|
context.stencilFunc( context.ALWAYS, writeValue, 0xffffffff );
|
||||||
|
context.clearStencil( clearValue );
|
||||||
|
|
||||||
|
// draw into the stencil buffer
|
||||||
|
|
||||||
|
renderer.render( this.scene, this.camera, readBuffer, this.clear );
|
||||||
|
renderer.render( this.scene, this.camera, writeBuffer, this.clear );
|
||||||
|
|
||||||
|
// re-enable update of color and depth
|
||||||
|
|
||||||
|
context.colorMask( true, true, true, true );
|
||||||
|
context.depthMask( true );
|
||||||
|
|
||||||
|
// only render where stencil is set to 1
|
||||||
|
|
||||||
|
context.stencilFunc( context.EQUAL, 1, 0xffffffff ); // draw if == 1
|
||||||
|
context.stencilOp( context.KEEP, context.KEEP, context.KEEP );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
THREE.ClearMaskPass = function () {
|
||||||
|
|
||||||
|
this.enabled = true;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
THREE.ClearMaskPass.prototype = {
|
||||||
|
|
||||||
|
render: function ( renderer, writeBuffer, readBuffer, delta ) {
|
||||||
|
|
||||||
|
var context = renderer.context;
|
||||||
|
|
||||||
|
context.disable( context.STENCIL_TEST );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
/**
|
||||||
|
* @author alteredq / http://alteredqualia.com/
|
||||||
|
*/
|
||||||
|
|
||||||
|
THREE.RenderPass = function ( scene, camera, overrideMaterial, clearColor, clearAlpha ) {
|
||||||
|
|
||||||
|
this.scene = scene;
|
||||||
|
this.camera = camera;
|
||||||
|
|
||||||
|
this.overrideMaterial = overrideMaterial;
|
||||||
|
|
||||||
|
this.clearColor = clearColor;
|
||||||
|
this.clearAlpha = ( clearAlpha !== undefined ) ? clearAlpha : 1;
|
||||||
|
|
||||||
|
this.oldClearColor = new THREE.Color();
|
||||||
|
this.oldClearAlpha = 1;
|
||||||
|
|
||||||
|
this.enabled = true;
|
||||||
|
this.clear = true;
|
||||||
|
this.needsSwap = false;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
THREE.RenderPass.prototype = {
|
||||||
|
|
||||||
|
render: function ( renderer, writeBuffer, readBuffer, delta ) {
|
||||||
|
|
||||||
|
this.scene.overrideMaterial = this.overrideMaterial;
|
||||||
|
|
||||||
|
if ( this.clearColor ) {
|
||||||
|
|
||||||
|
this.oldClearColor.copy( renderer.getClearColor() );
|
||||||
|
this.oldClearAlpha = renderer.getClearAlpha();
|
||||||
|
|
||||||
|
renderer.setClearColor( this.clearColor, this.clearAlpha );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
renderer.render( this.scene, this.camera, readBuffer, this.clear );
|
||||||
|
|
||||||
|
if ( this.clearColor ) {
|
||||||
|
|
||||||
|
renderer.setClearColor( this.oldClearColor, this.oldClearAlpha );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
this.scene.overrideMaterial = null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
/**
|
||||||
|
* @author alteredq / http://alteredqualia.com/
|
||||||
|
*/
|
||||||
|
|
||||||
|
THREE.ShaderPass = function ( shader, textureID ) {
|
||||||
|
|
||||||
|
this.textureID = ( textureID !== undefined ) ? textureID : "tDiffuse";
|
||||||
|
|
||||||
|
this.uniforms = THREE.UniformsUtils.clone( shader.uniforms );
|
||||||
|
|
||||||
|
this.material = new THREE.ShaderMaterial( {
|
||||||
|
|
||||||
|
uniforms: this.uniforms,
|
||||||
|
vertexShader: shader.vertexShader,
|
||||||
|
fragmentShader: shader.fragmentShader
|
||||||
|
|
||||||
|
} );
|
||||||
|
|
||||||
|
this.renderToScreen = false;
|
||||||
|
|
||||||
|
this.enabled = true;
|
||||||
|
this.needsSwap = true;
|
||||||
|
this.clear = false;
|
||||||
|
|
||||||
|
|
||||||
|
this.camera = new THREE.OrthographicCamera( -1, 1, 1, -1, 0, 1 );
|
||||||
|
this.scene = new THREE.Scene();
|
||||||
|
|
||||||
|
this.quad = new THREE.Mesh( new THREE.PlaneGeometry( 2, 2 ), null );
|
||||||
|
this.scene.add( this.quad );
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
THREE.ShaderPass.prototype = {
|
||||||
|
|
||||||
|
render: function ( renderer, writeBuffer, readBuffer, delta ) {
|
||||||
|
|
||||||
|
if ( this.uniforms[ this.textureID ] ) {
|
||||||
|
|
||||||
|
this.uniforms[ this.textureID ].value = readBuffer;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
this.quad.material = this.material;
|
||||||
|
|
||||||
|
if ( this.renderToScreen ) {
|
||||||
|
|
||||||
|
renderer.render( this.scene, this.camera );
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
renderer.render( this.scene, this.camera, writeBuffer, this.clear );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Vendored
+6
@@ -0,0 +1,6 @@
|
|||||||
|
// stats.js - http://github.com/mrdoob/stats.js
|
||||||
|
var Stats=function(){var l=Date.now(),m=l,g=0,n=Infinity,o=0,h=0,p=Infinity,q=0,r=0,s=0,f=document.createElement("div");f.id="stats";f.addEventListener("mousedown",function(b){b.preventDefault();t(++s%2)},!1);f.style.cssText="width:80px;opacity:0.9;cursor:pointer";var a=document.createElement("div");a.id="fps";a.style.cssText="padding:0 0 3px 3px;text-align:left;background-color:#002";f.appendChild(a);var i=document.createElement("div");i.id="fpsText";i.style.cssText="color:#0ff;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px";
|
||||||
|
i.innerHTML="FPS";a.appendChild(i);var c=document.createElement("div");c.id="fpsGraph";c.style.cssText="position:relative;width:74px;height:30px;background-color:#0ff";for(a.appendChild(c);74>c.children.length;){var j=document.createElement("span");j.style.cssText="width:1px;height:30px;float:left;background-color:#113";c.appendChild(j)}var d=document.createElement("div");d.id="ms";d.style.cssText="padding:0 0 3px 3px;text-align:left;background-color:#020;display:none";f.appendChild(d);var k=document.createElement("div");
|
||||||
|
k.id="msText";k.style.cssText="color:#0f0;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px";k.innerHTML="MS";d.appendChild(k);var e=document.createElement("div");e.id="msGraph";e.style.cssText="position:relative;width:74px;height:30px;background-color:#0f0";for(d.appendChild(e);74>e.children.length;)j=document.createElement("span"),j.style.cssText="width:1px;height:30px;float:left;background-color:#131",e.appendChild(j);var t=function(b){s=b;switch(s){case 0:a.style.display=
|
||||||
|
"block";d.style.display="none";break;case 1:a.style.display="none",d.style.display="block"}};return{REVISION:11,domElement:f,setMode:t,begin:function(){l=Date.now()},end:function(){var b=Date.now();g=b-l;n=Math.min(n,g);o=Math.max(o,g);k.textContent=g+" MS ("+n+"-"+o+")";var a=Math.min(30,30-30*(g/200));e.appendChild(e.firstChild).style.height=a+"px";r++;b>m+1E3&&(h=Math.round(1E3*r/(b-m)),p=Math.min(p,h),q=Math.max(q,h),i.textContent=h+" FPS ("+p+"-"+q+")",a=Math.min(30,30-30*(h/100)),c.appendChild(c.firstChild).style.height=
|
||||||
|
a+"px",m=b,r=0);return b},update:function(){l=this.end()}}};
|
||||||
Vendored
+722
File diff suppressed because one or more lines are too long
@@ -0,0 +1,642 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<!-- saved from url=(0086)http://mrdoob.github.io/three.js/examples/webgl_geometry_text.html#FF000A0010#three.js -->
|
||||||
|
<html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||||
|
<title>three.js webgl - geometry - text</title>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: Monospace;
|
||||||
|
background-color: #000;
|
||||||
|
color: #fff;
|
||||||
|
margin: 0px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
#info {
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
z-index: 100;
|
||||||
|
display:block;
|
||||||
|
}
|
||||||
|
#info a, .button { color: #f00; font-weight: bold; text-decoration: underline; cursor: pointer }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script src="./webglgeometrytext_files/three.min.js"></script>
|
||||||
|
|
||||||
|
<script src="./webglgeometrytext_files/ConvolutionShader.js"></script>
|
||||||
|
<script src="./webglgeometrytext_files/CopyShader.js"></script>
|
||||||
|
<script src="./webglgeometrytext_files/FilmShader.js"></script>
|
||||||
|
<script src="./webglgeometrytext_files/FXAAShader.js"></script>
|
||||||
|
|
||||||
|
<script src="./webglgeometrytext_files/EffectComposer.js"></script>
|
||||||
|
<script src="./webglgeometrytext_files/RenderPass.js"></script>
|
||||||
|
<script src="./webglgeometrytext_files/ShaderPass.js"></script>
|
||||||
|
<script src="./webglgeometrytext_files/MaskPass.js"></script>
|
||||||
|
<script src="./webglgeometrytext_files/BloomPass.js"></script>
|
||||||
|
<script src="./webglgeometrytext_files/FilmPass.js"></script>
|
||||||
|
|
||||||
|
<script src="./webglgeometrytext_files/Detector.js"></script>
|
||||||
|
<script src="./webglgeometrytext_files/stats.min.js"></script>
|
||||||
|
|
||||||
|
<!-- load the font files -->
|
||||||
|
|
||||||
|
<script src="./webglgeometrytext_files/gentilis_bold.typeface.js"></script>
|
||||||
|
<script src="./webglgeometrytext_files/gentilis_regular.typeface.js"></script>
|
||||||
|
<script src="./webglgeometrytext_files/optimer_bold.typeface.js"></script>
|
||||||
|
<script src="./webglgeometrytext_files/optimer_regular.typeface.js"></script>
|
||||||
|
<script src="./webglgeometrytext_files/helvetiker_bold.typeface.js"></script>
|
||||||
|
<script src="./webglgeometrytext_files/helvetiker_regular.typeface.js"></script>
|
||||||
|
<script src="./webglgeometrytext_files/droid_sans_regular.typeface.js"></script>
|
||||||
|
<script src="./webglgeometrytext_files/droid_sans_bold.typeface.js"></script>
|
||||||
|
<script src="./webglgeometrytext_files/droid_serif_regular.typeface.js"></script>
|
||||||
|
<script src="./webglgeometrytext_files/droid_serif_bold.typeface.js"></script>
|
||||||
|
|
||||||
|
<!-- todo async loader for fonts -->
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
|
||||||
|
|
||||||
|
var container, stats, permalink, hex, color;
|
||||||
|
|
||||||
|
var camera, cameraTarget, scene, renderer;
|
||||||
|
|
||||||
|
var composer;
|
||||||
|
var effectFXAA;
|
||||||
|
|
||||||
|
var group, textMesh1, textMesh2, textGeo, material;
|
||||||
|
|
||||||
|
var firstLetter = true;
|
||||||
|
|
||||||
|
var text = "three.js",
|
||||||
|
|
||||||
|
height = 20,
|
||||||
|
size = 40,
|
||||||
|
hover = 40,
|
||||||
|
|
||||||
|
curveSegments = 4,
|
||||||
|
|
||||||
|
bevelThickness = 2,
|
||||||
|
bevelSize = 1.5,
|
||||||
|
bevelSegments = 3,
|
||||||
|
bevelEnabled = true,
|
||||||
|
|
||||||
|
font = "droid sans", // helvetiker, optimer, gentilis, droid sans, droid serif
|
||||||
|
weight = "bold", // normal bold
|
||||||
|
style = "normal"; // normal italic
|
||||||
|
|
||||||
|
var mirror = true;
|
||||||
|
|
||||||
|
var fontMap = {
|
||||||
|
|
||||||
|
"helvetiker": 0,
|
||||||
|
"optimer": 1,
|
||||||
|
"gentilis": 2,
|
||||||
|
"droid sans": 3,
|
||||||
|
"droid serif": 4
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
var weightMap = {
|
||||||
|
|
||||||
|
"normal": 0,
|
||||||
|
"bold": 1
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
var reverseFontMap = {};
|
||||||
|
var reverseWeightMap = {};
|
||||||
|
|
||||||
|
for ( var i in fontMap ) reverseFontMap[ fontMap[i] ] = i;
|
||||||
|
for ( var i in weightMap ) reverseWeightMap[ weightMap[i] ] = i;
|
||||||
|
|
||||||
|
var targetRotation = 0;
|
||||||
|
var targetRotationOnMouseDown = 0;
|
||||||
|
|
||||||
|
var mouseX = 0;
|
||||||
|
var mouseXOnMouseDown = 0;
|
||||||
|
|
||||||
|
var windowHalfX = window.innerWidth / 2;
|
||||||
|
var windowHalfY = window.innerHeight / 2;
|
||||||
|
|
||||||
|
var postprocessing = { enabled : true };
|
||||||
|
var glow = 2.9;
|
||||||
|
|
||||||
|
init();
|
||||||
|
animate();
|
||||||
|
|
||||||
|
function capitalize( txt ) {
|
||||||
|
return txt.substring( 0, 1 ).toUpperCase() + txt.substring( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
function decimalToHex( d ) {
|
||||||
|
|
||||||
|
var hex = Number( d ).toString( 16 );
|
||||||
|
hex = "000000".substr( 0, 6 - hex.length ) + hex;
|
||||||
|
return hex.toUpperCase();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
|
||||||
|
container = document.createElement( 'div' );
|
||||||
|
document.body.appendChild( container );
|
||||||
|
|
||||||
|
permalink = document.getElementById( "permalink" );
|
||||||
|
|
||||||
|
// CAMERA
|
||||||
|
|
||||||
|
camera = new THREE.PerspectiveCamera( 30, window.innerWidth / window.innerHeight, 1, 1500 );
|
||||||
|
camera.position.set( 0, 400, 700 );
|
||||||
|
|
||||||
|
cameraTarget = new THREE.Vector3( 0, 150, 0 );
|
||||||
|
|
||||||
|
// SCENE
|
||||||
|
|
||||||
|
scene = new THREE.Scene();
|
||||||
|
scene.fog = new THREE.Fog( 0x000000, 250, 1400 );
|
||||||
|
|
||||||
|
// LIGHTS
|
||||||
|
|
||||||
|
var dirLight = new THREE.DirectionalLight( 0xffffff, 0.125 );
|
||||||
|
dirLight.position.set( 0, 0, 1 ).normalize();
|
||||||
|
scene.add( dirLight );
|
||||||
|
|
||||||
|
var pointLight = new THREE.PointLight( 0xffffff, 1.5 );
|
||||||
|
pointLight.position.set( 0, 100, 90 );
|
||||||
|
scene.add( pointLight );
|
||||||
|
|
||||||
|
//text = capitalize( font ) + " " + capitalize( weight );
|
||||||
|
//text = "abcdefghijklmnopqrstuvwxyz0123456789";
|
||||||
|
text = "The Glitch in the Game";
|
||||||
|
|
||||||
|
// Get text from hash
|
||||||
|
|
||||||
|
var hash = document.location.hash.substr( 1 );
|
||||||
|
|
||||||
|
if ( hash.length !== 0 ) {
|
||||||
|
|
||||||
|
var colorhash = hash.substring( 0, 6 );
|
||||||
|
var fonthash = hash.substring( 6, 7 );
|
||||||
|
var weighthash = hash.substring( 7, 8 );
|
||||||
|
var pphash = hash.substring( 8, 9 );
|
||||||
|
var bevelhash = hash.substring( 9, 10 );
|
||||||
|
var texthash = hash.substring( 10 );
|
||||||
|
|
||||||
|
hex = colorhash;
|
||||||
|
pointLight.color.setHex( parseInt( colorhash, 16 ) );
|
||||||
|
|
||||||
|
//font = reverseFontMap[ parseInt( fonthash ) ];
|
||||||
|
//font = 5;
|
||||||
|
weight = reverseWeightMap[ parseInt( weighthash ) ];
|
||||||
|
|
||||||
|
postprocessing.enabled = parseInt( pphash );
|
||||||
|
bevelEnabled = parseInt( bevelhash );
|
||||||
|
|
||||||
|
text = decodeURI( texthash );
|
||||||
|
|
||||||
|
updatePermalink();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
pointLight.color.setHSL(0.6236155861988664, 1, 0.5 );
|
||||||
|
hex = decimalToHex( pointLight.color.getHex() );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
material = new THREE.MeshFaceMaterial( [
|
||||||
|
new THREE.MeshPhongMaterial( { color: 0xffffff, shading: THREE.FlatShading } ), // front
|
||||||
|
new THREE.MeshPhongMaterial( { color: 0xffffff, shading: THREE.SmoothShading } ) // side
|
||||||
|
] );
|
||||||
|
|
||||||
|
group = new THREE.Object3D();
|
||||||
|
group.position.y = 100;
|
||||||
|
|
||||||
|
scene.add( group );
|
||||||
|
|
||||||
|
createText();
|
||||||
|
|
||||||
|
var plane = new THREE.Mesh( new THREE.PlaneGeometry( 10000, 10000 ), new THREE.MeshBasicMaterial( { color: 0xffffff, opacity: 0.5, transparent: true } ) );
|
||||||
|
plane.position.y = 100;
|
||||||
|
plane.rotation.x = - Math.PI / 2;
|
||||||
|
scene.add( plane );
|
||||||
|
|
||||||
|
// RENDERER
|
||||||
|
|
||||||
|
renderer = new THREE.WebGLRenderer( { antialias: true } );
|
||||||
|
renderer.setSize( window.innerWidth, window.innerHeight );
|
||||||
|
|
||||||
|
renderer.setClearColor( scene.fog.color, 1 );
|
||||||
|
|
||||||
|
container.appendChild( renderer.domElement );
|
||||||
|
|
||||||
|
// STATS
|
||||||
|
|
||||||
|
stats = new Stats();
|
||||||
|
stats.domElement.style.position = 'absolute';
|
||||||
|
stats.domElement.style.top = '0px';
|
||||||
|
//container.appendChild( stats.domElement );
|
||||||
|
|
||||||
|
// EVENTS
|
||||||
|
|
||||||
|
/*document.addEventListener( 'mousedown', onDocumentMouseDown, false );
|
||||||
|
document.addEventListener( 'touchstart', onDocumentTouchStart, false );
|
||||||
|
document.addEventListener( 'touchmove', onDocumentTouchMove, false );
|
||||||
|
document.addEventListener( 'keypress', onDocumentKeyPress, false );
|
||||||
|
document.addEventListener( 'keydown', onDocumentKeyDown, false );
|
||||||
|
|
||||||
|
document.getElementById( "color" ).addEventListener( 'click', function() {
|
||||||
|
|
||||||
|
pointLight.color.setHSL( Math.random(), 1, 0.5 );
|
||||||
|
hex = decimalToHex( pointLight.color.getHex() );
|
||||||
|
|
||||||
|
updatePermalink();
|
||||||
|
|
||||||
|
}, false );
|
||||||
|
|
||||||
|
document.getElementById( "font" ).addEventListener( 'click', function() {
|
||||||
|
|
||||||
|
if ( font == "helvetiker" ) {
|
||||||
|
|
||||||
|
font = "optimer";
|
||||||
|
|
||||||
|
} else if ( font == "optimer" ) {
|
||||||
|
|
||||||
|
font = "gentilis";
|
||||||
|
|
||||||
|
} else if ( font == "gentilis" ) {
|
||||||
|
|
||||||
|
font = "droid sans";
|
||||||
|
|
||||||
|
} else if ( font == "droid sans" ) {
|
||||||
|
|
||||||
|
font = "droid serif";
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
font = "helvetiker";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
refreshText();
|
||||||
|
|
||||||
|
}, false );
|
||||||
|
|
||||||
|
document.getElementById( "weight" ).addEventListener( 'click', function() {
|
||||||
|
|
||||||
|
if ( weight == "bold" ) {
|
||||||
|
|
||||||
|
weight = "normal";
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
weight = "bold";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
refreshText();
|
||||||
|
|
||||||
|
}, false );
|
||||||
|
|
||||||
|
document.getElementById( "bevel" ).addEventListener( 'click', function() {
|
||||||
|
|
||||||
|
bevelEnabled = !bevelEnabled;
|
||||||
|
|
||||||
|
refreshText();
|
||||||
|
|
||||||
|
}, false );
|
||||||
|
|
||||||
|
document.getElementById( "postprocessing" ).addEventListener( 'click', function() {
|
||||||
|
|
||||||
|
postprocessing.enabled = !postprocessing.enabled;
|
||||||
|
updatePermalink();
|
||||||
|
|
||||||
|
}, false );*/
|
||||||
|
|
||||||
|
|
||||||
|
// POSTPROCESSING
|
||||||
|
|
||||||
|
renderer.autoClear = false;
|
||||||
|
|
||||||
|
var renderModel = new THREE.RenderPass( scene, camera );
|
||||||
|
var effectBloom = new THREE.BloomPass( 0.25 );
|
||||||
|
var effectFilm = new THREE.FilmPass( 0.5, 0.125, 2048, false );
|
||||||
|
|
||||||
|
|
||||||
|
//effectFXAA = new THREE.ShaderPass( THREE.FXAAShader );
|
||||||
|
//badTVPass = new THREE.ShaderPass( THREE.BadTVShader );
|
||||||
|
|
||||||
|
var width = window.innerWidth || 2;
|
||||||
|
var height = window.innerHeight || 2;
|
||||||
|
|
||||||
|
//effectFXAA.uniforms[ 'resolution' ].value.set( 1 / width, 1 / height );
|
||||||
|
|
||||||
|
effectFilm.renderToScreen = true;
|
||||||
|
|
||||||
|
composer = new THREE.EffectComposer( renderer );
|
||||||
|
|
||||||
|
composer.addPass( renderModel );
|
||||||
|
//composer.addPass( badTVPass );
|
||||||
|
composer.addPass( effectBloom );
|
||||||
|
composer.addPass( effectFilm );
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
window.addEventListener( 'resize', onWindowResize, false );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function onWindowResize() {
|
||||||
|
|
||||||
|
windowHalfX = window.innerWidth / 2;
|
||||||
|
windowHalfY = window.innerHeight / 2;
|
||||||
|
|
||||||
|
camera.aspect = window.innerWidth / window.innerHeight;
|
||||||
|
camera.updateProjectionMatrix();
|
||||||
|
|
||||||
|
renderer.setSize( window.innerWidth, window.innerHeight );
|
||||||
|
|
||||||
|
composer.reset();
|
||||||
|
|
||||||
|
effectFXAA.uniforms[ 'resolution' ].value.set( 1 / window.innerWidth, 1 / window.innerHeight );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
function boolToNum( b ) {
|
||||||
|
|
||||||
|
return b ? 1 : 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function updatePermalink() {
|
||||||
|
|
||||||
|
var link = hex + fontMap[ font ] + weightMap[ weight ] + boolToNum( postprocessing.enabled ) + boolToNum( bevelEnabled ) + "#" + encodeURI( text );
|
||||||
|
|
||||||
|
permalink.href = "#" + link;
|
||||||
|
window.location.hash = link;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function onDocumentKeyDown( event ) {
|
||||||
|
|
||||||
|
if ( firstLetter ) {
|
||||||
|
|
||||||
|
firstLetter = false;
|
||||||
|
text = "";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var keyCode = event.keyCode;
|
||||||
|
|
||||||
|
// backspace
|
||||||
|
|
||||||
|
if ( keyCode == 8 ) {
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
text = text.substring( 0, text.length - 1 );
|
||||||
|
refreshText();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function onDocumentKeyPress( event ) {
|
||||||
|
|
||||||
|
var keyCode = event.which;
|
||||||
|
|
||||||
|
// backspace
|
||||||
|
|
||||||
|
if ( keyCode == 8 ) {
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
var ch = String.fromCharCode( keyCode );
|
||||||
|
text += ch;
|
||||||
|
|
||||||
|
refreshText();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function createText() {
|
||||||
|
|
||||||
|
textGeo = new THREE.TextGeometry( text, {
|
||||||
|
|
||||||
|
size: size,
|
||||||
|
height: height,
|
||||||
|
curveSegments: curveSegments,
|
||||||
|
|
||||||
|
font: font,
|
||||||
|
weight: weight,
|
||||||
|
style: style,
|
||||||
|
|
||||||
|
bevelThickness: bevelThickness,
|
||||||
|
bevelSize: bevelSize,
|
||||||
|
bevelEnabled: bevelEnabled,
|
||||||
|
|
||||||
|
material: 0,
|
||||||
|
extrudeMaterial: 1
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
textGeo.computeBoundingBox();
|
||||||
|
textGeo.computeVertexNormals();
|
||||||
|
|
||||||
|
// "fix" side normals by removing z-component of normals for side faces
|
||||||
|
// (this doesn't work well for beveled geometry as then we lose nice curvature around z-axis)
|
||||||
|
|
||||||
|
if ( ! bevelEnabled ) {
|
||||||
|
|
||||||
|
var triangleAreaHeuristics = 0.1 * ( height * size );
|
||||||
|
|
||||||
|
for ( var i = 0; i < textGeo.faces.length; i ++ ) {
|
||||||
|
|
||||||
|
var face = textGeo.faces[ i ];
|
||||||
|
|
||||||
|
if ( face.materialIndex == 1 ) {
|
||||||
|
|
||||||
|
for ( var j = 0; j < face.vertexNormals.length; j ++ ) {
|
||||||
|
|
||||||
|
face.vertexNormals[ j ].z = 0;
|
||||||
|
face.vertexNormals[ j ].normalize();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var va = textGeo.vertices[ face.a ];
|
||||||
|
var vb = textGeo.vertices[ face.b ];
|
||||||
|
var vc = textGeo.vertices[ face.c ];
|
||||||
|
|
||||||
|
var s = THREE.GeometryUtils.triangleArea( va, vb, vc );
|
||||||
|
|
||||||
|
if ( s > triangleAreaHeuristics ) {
|
||||||
|
|
||||||
|
for ( var j = 0; j < face.vertexNormals.length; j ++ ) {
|
||||||
|
|
||||||
|
face.vertexNormals[ j ].copy( face.normal );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var centerOffset = -0.5 * ( textGeo.boundingBox.max.x - textGeo.boundingBox.min.x );
|
||||||
|
|
||||||
|
textMesh1 = new THREE.Mesh( textGeo, material );
|
||||||
|
|
||||||
|
textMesh1.position.x = centerOffset;
|
||||||
|
textMesh1.position.y = hover;
|
||||||
|
textMesh1.position.z = 0;
|
||||||
|
|
||||||
|
textMesh1.rotation.x = 0;
|
||||||
|
textMesh1.rotation.y = Math.PI * 2;
|
||||||
|
|
||||||
|
group.add( textMesh1 );
|
||||||
|
|
||||||
|
if ( mirror ) {
|
||||||
|
|
||||||
|
textMesh2 = new THREE.Mesh( textGeo, material );
|
||||||
|
|
||||||
|
textMesh2.position.x = centerOffset;
|
||||||
|
textMesh2.position.y = -hover;
|
||||||
|
textMesh2.position.z = height;
|
||||||
|
|
||||||
|
textMesh2.rotation.x = Math.PI;
|
||||||
|
textMesh2.rotation.y = Math.PI * 2;
|
||||||
|
|
||||||
|
group.add( textMesh2 );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function refreshText() {
|
||||||
|
|
||||||
|
updatePermalink();
|
||||||
|
|
||||||
|
group.remove( textMesh1 );
|
||||||
|
if ( mirror ) group.remove( textMesh2 );
|
||||||
|
|
||||||
|
if ( !text ) return;
|
||||||
|
|
||||||
|
createText();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function onDocumentMouseDown( event ) {
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
|
||||||
|
document.addEventListener( 'mouseup', onDocumentMouseUp, false );
|
||||||
|
document.addEventListener( 'mouseout', onDocumentMouseOut, false );
|
||||||
|
|
||||||
|
mouseXOnMouseDown = event.clientX - windowHalfX;
|
||||||
|
targetRotationOnMouseDown = targetRotation;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function onDocumentMouseMove( event ) {
|
||||||
|
|
||||||
|
mouseX = event.clientX - windowHalfX;
|
||||||
|
|
||||||
|
targetRotation = targetRotationOnMouseDown + ( mouseX - mouseXOnMouseDown ) * 0.02;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function onDocumentMouseUp( event ) {
|
||||||
|
|
||||||
|
document.removeEventListener( 'mousemove', onDocumentMouseMove, false );
|
||||||
|
document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
|
||||||
|
document.removeEventListener( 'mouseout', onDocumentMouseOut, false );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function onDocumentMouseOut( event ) {
|
||||||
|
|
||||||
|
document.removeEventListener( 'mousemove', onDocumentMouseMove, false );
|
||||||
|
document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
|
||||||
|
document.removeEventListener( 'mouseout', onDocumentMouseOut, false );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function onDocumentTouchStart( event ) {
|
||||||
|
|
||||||
|
if ( event.touches.length == 1 ) {
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
mouseXOnMouseDown = event.touches[ 0 ].pageX - windowHalfX;
|
||||||
|
targetRotationOnMouseDown = targetRotation;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function onDocumentTouchMove( event ) {
|
||||||
|
|
||||||
|
if ( event.touches.length == 1 ) {
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
mouseX = event.touches[ 0 ].pageX - windowHalfX;
|
||||||
|
targetRotation = targetRotationOnMouseDown + ( mouseX - mouseXOnMouseDown ) * 0.05;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
function animate() {
|
||||||
|
|
||||||
|
requestAnimationFrame( animate );
|
||||||
|
|
||||||
|
render();
|
||||||
|
stats.update();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function render() {
|
||||||
|
|
||||||
|
group.rotation.y += ( targetRotation - group.rotation.y ) * 0.05;
|
||||||
|
|
||||||
|
camera.lookAt( cameraTarget );
|
||||||
|
|
||||||
|
renderer.clear();
|
||||||
|
|
||||||
|
if ( postprocessing.enabled ) {
|
||||||
|
|
||||||
|
composer.render( 0.05 );
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
renderer.render( scene, camera );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</script><div><canvas width="1756" height="1524" style="width: 878px; height: 762px; position: fixed; top: 0; left: 0; z-index: -1"></canvas></div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</body></html>
|
||||||
Reference in New Issue
Block a user