├── .gitignore ├── .jshintrc ├── LICENSE ├── README.md ├── assets ├── build │ ├── bundle.js │ └── bundle.js.map ├── images │ ├── bokeh.png │ ├── cloud1024.png │ ├── earth_atmos_2048.jpg │ ├── gene.sys │ │ ├── gene.sys_01.png │ │ ├── gene.sys_02.png │ │ ├── gene.sys_03.png │ │ ├── gene.sys_04.png │ │ ├── gene.sys_05.png │ │ ├── gene.sys_06.png │ │ ├── gene.sys_07.png │ │ └── gene.sys_08.png │ ├── nasa-goddard.png │ ├── sinegravitycloud.png │ ├── sound-mute-hover.png │ ├── sound-mute.png │ ├── sound-unmute-hover.png │ └── sound-unmute.png ├── shaders │ ├── shaderplay.example.frag │ ├── shaderplay.example.vert │ ├── sinegravitycloud.frag │ └── sinegravitycloud.vert └── vendor │ ├── jquery-2.1.1.min.js │ ├── jquery-2.1.1.min.map │ ├── three.js │ ├── three.min.js │ ├── underscore-min.js │ └── underscore-min.map ├── base.css ├── index.hbs ├── index.html ├── js ├── components │ ├── Info.js │ ├── Stars.js │ ├── ambiance │ │ ├── Clouds │ │ │ ├── clouds.frag │ │ │ ├── clouds.vert │ │ │ └── index.js │ │ ├── Sky │ │ │ ├── index.js │ │ │ ├── sky-old.frag │ │ │ ├── sky.frag │ │ │ └── sky.vert │ │ ├── blobs │ │ │ ├── blobs.frag │ │ │ ├── blobs.js │ │ │ └── blobs.vert │ │ ├── light-beam │ │ │ ├── light-beam.frag │ │ │ ├── light-beam.js │ │ │ └── light-beam.vert │ │ └── particles │ │ │ ├── particles.frag │ │ │ ├── particles.js │ │ │ └── particles.vert │ ├── animator.js │ ├── cameras │ │ ├── Camera.js │ │ ├── ConstantMove.js │ │ ├── Controls.js │ │ ├── Orientation.js │ │ ├── RestrictedCamera.js │ │ ├── RotateAroundOrigin.js │ │ ├── Swivel.js │ │ └── Trackball.js │ ├── fbo-positioning │ │ ├── fbo-position.shader │ │ ├── fbo-render.frag │ │ ├── fbo-render.vert │ │ └── fbo.js │ ├── hids │ │ └── mouse-tracker.js │ ├── lights │ │ └── TrackCameraLights.js │ ├── models │ │ ├── tree.js │ │ └── tree.json │ ├── sound │ │ ├── Music.js │ │ └── SoundGenerator.js │ └── utils │ │ ├── Stats.js │ │ └── drag-scroll.js ├── core │ ├── manifestToPoem.js │ ├── poem.js │ ├── routing.js │ └── ui.js ├── demos │ ├── Earth.js │ ├── EndlessTerrain │ │ ├── credits.js │ │ ├── endless.frag │ │ ├── endless.js │ │ ├── endless.vert │ │ └── keyframes.js │ ├── Grid.js │ ├── MeshGroupBoxDemo │ │ ├── MeshGroup.js │ │ ├── index.js │ │ ├── shader.frag │ │ └── shader.vert │ ├── TexturePositionalMatrices │ │ ├── index.js │ │ ├── shader.frag │ │ └── shader.vert │ ├── UniformPositionalMatrices │ │ ├── index.js │ │ ├── shader.frag │ │ └── shader.vert │ ├── sine-gravity-cloud │ │ ├── sine.frag │ │ ├── sine.js │ │ └── sine.vert │ ├── tetrahedra.js │ └── wire-terrain │ │ ├── credits.js │ │ ├── keyframes.js │ │ ├── terrain.frag │ │ ├── terrain.js │ │ └── terrain.vert ├── index.js ├── postprocessing │ ├── BloomPass.js │ ├── BokehPass.js │ ├── ChromaticAberration │ │ ├── chromatic.frag │ │ ├── chromatic.vert │ │ └── index.js │ ├── DotScreenPass.js │ ├── EffectComposer.js │ ├── FilmPass.js │ ├── GlitchPass.js │ ├── MaskPass.js │ ├── RenderPass.js │ ├── SSAOShader.js │ ├── SavePass.js │ ├── ShaderPass.js │ ├── TexturePass.js │ ├── index.js │ └── playground │ │ ├── playground.frag │ │ ├── playground.js │ │ └── playground.vert ├── renderers │ ├── basic-renderer.js │ ├── cardboard-renderer.js │ ├── effects-renderer.js │ ├── postprocess-renderer.js │ └── utils │ │ ├── create-renderer.js │ │ ├── fade-out-ui.js │ │ ├── resize-handler.js │ │ └── resize-renderer-fn.js ├── shaders │ ├── BasicShader.js │ ├── BleachBypassShader.js │ ├── BlendShader.js │ ├── BokehShader.js │ ├── BokehShader2.js │ ├── BrightnessContrastShader.js │ ├── ChromaticAberration.js │ ├── ColorCorrectionShader.js │ ├── ColorifyShader.js │ ├── ConvolutionShader.js │ ├── CopyShader.js │ ├── DOFMipMapShader.js │ ├── DigitalGlitch.js │ ├── DotScreenShader.js │ ├── EdgeShader.js │ ├── EdgeShader2.js │ ├── FXAAShader.js │ ├── FilmShader.js │ ├── FocusShader.js │ ├── FresnelShader.js │ ├── HorizontalBlurShader.js │ ├── HorizontalTiltShiftShader.js │ ├── HueSaturationShader.js │ ├── KaleidoShader.js │ ├── LuminosityShader.js │ ├── MirrorShader.js │ ├── NormalMapShader.js │ ├── OceanShaders.js │ ├── RGBShiftShader.js │ ├── SSAOShader.js │ ├── SepiaShader.js │ ├── TechnicolorShader.js │ ├── TestShader.js │ ├── TriangleBlurShader.js │ ├── UnpackDepthRGBAShader.js │ ├── VerticalBlurShader.js │ ├── VerticalTiltShiftShader.js │ └── VignetteShader.js ├── sound │ ├── Music.js │ ├── SoundGenerator.js │ └── mute.js ├── utils │ ├── Clock.js │ ├── ClosedSplineCurve3.js │ ├── EventDispatcher.js │ ├── Stats.js │ ├── ThreeConsole.js │ ├── WebGLDetector.js │ ├── calculateSquaredTextureWidth.js │ ├── destroyMesh.js │ ├── duplicate-buffer-geometry.js │ ├── gpu-processor │ │ ├── README.md │ │ ├── copy-texture.js │ │ └── gpu-processor.js │ ├── loadImage.js │ ├── loadText.js │ ├── loadTexture.js │ ├── random.js │ ├── selectors.js │ ├── simplex2.js │ └── simplex3.js └── vendor │ ├── AssimpJSONLoader.js │ ├── DeviceOrientationControls.js │ ├── OrbitControls.js │ ├── Stats.js │ ├── StereoEffect.js │ ├── TrackballControls.js │ └── WebGLDetector.js ├── manifests ├── blobs.js ├── carbonDioxideEarth.js ├── cubic.js ├── endlessTerrain.js ├── fbo-positioning.js ├── index.js ├── light-beams.js ├── meshGroupBoxDemo.js ├── postprocessing.js ├── sineGravityCloud.js ├── tetrahedra.js ├── texturePositionalMatrices.js ├── uniformPositionalMatrices.js └── vr.js ├── menu.html └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | assets/video/* 2 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "globals": { 3 | "THREE": true, 4 | "_": true, 5 | "poem": true, 6 | "LevelLoader": true, 7 | "webkitAudioContext": true, 8 | "AudioContext": true, 9 | "_gaq": true 10 | }, 11 | "laxcomma": true, 12 | "node": true, 13 | "devel": true, 14 | "asi": true, 15 | "jquery": true, 16 | "sub": true, 17 | "browser": true, 18 | "debug": true, //allow debug statements 19 | "eqeqeq": true, //must use === 20 | "latedef": "nofunc", //variables must be defined before use 21 | "undef": true //all variables must be declared 22 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Greg Tatum 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Three.js Sandbox 2 | 3 | http://gregtatum.com/sandbox/ 4 | 5 | A sandbox to play around with ideas. It uses [poem-manifests](https://www.npmjs.com/package/poem-manifests), [poem-loop](https://www.npmjs.com/package/poem-loop), and [poem-menu](https://www.npmjs.com/package/poem-menu) to quickly write re-usable 3d code. See the respective module documentation pages to see how the manifests and menus work. 6 | 7 | The central poem object is the application graph. If you're looking to get oriented in the code base, the manifests are the individual experiments. They then load in components that get saved to the central poem object. 8 | 9 | ## Running 10 | 11 | Make sure npm is install, then in the directory run `npm install` to get the dependencies. 12 | 13 | To run and prototype with live-reload: 14 | 15 | npm start 16 | 17 | To build: 18 | 19 | npm run build 20 | 21 | Project copyright (c) 2014 Greg Tatum under The MIT License (MIT) 22 | -------------------------------------------------------------------------------- /assets/images/bokeh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregtatum/sandbox/b5279bac41d2af3c681029b2aa544987db992102/assets/images/bokeh.png -------------------------------------------------------------------------------- /assets/images/cloud1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregtatum/sandbox/b5279bac41d2af3c681029b2aa544987db992102/assets/images/cloud1024.png -------------------------------------------------------------------------------- /assets/images/earth_atmos_2048.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregtatum/sandbox/b5279bac41d2af3c681029b2aa544987db992102/assets/images/earth_atmos_2048.jpg -------------------------------------------------------------------------------- /assets/images/gene.sys/gene.sys_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregtatum/sandbox/b5279bac41d2af3c681029b2aa544987db992102/assets/images/gene.sys/gene.sys_01.png -------------------------------------------------------------------------------- /assets/images/gene.sys/gene.sys_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregtatum/sandbox/b5279bac41d2af3c681029b2aa544987db992102/assets/images/gene.sys/gene.sys_02.png -------------------------------------------------------------------------------- /assets/images/gene.sys/gene.sys_03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregtatum/sandbox/b5279bac41d2af3c681029b2aa544987db992102/assets/images/gene.sys/gene.sys_03.png -------------------------------------------------------------------------------- /assets/images/gene.sys/gene.sys_04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregtatum/sandbox/b5279bac41d2af3c681029b2aa544987db992102/assets/images/gene.sys/gene.sys_04.png -------------------------------------------------------------------------------- /assets/images/gene.sys/gene.sys_05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregtatum/sandbox/b5279bac41d2af3c681029b2aa544987db992102/assets/images/gene.sys/gene.sys_05.png -------------------------------------------------------------------------------- /assets/images/gene.sys/gene.sys_06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregtatum/sandbox/b5279bac41d2af3c681029b2aa544987db992102/assets/images/gene.sys/gene.sys_06.png -------------------------------------------------------------------------------- /assets/images/gene.sys/gene.sys_07.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregtatum/sandbox/b5279bac41d2af3c681029b2aa544987db992102/assets/images/gene.sys/gene.sys_07.png -------------------------------------------------------------------------------- /assets/images/gene.sys/gene.sys_08.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregtatum/sandbox/b5279bac41d2af3c681029b2aa544987db992102/assets/images/gene.sys/gene.sys_08.png -------------------------------------------------------------------------------- /assets/images/nasa-goddard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregtatum/sandbox/b5279bac41d2af3c681029b2aa544987db992102/assets/images/nasa-goddard.png -------------------------------------------------------------------------------- /assets/images/sinegravitycloud.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregtatum/sandbox/b5279bac41d2af3c681029b2aa544987db992102/assets/images/sinegravitycloud.png -------------------------------------------------------------------------------- /assets/images/sound-mute-hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregtatum/sandbox/b5279bac41d2af3c681029b2aa544987db992102/assets/images/sound-mute-hover.png -------------------------------------------------------------------------------- /assets/images/sound-mute.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregtatum/sandbox/b5279bac41d2af3c681029b2aa544987db992102/assets/images/sound-mute.png -------------------------------------------------------------------------------- /assets/images/sound-unmute-hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregtatum/sandbox/b5279bac41d2af3c681029b2aa544987db992102/assets/images/sound-unmute-hover.png -------------------------------------------------------------------------------- /assets/images/sound-unmute.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregtatum/sandbox/b5279bac41d2af3c681029b2aa544987db992102/assets/images/sound-unmute.png -------------------------------------------------------------------------------- /assets/shaders/shaderplay.example.frag: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | precision highp int; 3 | 4 | 5 | #define MAX_DIR_LIGHTS 0 6 | #define MAX_POINT_LIGHTS 0 7 | #define MAX_SPOT_LIGHTS 0 8 | #define MAX_HEMI_LIGHTS 0 9 | #define MAX_SHADOWS 0 10 | 11 | uniform mat4 viewMatrix; 12 | uniform vec3 cameraPosition; 13 | uniform vec3 color; 14 | uniform sampler2D texture; 15 | 16 | varying vec3 vColor; 17 | 18 | void main() { 19 | 20 | gl_FragColor = vec4( color * vColor, 1.0 ); 21 | 22 | gl_FragColor = gl_FragColor * texture2D( texture, gl_PointCoord ); 23 | 24 | } -------------------------------------------------------------------------------- /assets/shaders/shaderplay.example.vert: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | precision highp int; 3 | 4 | #define VERTEX_TEXTURES 5 | #define MAX_DIR_LIGHTS 0 6 | #define MAX_POINT_LIGHTS 0 7 | #define MAX_SPOT_LIGHTS 0 8 | #define MAX_HEMI_LIGHTS 0 9 | #define MAX_SHADOWS 0 10 | #define MAX_BONES 251 11 | 12 | uniform mat4 modelMatrix; 13 | uniform mat4 modelViewMatrix; 14 | uniform mat4 projectionMatrix; 15 | uniform mat4 viewMatrix; 16 | uniform mat3 normalMatrix; 17 | uniform vec3 cameraPosition; 18 | attribute vec3 position; 19 | attribute vec3 normal; 20 | attribute vec2 uv; 21 | attribute vec2 uv2; 22 | #ifdef USE_COLOR 23 | attribute vec3 color; 24 | #endif 25 | #ifdef USE_MORPHTARGETS 26 | attribute vec3 morphTarget0; 27 | attribute vec3 morphTarget1; 28 | attribute vec3 morphTarget2; 29 | attribute vec3 morphTarget3; 30 | #ifdef USE_MORPHNORMALS 31 | attribute vec3 morphNormal0; 32 | attribute vec3 morphNormal1; 33 | attribute vec3 morphNormal2; 34 | attribute vec3 morphNormal3; 35 | #else 36 | attribute vec3 morphTarget4; 37 | attribute vec3 morphTarget5; 38 | attribute vec3 morphTarget6; 39 | attribute vec3 morphTarget7; 40 | #endif 41 | #endif 42 | #ifdef USE_SKINNING 43 | attribute vec4 skinIndex; 44 | attribute vec4 skinWeight; 45 | #endif 46 | attribute float size; 47 | attribute vec3 customColor; 48 | 49 | varying vec3 vColor; 50 | 51 | void main() { 52 | 53 | vColor = customColor; 54 | 55 | vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 ); 56 | 57 | gl_PointSize = size * ( 300.0 / length( mvPosition.xyz ) ); 58 | 59 | gl_Position = projectionMatrix * mvPosition; 60 | 61 | } -------------------------------------------------------------------------------- /assets/shaders/sinegravitycloud.frag: -------------------------------------------------------------------------------- 1 | uniform vec3 color; 2 | uniform sampler2D texture; 3 | 4 | varying vec3 vColor; 5 | 6 | void main() { 7 | 8 | gl_FragColor = vec4( color * vColor, 1.0 ); 9 | 10 | gl_FragColor = gl_FragColor * texture2D( texture, gl_PointCoord ); 11 | 12 | } -------------------------------------------------------------------------------- /assets/shaders/sinegravitycloud.vert: -------------------------------------------------------------------------------- 1 | attribute float size; 2 | attribute vec3 customColor; 3 | 4 | varying vec3 vColor; 5 | 6 | void main() { 7 | 8 | vColor = customColor; 9 | 10 | vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 ); 11 | 12 | gl_PointSize = size * ( 300.0 / length( mvPosition.xyz ) ); 13 | 14 | gl_Position = projectionMatrix * mvPosition; 15 | 16 | } -------------------------------------------------------------------------------- /index.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{documentTitle}} 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 36 | 37 |
38 |

Sorry, it looks like WebGL is not supported by your browser or graphics card.

39 |

Find out more about WebGL support here.

40 |
41 | 42 |
43 | 44 |
45 | 46 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | A Three.js Sandbox of Experiments | Greg Tatum 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 36 | 37 |
38 |

Sorry, it looks like WebGL is not supported by your browser or graphics card.

39 |

Find out more about WebGL support here.

40 |
41 | 42 |
43 | 44 |
45 | 46 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /js/components/Info.js: -------------------------------------------------------------------------------- 1 | var Info = function( poem, properties ) { 2 | 3 | var originalTitle = document.title; 4 | 5 | var $appendCredits = $( properties.appendCredits ); 6 | 7 | if( properties.appendCredits ) $('.credits').append( $appendCredits ); 8 | if( properties.title ) $("#info-title").text( properties.title ); 9 | if( properties.subtitle ) $("#info-subtitle").text( properties.subtitle); 10 | 11 | if( properties.titleCss ) $("#info-title").css( properties.titleCss ); 12 | if( properties.subtitleCss ) $("#info-subtitle").css( properties.subtitleCss ); 13 | 14 | 15 | if( properties.documentTitle ) document.title = properties.documentTitle; 16 | 17 | if( properties.showArrowNext ) $(".arrow-next").show(); 18 | 19 | $("#info").show(); 20 | 21 | poem.emitter.on('destroy', function() { 22 | document.title = originalTitle; 23 | $("#info-title").text(''); 24 | $("#info-subtitle").text(''); 25 | $("#info-title").attr('style', ''); 26 | $("#info-subtitle").attr('style', ''); 27 | $(".arrow-next").hide(); 28 | $("#info").hide(); 29 | $appendCredits.remove(); 30 | }); 31 | 32 | }; 33 | 34 | module.exports = Info; -------------------------------------------------------------------------------- /js/components/Stars.js: -------------------------------------------------------------------------------- 1 | var Stars = function( poem ) { 2 | this.poem = poem; 3 | this.object = null; 4 | 5 | this.count = 30000; 6 | this.depth = 5000; 7 | this.minDepth = 700; 8 | this.color = 0xaaaaaa; 9 | 10 | this.addObject(); 11 | }; 12 | 13 | module.exports = Stars; 14 | 15 | Stars.prototype = { 16 | 17 | generateGeometry : function() { 18 | var r, theta, x, y, z, geometry; 19 | 20 | geometry = new THREE.Geometry(); 21 | 22 | for(var i=0; i < this.count; i++) { 23 | 24 | r = Math.random() * this.depth + this.minDepth; 25 | 26 | theta = Math.random() * 2 * Math.PI; 27 | 28 | x = Math.cos( theta ) * r; 29 | z = Math.sin( theta ) * r; 30 | y = (0.5 - Math.random()) * this.depth; 31 | 32 | geometry.vertices.push( new THREE.Vector3(x,y,z) ); 33 | 34 | } 35 | 36 | return geometry; 37 | }, 38 | 39 | addObject : function() { 40 | 41 | var geometry, lineMaterial; 42 | 43 | geometry = this.generateGeometry(); 44 | 45 | 46 | this.object = new THREE.PointCloud( 47 | geometry, 48 | new THREE.PointCloudMaterial({ 49 | size: 3 * this.poem.ratio, 50 | color: this.color, 51 | fog: false 52 | } 53 | ) ); 54 | 55 | this.poem.scene.add( this.object ) ; 56 | 57 | } 58 | }; -------------------------------------------------------------------------------- /js/components/ambiance/Clouds/clouds.frag: -------------------------------------------------------------------------------- 1 | uniform float time; 2 | uniform vec4 color; 3 | uniform vec2 offset; 4 | uniform sampler2D texture; 5 | 6 | varying vec2 vUv; 7 | 8 | void main() { 9 | 10 | vec4 texel = 11 | texture2D( texture, vUv * 0.1 + ( offset + time * 0.00001) * offset ) + 12 | texture2D( texture, vUv * 0.22 + ( offset + time * 0.0000055) * offset ); 13 | 14 | float edges = 0.5 - length(vUv - 0.5); 15 | 16 | gl_FragColor = color * edges * vec4( 1.0, 1.0, 1.0, texel.w * texel.w * 2.5 ); 17 | 18 | } -------------------------------------------------------------------------------- /js/components/ambiance/Clouds/clouds.vert: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | 3 | void main() { 4 | 5 | vUv = uv; 6 | 7 | gl_Position = projectionMatrix * 8 | modelViewMatrix * 9 | vec4( position, 1.0); 10 | 11 | } -------------------------------------------------------------------------------- /js/components/ambiance/Clouds/index.js: -------------------------------------------------------------------------------- 1 | var glslify = require('glslify'); 2 | 3 | function setupTexture( mesh, scene, material ) { 4 | 5 | var img = new Image(); 6 | var texture = new THREE.Texture( img ); 7 | img.src = 'assets/images/cloud1024.png'; 8 | 9 | $('body').append(img); 10 | 11 | texture.wrapS = THREE.RepeatWrapping; 12 | texture.wrapT = THREE.RepeatWrapping; 13 | 14 | $(img).on('load', function() { 15 | material.needsUpdate = true; 16 | texture.needsUpdate = true; 17 | }); 18 | 19 | scene.add( mesh ); 20 | 21 | return texture; 22 | 23 | } 24 | 25 | var Clouds = function( poem, properties ) { 26 | 27 | var config = _.extend({ 28 | width : 500, 29 | offset : new THREE.Vector2(1,1), 30 | color : new THREE.Vector4( 0.5, 1.0, 0.7, 1 ), 31 | height : -200, 32 | rotation : Math.PI / 2 33 | }, properties); 34 | 35 | var geometry = new THREE.PlaneGeometry( config.width, config.width ); 36 | 37 | var material = new THREE.ShaderMaterial({ 38 | 39 | vertexShader: glslify('./clouds.vert'), 40 | fragmentShader: glslify('./clouds.frag'), 41 | 42 | transparent: true, 43 | blending: THREE.AdditiveBlending, 44 | side: THREE.DoubleSide, 45 | depthTest: false, 46 | 47 | uniforms: { 48 | time: { type: "f", value:0 }, 49 | texture: { type: "t", value: null }, 50 | offset: { type: "v2", value: config.offset }, 51 | color: { type: "v4", value: config.color } 52 | }, 53 | attributes: {} 54 | }) 55 | 56 | var mesh = new THREE.Mesh( geometry, material ); 57 | 58 | mesh.rotation.x = config.rotation; 59 | mesh.position.y = config.height; 60 | mesh.scale.multiplyScalar( 10 ); 61 | 62 | material.uniforms.texture.value = setupTexture( mesh, poem.scene, material ); 63 | 64 | poem.emitter.on('update', function( e ) { 65 | var cameraPosition = poem.camera.object.position; 66 | material.uniforms.time.value = e.elapsed; 67 | mesh.position.set( 68 | cameraPosition.x, 69 | mesh.position.y, 70 | cameraPosition.z 71 | ); 72 | }); 73 | }; 74 | 75 | module.exports = Clouds; 76 | -------------------------------------------------------------------------------- /js/components/ambiance/Sky/index.js: -------------------------------------------------------------------------------- 1 | var glslify = require('glslify'); 2 | 3 | var Sky = function( poem, properties ) { 4 | 5 | var config = _.extend({ 6 | 7 | width : 5000 8 | 9 | }, properties ); 10 | 11 | var geometry = new THREE.SphereGeometry( config.width, 64, 30 ); 12 | 13 | var material = new THREE.ShaderMaterial({ 14 | 15 | vertexShader : glslify('./sky.vert'), 16 | fragmentShader : glslify('./sky.frag'), 17 | 18 | side : THREE.BackSide, 19 | transparent : true, 20 | depthTest : false, 21 | 22 | uniforms: { 23 | time: { type: "f", value:0 }, 24 | }, 25 | attributes: {} 26 | }) 27 | 28 | var mesh = new THREE.Mesh( geometry, material ); 29 | poem.scene.add( mesh ); 30 | 31 | poem.emitter.on('update', function( e ) { 32 | material.uniforms.time.value = e.elapsed; 33 | mesh.position.copy( poem.camera.object.position ); 34 | }); 35 | }; 36 | 37 | module.exports = Sky; 38 | -------------------------------------------------------------------------------- /js/components/ambiance/Sky/sky-old.frag: -------------------------------------------------------------------------------- 1 | #define PI 3.141592653589793 2 | #define TWOPI 6.283185307179586 3 | 4 | varying vec4 vColor; 5 | varying vec2 vUv; 6 | uniform float time; 7 | 8 | #pragma glslify: snoise3 = require(glsl-noise/simplex/3d) 9 | 10 | float remap( in float value, in float start, in float stop ) { 11 | return start + value * ( stop - start ); 12 | } 13 | 14 | float inRange( in float value, in float start, in float stop ) { 15 | 16 | return min( 1.0, max( 0.0, 17 | (value - start) / (stop - start) 18 | )); 19 | 20 | } 21 | 22 | float generateClouds( in vec2 vUv, in float time ) { 23 | 24 | return snoise3( 10.0 * vec3( 25 | sin( vUv.x * PI ) * 0.5, 26 | vUv.y, 27 | time 28 | )); 29 | 30 | } 31 | 32 | 33 | void main() { 34 | 35 | float timeScaled = time * 0.00001; 36 | 37 | float brightness = 38 | inRange( vUv.y, 0.4, 0.6 ) * 39 | mix( sin( vUv.x * 10.0 * TWOPI ), 1.0, 0.2 ); 40 | 41 | brightness += generateClouds( vUv, timeScaled ); 42 | 43 | vec4 cloudColor = vec4( 44 | 0.0, 45 | 0.3 * brightness, 46 | 0.3 * brightness, 47 | 0.1 48 | ); 49 | 50 | vec4 noise = vec4( 51 | snoise3( vec3( 10.0, 10.0, timeScaled ) ), 52 | snoise3( vec3( 10.0, 10.0, timeScaled ) ), 53 | snoise3( vec3( 10.0, 10.0, timeScaled ) ), 54 | 1.0 55 | ); 56 | 57 | gl_FragColor = vColor + cloudColor * noise; 58 | 59 | } -------------------------------------------------------------------------------- /js/components/ambiance/Sky/sky.frag: -------------------------------------------------------------------------------- 1 | varying vec4 vColor; 2 | 3 | // float remap( in float value, in float start, in float stop ) { 4 | // return start + value * ( stop - start ); 5 | // } 6 | 7 | void main() { 8 | 9 | gl_FragColor = vColor; 10 | 11 | } -------------------------------------------------------------------------------- /js/components/ambiance/Sky/sky.vert: -------------------------------------------------------------------------------- 1 | uniform float time; 2 | varying vec4 vColor; 3 | 4 | #pragma glslify: simplex4 = require(glsl-noise/simplex/4d) 5 | #pragma glslify: hsv2rgb = require(glsl-hsv2rgb) 6 | 7 | float inRange( in float value, in float start, in float stop ) { 8 | 9 | return min( 1.0, max( 0.0, 10 | (value - start) / (stop - start) 11 | )); 12 | 13 | } 14 | 15 | vec4 calculateColor( in vec2 uv, in vec3 position ) { 16 | 17 | float gradient = 18 | inRange( uv.y, 0.55, 0.7 ) + 19 | inRange( uv.y, 0.45, 0.3 ) ; 20 | 21 | float noise = simplex4( vec4( position * 0.03, time * 0.0001 ) ); 22 | 23 | vec3 color = hsv2rgb(vec3( 24 | max(0.0, noise) * 0.2 + 0.4, 25 | 1.0, 26 | 1.0 27 | )); 28 | 29 | return vec4( 30 | color, 31 | noise * gradient 32 | ); 33 | 34 | } 35 | 36 | void main() { 37 | 38 | vColor = calculateColor( uv, position ); 39 | 40 | gl_Position = projectionMatrix * 41 | modelViewMatrix * 42 | vec4( position, 1.0); 43 | 44 | } -------------------------------------------------------------------------------- /js/components/ambiance/blobs/blobs.frag: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | 3 | uniform float elapsed; 4 | varying float vOffset; 5 | 6 | vec2 doModel(vec3 p); 7 | 8 | #pragma glslify: raytrace = require('glsl-raytrace', map = doModel, steps = 30) 9 | #pragma glslify: normal = require('glsl-sdf-normal', map = doModel) 10 | #pragma glslify: camera = require('glsl-turntable-camera') 11 | #pragma glslify: noise = require('glsl-noise/simplex/4d') 12 | #pragma glslify: cameraRay = require('glsl-camera-ray') 13 | 14 | vec2 doModel(vec3 p) { 15 | float r = 1.0 + noise(vec4(p, elapsed / 1000.0)) * 0.25; 16 | float d = length(p) - r; 17 | float id = 0.0; 18 | 19 | return vec2(d, id); 20 | } 21 | 22 | vec2 squareFrame(vec2 screenSize, vec2 screenPosition) { 23 | vec2 position = 2.0 * (screenPosition.xy / screenSize.xy) - 1.0; 24 | position.x *= screenSize.x / screenSize.y; 25 | return position; 26 | } 27 | 28 | 29 | void orbitCamera( 30 | in float camAngle, 31 | in float camHeight, 32 | in float camDistance, 33 | in vec2 screenResolution, 34 | in vec2 screenPosition, 35 | out vec3 rayOrigin, 36 | out vec3 rayDirection 37 | ) { 38 | vec2 screenPos = squareFrame(screenResolution, screenPosition); 39 | vec3 rayTarget = vec3(0.0); 40 | 41 | rayOrigin = vec3( 42 | camDistance * sin(camAngle), 43 | camHeight, 44 | camDistance * cos(camAngle) 45 | ); 46 | 47 | rayDirection = cameraRay(rayOrigin, rayTarget, screenPos, 2.0); 48 | } 49 | 50 | 51 | void main() { 52 | vec3 color = vec3(0.0); 53 | vec3 rayOrigin, rayDirection; 54 | 55 | float rotation = elapsed / 1000.0; 56 | float height = 0.0; 57 | float dist = 3.0; 58 | vec2 iResolution = vec2( 1.0, 1.0 ); 59 | 60 | orbitCamera(rotation + vOffset * 100.0, height, dist, iResolution, gl_PointCoord, rayOrigin, rayDirection); 61 | 62 | vec2 t = raytrace(rayOrigin, rayDirection); 63 | if (t.x > -0.5) { 64 | vec3 pos = rayOrigin + rayDirection * t.x; 65 | vec3 nor = normal(pos); 66 | 67 | color = nor * 0.5 + 0.5; 68 | } 69 | 70 | gl_FragColor.rgb = color; 71 | gl_FragColor.a = length(color) * 10.0; 72 | } 73 | 74 | // Old shader: 75 | // 76 | // uniform vec3 color; 77 | // uniform sampler2D texture; 78 | // uniform float elapsed; 79 | // 80 | // varying float vAlpha; 81 | // 82 | // void main() { 83 | // 84 | // gl_FragColor = vec4(color, 1.0); 85 | // 86 | // } 87 | // -------------------------------------------------------------------------------- /js/components/ambiance/blobs/blobs.js: -------------------------------------------------------------------------------- 1 | var Glslify = require('glslify') 2 | var LoadTexture = require('../../../utils/loadTexture') 3 | var Random = require('../../../utils/random') 4 | 5 | 6 | function _createMaterial( color, range ) { 7 | 8 | var material = new THREE.ShaderMaterial({ 9 | 10 | vertexShader : Glslify('./blobs.vert'), 11 | fragmentShader : Glslify('./blobs.frag'), 12 | depthTest : false, 13 | blending : THREE.AdditiveBlending, 14 | transparent : true, 15 | uniforms : { 16 | elapsed : { type: 'f', value: color }, 17 | uRange : { type: 'f', value: range } 18 | }, 19 | attributes : { 20 | size : { type: 'f', value: [] }, 21 | aOffset : { type: 'f', value: [] } 22 | } 23 | 24 | }) 25 | 26 | 27 | return material 28 | } 29 | 30 | function _createGeometry( material, count, range, sizeRange, ratio ) { 31 | 32 | var geometry = new THREE.BufferGeometry() 33 | 34 | var positions = new Float32Array( count * 3 ) 35 | var sizes = new Float32Array( count ) 36 | var offsets = new Float32Array( count ) 37 | 38 | for( var i = 0; i < count; i++ ) { 39 | 40 | positions[ i * 3 + 0 ] = Random.range( -range, range ) 41 | positions[ i * 3 + 1 ] = Random.range( -range, range ) * 0.3 42 | positions[ i * 3 + 2 ] = Random.range( -range, range ) 43 | 44 | sizes[ i ] = Random.range( sizeRange[0], sizeRange[1] ) * ratio 45 | offsets[ i ] = Random.range( 0, 1 ) 46 | 47 | } 48 | 49 | geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) ) 50 | geometry.addAttribute( 'size', new THREE.BufferAttribute( sizes, 1 ) ) 51 | geometry.addAttribute( 'aOffset', new THREE.BufferAttribute( offsets, 1 ) ) 52 | 53 | return geometry 54 | } 55 | 56 | function _createMeshAndStart( poem, geometry, material ) { 57 | 58 | var mesh = new THREE.PointCloud( geometry, material ) 59 | mesh.frustumCulled = false 60 | 61 | var p = LoadTexture( "assets/images/bokeh.png", material.uniforms.texture, "value" ).then(function() { 62 | 63 | poem.scene.add( mesh ) 64 | poem.emitter.on('update', _updateFn( poem, mesh )) 65 | }) 66 | 67 | return mesh 68 | } 69 | 70 | function _updateFn( poem, mesh ) { 71 | 72 | return function(e) { 73 | 74 | // mesh.position.copy( poem.camera.object.position ) 75 | mesh.material.uniforms.elapsed.value = e.elapsed; 76 | } 77 | } 78 | 79 | module.exports = function particles( poem, properties ) { 80 | 81 | var config = _.extend({ 82 | count: 1000 83 | , color: new THREE.Color(0x77ffff) 84 | , range: 300 85 | , sizeRange: [10,20] 86 | }, properties) 87 | 88 | var material = _createMaterial( 89 | config.color 90 | , config.range 91 | ) 92 | 93 | var geometry = _createGeometry( 94 | material 95 | , config.count 96 | , config.range 97 | , config.sizeRange 98 | , poem.ratio 99 | ) 100 | 101 | var mesh = _createMeshAndStart( 102 | poem, 103 | geometry, 104 | material 105 | ) 106 | 107 | return {} 108 | } -------------------------------------------------------------------------------- /js/components/ambiance/blobs/blobs.vert: -------------------------------------------------------------------------------- 1 | uniform float elapsed; 2 | uniform float uRange; 3 | attribute float size; 4 | attribute float aOffset; 5 | 6 | varying float vOffset; 7 | #pragma glslify: snoise3 = require(glsl-noise/simplex/3d) 8 | 9 | void main() { 10 | 11 | // vec3 movement = vec3(0.0, elapsed * 0.001, 0.0); 12 | vec3 movement = vec3( 13 | sin( elapsed * 0.002 * aOffset) * uRange * 0.003, 14 | elapsed * (-uRange / 100000.0 - uRange / 100000.0 * aOffset), 15 | cos( elapsed * 0.002 * aOffset ) * uRange * 0.003 16 | ); 17 | 18 | vec3 range = vec3(uRange, uRange * 0.3, uRange); 19 | 20 | vec3 cameraOffset = cameraPosition - range; 21 | 22 | vec3 moduloPosition = mod( position + movement - cameraOffset, range * 2.0 ) + cameraOffset; 23 | vec4 mvPosition = modelViewMatrix * vec4( moduloPosition, 1.0 ); 24 | 25 | vOffset = aOffset; 26 | 27 | gl_PointSize = size * ( uRange / (length( mvPosition.xyz ) + 1.0) ); 28 | gl_Position = projectionMatrix * mvPosition; 29 | 30 | } -------------------------------------------------------------------------------- /js/components/ambiance/light-beam/light-beam.frag: -------------------------------------------------------------------------------- 1 | uniform vec3 color; 2 | uniform sampler2D texture; 3 | // uniform float elapsed; 4 | 5 | varying float vAlpha; 6 | 7 | void main() { 8 | 9 | gl_FragColor = vec4(color, vAlpha) * texture2D( texture, gl_PointCoord ); 10 | 11 | } -------------------------------------------------------------------------------- /js/components/ambiance/light-beam/light-beam.vert: -------------------------------------------------------------------------------- 1 | uniform float elapsed; 2 | 3 | attribute float size; 4 | attribute float opacity; 5 | 6 | varying float vAlpha; 7 | 8 | #pragma glslify: snoise3 = require(glsl-noise/simplex/3d) 9 | 10 | void main() { 11 | 12 | vAlpha = opacity; 13 | 14 | vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 ); 15 | 16 | gl_PointSize = 100.0 * size / length( mvPosition.xyz ); 17 | 18 | gl_Position = projectionMatrix * mvPosition; 19 | } -------------------------------------------------------------------------------- /js/components/ambiance/particles/particles.frag: -------------------------------------------------------------------------------- 1 | uniform vec3 color; 2 | uniform sampler2D texture; 3 | uniform float elapsed; 4 | 5 | varying float vAlpha; 6 | 7 | void main() { 8 | 9 | gl_FragColor = vec4(color, vAlpha) * texture2D( texture, gl_PointCoord ); 10 | 11 | } -------------------------------------------------------------------------------- /js/components/ambiance/particles/particles.js: -------------------------------------------------------------------------------- 1 | var Glslify = require('glslify') 2 | var LoadTexture = require('../../../utils/loadTexture') 3 | var Random = require('../../../utils/random') 4 | 5 | var internals = { 6 | 7 | createMaterial : function( color, range ) { 8 | 9 | var material = new THREE.ShaderMaterial({ 10 | 11 | vertexShader : Glslify('./particles.vert'), 12 | fragmentShader : Glslify('./particles.frag'), 13 | 14 | blending: THREE.AdditiveBlending, 15 | depthTest: false, 16 | transparent: true, 17 | 18 | uniforms: { 19 | elapsed : { type: 'f' }, 20 | texture : { type: 't' }, 21 | color : { type: "c", value: color }, 22 | uRange : { type: "f", value: range }, 23 | }, 24 | attributes : { 25 | position: { type: 'v3' }, 26 | size: { type: 'f' }, 27 | aOffset: { type: 'f' }, 28 | } 29 | }) 30 | 31 | return material 32 | }, 33 | 34 | createGeometry : function( material, count, range, sizeRange ) { 35 | 36 | var geometry = new THREE.BufferGeometry() 37 | 38 | var positions = new Float32Array( count * 3 ) 39 | var sizes = new Float32Array( count ) 40 | var offsets = new Float32Array( count ) 41 | 42 | for( var i = 0; i < count; i++ ) { 43 | 44 | positions[ i * 3 + 0 ] = Random.range( -range, range ) 45 | positions[ i * 3 + 1 ] = Random.range( -range, range ) * 0.3 46 | positions[ i * 3 + 2 ] = Random.range( -range, range ) 47 | 48 | sizes[ i ] = Random.range( sizeRange[0], sizeRange[1] ) 49 | offsets[ i ] = Random.range( 0, 1 ) 50 | 51 | } 52 | 53 | geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) ) 54 | geometry.addAttribute( 'size', new THREE.BufferAttribute( sizes, 1 ) ) 55 | geometry.addAttribute( 'aOffset', new THREE.BufferAttribute( offsets, 1 ) ) 56 | 57 | return geometry 58 | }, 59 | 60 | createMeshAndStart : function( poem, geometry, material ) { 61 | 62 | var mesh = new THREE.PointCloud( geometry, material ) 63 | mesh.frustumCulled = false 64 | 65 | var p = LoadTexture( "assets/images/bokeh.png", material.uniforms.texture, "value" ).then(function() { 66 | 67 | poem.scene.add( mesh ) 68 | poem.emitter.on('update', internals.updateFn( poem, mesh )) 69 | }) 70 | 71 | return mesh 72 | }, 73 | 74 | updateFn : function( poem, mesh ) { 75 | 76 | return function(e) { 77 | 78 | // mesh.position.copy( poem.camera.object.position ) 79 | mesh.material.uniforms.elapsed.value = e.elapsed; 80 | } 81 | } 82 | } 83 | 84 | 85 | module.exports = function particles( poem, properties ) { 86 | 87 | var config = _.extend({ 88 | count: 3000 89 | , color: new THREE.Color(0x77ffff) 90 | , range: 300 91 | , sizeRange: [3,8] 92 | }, properties) 93 | 94 | var material = internals.createMaterial( 95 | config.color 96 | , config.range 97 | ) 98 | 99 | var geometry = internals.createGeometry( 100 | material 101 | , config.count 102 | , config.range 103 | , config.sizeRange 104 | ) 105 | 106 | var mesh = internals.createMeshAndStart( 107 | poem, 108 | geometry, 109 | material 110 | ) 111 | 112 | return {} 113 | } -------------------------------------------------------------------------------- /js/components/ambiance/particles/particles.vert: -------------------------------------------------------------------------------- 1 | uniform float elapsed; 2 | uniform float uRange; 3 | attribute float size; 4 | attribute float aOffset; 5 | varying float vAlpha; 6 | 7 | #pragma glslify: snoise3 = require(glsl-noise/simplex/3d) 8 | 9 | void main() { 10 | 11 | // vec3 movement = vec3(0.0, elapsed * 0.001, 0.0); 12 | vec3 movement = vec3( 13 | sin( elapsed * 0.002 * aOffset) * uRange * 0.003, 14 | elapsed * (-uRange / 100000.0 - uRange / 100000.0 * aOffset), 15 | cos( elapsed * 0.002 * aOffset ) * uRange * 0.003 16 | ); 17 | 18 | vec3 range = vec3(uRange, uRange * 0.3, uRange); 19 | 20 | vec3 cameraOffset = cameraPosition - range; 21 | 22 | vec3 moduloPosition = mod( position + movement - cameraOffset, range * 2.0 ) + cameraOffset; 23 | vec4 mvPosition = modelViewMatrix * vec4( moduloPosition, 1.0 ); 24 | 25 | gl_PointSize = size * ( uRange / (length( mvPosition.xyz ) + 1.0) ); 26 | 27 | float flicker = mix(0.6, 1.0, snoise3( moduloPosition + elapsed * 0.0001 )); 28 | 29 | vAlpha = 0.5 * min(1.0, max(0.0, 30 | 1.0 - (length( mvPosition.xyz ) / uRange) 31 | )) * flicker; 32 | 33 | gl_Position = projectionMatrix * mvPosition; 34 | 35 | } -------------------------------------------------------------------------------- /js/components/cameras/Camera.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | var Camera = function( properties, scene, poemEmitter ) { 4 | 5 | var config = _.extend({ 6 | fov : 50, 7 | near : 3, 8 | far : 10000, 9 | aspectRatio : window.innerWidth / window.innerHeight 10 | }, properties); 11 | 12 | this.object = new THREE.PerspectiveCamera( 13 | config.fov, 14 | config.aspect, 15 | config.near, 16 | config.far 17 | ); 18 | 19 | this.object.position.x = _.isNumber( properties.x ) ? properties.x : 0; 20 | this.object.position.y = _.isNumber( properties.y ) ? properties.y : 0; 21 | this.object.position.z = _.isNumber( properties.z ) ? properties.z : 500; 22 | 23 | scene.add( this.object ); 24 | 25 | poemEmitter.on( 'resize', this.resize.bind(this) ); 26 | 27 | }; 28 | 29 | module.exports = Camera; 30 | 31 | Camera.prototype = { 32 | 33 | resize : function() { 34 | this.object.aspect = window.innerWidth / window.innerHeight; 35 | this.object.updateProjectionMatrix(); 36 | }, 37 | 38 | setAndUpdateFov : function( fov ) { 39 | this.object.fov = fov 40 | this.object.updateProjectionMatrix() 41 | } 42 | }; -------------------------------------------------------------------------------- /js/components/cameras/ConstantMove.js: -------------------------------------------------------------------------------- 1 | function updateCamera( position, movement ) { 2 | 3 | var changeMovement = new THREE.Vector3(); 4 | 5 | return function(e) { 6 | 7 | changeMovement 8 | .copy( movement ) 9 | .multiplyScalar(e.unitDt); 10 | 11 | position.add( changeMovement ); 12 | 13 | }; 14 | } 15 | 16 | var ConstantMove = function( poem, properties ) { 17 | 18 | var config = _.extend({ 19 | x : 0, 20 | y : 0, 21 | z : 0 22 | }, properties); 23 | 24 | var movement = new THREE.Vector3( config.x, config.y, config.z ); 25 | 26 | poem.emitter.on('update', updateCamera( poem.camera.object.position, movement)); 27 | }; 28 | 29 | module.exports = ConstantMove; -------------------------------------------------------------------------------- /js/components/cameras/Controls.js: -------------------------------------------------------------------------------- 1 | var OrbitControls = require('../../vendor/OrbitControls'); 2 | 3 | var Controls = function( poem, properties ) { 4 | 5 | this.poem = poem; 6 | this.properties = properties; 7 | 8 | this.controls = new OrbitControls( this.poem.camera.object, this.poem.canvas ); 9 | 10 | _.extend( this.controls, properties ); 11 | 12 | this.poem.emitter.on( 'update', this.controls.update.bind( this.controls ) ); 13 | 14 | }; 15 | 16 | module.exports = Controls; 17 | -------------------------------------------------------------------------------- /js/components/cameras/Orientation.js: -------------------------------------------------------------------------------- 1 | var OrbitControls = require('../../vendor/OrbitControls'); 2 | var DeviceOrientationControls = require('../../vendor/DeviceOrientationControls'); 3 | var _e; 4 | 5 | $(window).one( 'deviceorientation', function( e ) { 6 | _e = e; 7 | }); 8 | 9 | 10 | var Orientation = function( poem ) { 11 | 12 | this.poem = poem; 13 | this.camera = this.poem.camera.object; 14 | 15 | this.controls = new OrbitControls( this.camera, this.poem.canvas ); 16 | this.controls.rotateUp(Math.PI / 4); 17 | this.controls.target.set( 18 | this.camera.position.x + 0.1, 19 | this.camera.position.y, 20 | this.camera.position.z 21 | ); 22 | this.controls.noZoom = true; 23 | this.controls.noPan = true; 24 | 25 | this.deviceOrientationHandler = this.setOrientationControls.bind(this); 26 | 27 | $(window).on( 'deviceorientation', this.deviceOrientationHandler ); 28 | 29 | this.poem.emitter.on( 'update', this.update.bind(this) ); 30 | this.poem.emitter.on( 'destroy', this.destroy.bind(this) ); 31 | 32 | if( _e ) this.setOrientationControls( _e ); 33 | 34 | }; 35 | 36 | module.exports = Orientation; 37 | 38 | Orientation.prototype = { 39 | 40 | setOrientationControls : function( e ) { 41 | // if( !e.originalEvent.alpha ) { 42 | // return; 43 | // } 44 | 45 | this.controls = new DeviceOrientationControls( this.camera, true ); 46 | this.controls.connect(); 47 | this.controls.update(); 48 | 49 | $(window).off( 'deviceorientation', this.deviceOrientationHandler ); 50 | }, 51 | 52 | update : function( e ) { 53 | this.controls.update(); 54 | }, 55 | 56 | destroy : function( e ) { 57 | $(window).off( 'deviceorientation', this.deviceOrientationHandler ); 58 | } 59 | 60 | }; -------------------------------------------------------------------------------- /js/components/cameras/RotateAroundOrigin.js: -------------------------------------------------------------------------------- 1 | var RotateAroundOrigin = function( poem ) { 2 | 3 | var camera = poem.camera.object; 4 | var speed = 0.00005; 5 | var baseY = camera.position.y; 6 | var baseZ = camera.position.z / 2; 7 | 8 | poem.emitter.on('update', function( e ) { 9 | 10 | poem.grid.grid.rotation.y += e.dt * speed; 11 | if( poem.pointcloud.object ) { 12 | poem.pointcloud.object.rotation.y += e.dt * speed; 13 | } 14 | 15 | camera.position.y = baseY + Math.sin( e.now * speed * 10 ) * 200; 16 | camera.position.z = baseY + Math.sin( e.now * speed * 10 ) * baseZ; 17 | 18 | 19 | }); 20 | 21 | }; 22 | 23 | module.exports = RotateAroundOrigin; 24 | 25 | RotateAroundOrigin.prototype = { 26 | 27 | }; -------------------------------------------------------------------------------- /js/components/cameras/Swivel.js: -------------------------------------------------------------------------------- 1 | function mouseMove( prevXY, quaternion, speedX, speedY ) { 2 | 3 | var axisX = new THREE.Vector3(1,0,0); 4 | var axisY = new THREE.Vector3(0,1,0); 5 | 6 | var q1 = new THREE.Quaternion(); 7 | var q2 = new THREE.Quaternion(); 8 | 9 | var rotationX = 0; 10 | var rotationY = 0; 11 | 12 | return function( e ) { 13 | 14 | e.preventDefault(); 15 | 16 | var x = e.pageX; 17 | var y = e.pageY; 18 | 19 | var offsetX = prevXY.x - x; 20 | var offsetY = prevXY.y - y; 21 | 22 | rotationY += offsetX * speedX; 23 | rotationX += offsetY * speedY; 24 | 25 | rotationX = Math.min( rotationX, Math.PI * 0.45 ); 26 | rotationX = Math.max( rotationX, -Math.PI * 0.45 ); 27 | 28 | q1.setFromAxisAngle( axisY, rotationY ); 29 | q2.setFromAxisAngle( axisX, rotationX ); 30 | quaternion.multiplyQuaternions( q1, q2 ); 31 | 32 | 33 | prevXY.x = x; 34 | prevXY.y = y; 35 | 36 | }; 37 | } 38 | 39 | function mouseUp( $canvas, handlers ) { 40 | 41 | return function() { 42 | $canvas.off('mouseleave', handlers.mouseUp); 43 | $canvas.off('mouseup', handlers.mouseUp); 44 | $canvas.off('mousemove', handlers.mouseMove); 45 | }; 46 | } 47 | 48 | function mouseDown( $canvas, handlers, prevXY ) { 49 | 50 | return function( e ) { 51 | e.preventDefault(); 52 | 53 | prevXY.x = e.pageX; 54 | prevXY.y = e.pageY; 55 | 56 | $canvas.on('mouseleave', handlers.mouseUp ); 57 | $canvas.on('mouseup', handlers.mouseUp ); 58 | $canvas.on('mousemove', handlers.mouseMove ); 59 | }; 60 | } 61 | 62 | function stopHandlers( $canvas, handlers ) { 63 | 64 | return function() { 65 | $canvas.off('mouseleave', handlers.mouseUp); 66 | $canvas.off('mouseup', handlers.mouseUp); 67 | $canvas.off('mousemove', handlers.mouseMove); 68 | $canvas.off('mousedown', handlers.mouseDown); 69 | }; 70 | } 71 | 72 | function startMouseHandlers( canvas, cameraObj, poem, speedX, speedY ) { 73 | 74 | var prevXY = {x:0,y:0}; 75 | var $canvas = $(canvas); 76 | var handlers = {}; 77 | var quaternion = new THREE.Quaternion().copy( cameraObj.quaternion ); 78 | 79 | handlers.mouseMove = mouseMove( prevXY, quaternion, speedX, speedY ); 80 | handlers.mouseUp = mouseUp( $canvas, handlers ); 81 | handlers.mouseDown = mouseDown( $canvas, handlers, prevXY ); 82 | 83 | $canvas.on('mousedown', handlers.mouseDown); 84 | poem.emitter.on('destroy', stopHandlers( $canvas, handlers ) ); 85 | 86 | return quaternion; 87 | } 88 | 89 | function updateCamera( cameraQuaternion, targetQuaternion, unitI ) { 90 | 91 | return function( e ) { 92 | 93 | cameraQuaternion.slerp( targetQuaternion, unitI * e.unitDt ); 94 | 95 | }; 96 | } 97 | 98 | var Swivel = function( poem, properties ) { 99 | 100 | var config = _.extend({ 101 | easing : 0.5, 102 | speedX : 0.002, 103 | speedY : 0.002 104 | }, properties); 105 | 106 | var targetQuaternion = startMouseHandlers( 107 | poem.canvas, 108 | poem.camera.object, 109 | poem, 110 | config.speedX, config.speedY 111 | ); 112 | 113 | poem.emitter.on('update', updateCamera( poem.camera.object.quaternion, targetQuaternion, config.easing ) ); 114 | 115 | }; 116 | 117 | module.exports = Swivel; -------------------------------------------------------------------------------- /js/components/cameras/Trackball.js: -------------------------------------------------------------------------------- 1 | var Trackball = require('../../vendor/TrackballControls'); 2 | 3 | var Controls = function( poem, properties ) { 4 | 5 | this.poem = poem; 6 | this.properties = properties; 7 | 8 | this.controls = new Trackball( this.poem.camera.object, this.poem.canvas ); 9 | 10 | _.extend( this.controls, properties ); 11 | 12 | this.poem.emitter.on( 'update', this.controls.update.bind( this.controls ) ); 13 | 14 | }; 15 | 16 | module.exports = Controls; 17 | -------------------------------------------------------------------------------- /js/components/fbo-positioning/fbo-position.shader: -------------------------------------------------------------------------------- 1 | uniform float textureSideLength; 2 | 3 | uniform sampler2D textureCurrPosition; 4 | uniform sampler2D texturePrevPosition; 5 | 6 | 7 | void main() { 8 | 9 | vec2 uv = gl_FragCoord.xy / textureSideLength; 10 | vec4 currPosition = texture2D( textureCurrPosition, uv ); 11 | vec4 prevPosition = texture2D( texturePrevPosition, uv ); 12 | 13 | vec3 velocity = currPosition.xyz - prevPosition.xyz; 14 | vec3 toOrigin = normalize(-1.0 * currPosition.xyz); 15 | vec3 orientation = normalize( velocity ); 16 | vec3 newOrientation = normalize( mix( toOrigin, orientation, 0.93 ) ); 17 | newOrientation += vec3(0.0001, 0.0001, 0.0001); 18 | float velocityLength = length( velocity ); 19 | float toOriginLength = length( currPosition.xyz ); 20 | 21 | gl_FragColor = vec4( 22 | currPosition.xyz + newOrientation * 0.02, 23 | 1.0 24 | ); 25 | } -------------------------------------------------------------------------------- /js/components/fbo-positioning/fbo-render.frag: -------------------------------------------------------------------------------- 1 | varying float vLighting; 2 | varying float vAttributeIndex; 3 | 4 | #pragma glslify: hsl2rgb = require(glsl-hsl2rgb) 5 | 6 | void main() { 7 | 8 | gl_FragColor = vec4( 9 | hsl2rgb( mod(0.5 + vAttributeIndex * 0.000002, 1.0), 0.8, 0.5 ), 10 | 1.0 11 | ) * vLighting; 12 | } -------------------------------------------------------------------------------- /js/components/fbo-positioning/fbo-render.vert: -------------------------------------------------------------------------------- 1 | uniform float elapsed; 2 | 3 | uniform float textureSideLength; 4 | uniform sampler2D textureCurrPosition; 5 | uniform sampler2D texturePrevPosition; 6 | 7 | attribute float attributeIndex; 8 | 9 | varying float vLighting; 10 | varying float vAttributeIndex; 11 | 12 | void main() { 13 | 14 | vec2 positionLookup = vec2( 15 | mod(attributeIndex, textureSideLength), 16 | floor(attributeIndex / textureSideLength) 17 | ) / textureSideLength; 18 | 19 | vec3 currPosition = texture2D( textureCurrPosition, positionLookup ).xyz; 20 | vec3 prevPosition = texture2D( texturePrevPosition, positionLookup ).xyz; 21 | 22 | float theta = log(attributeIndex) * 8.0; 23 | float r = attributeIndex * 2.0; 24 | 25 | vec4 offset = vec4( r * sin(theta), r * cos(theta), 0.0, 0.0 ); 26 | 27 | vLighting = dot( normal, normalize(cameraPosition - position) ); 28 | vLighting = vLighting * 0.5 + 0.5; 29 | 30 | vAttributeIndex = attributeIndex; 31 | 32 | gl_Position = 33 | projectionMatrix * 34 | modelViewMatrix * ( 35 | vec4( position, 1.0 ) + offset * 0.0 + vec4( currPosition * 100.0, 0 ) 36 | ); 37 | } -------------------------------------------------------------------------------- /js/components/hids/mouse-tracker.js: -------------------------------------------------------------------------------- 1 | var Touches = require('touches') 2 | var EventEmitter = require('events').EventEmitter 3 | 4 | module.exports = function createMouseTracker( poem, config ) { 5 | 6 | var pixelPosition = new THREE.Vector2() 7 | var normalizedPosition = new THREE.Vector2() 8 | 9 | var savePosition = function(e, position) { 10 | e.preventDefault() 11 | 12 | normalizedPosition.x = 2 * (position[0] / poem.canvas.offsetWidth) - 1 13 | normalizedPosition.y = -2 * (position[1] / poem.canvas.offsetHeight) + 1 14 | 15 | pixelPosition.x = position[0] 16 | pixelPosition.y = position[1] 17 | } 18 | 19 | var emitter = Touches( poem.canvas, { filtered: true }) 20 | 21 | .on('start', savePosition ) 22 | 23 | .on('move', savePosition) 24 | 25 | .on('end', function(e) { 26 | pixelPosition.x = null 27 | pixelPosition.y = null 28 | normalizedPosition.x = null 29 | normalizedPosition.y = null 30 | }) 31 | 32 | poem.emitter.on('destroy', function() { 33 | emitter.disable() 34 | }) 35 | 36 | return { 37 | emitter : emitter 38 | , pixelPosition : pixelPosition 39 | , normalizedPosition : normalizedPosition 40 | } 41 | } -------------------------------------------------------------------------------- /js/components/lights/TrackCameraLights.js: -------------------------------------------------------------------------------- 1 | var TrackCameraLights = function( poem, properties ) { 2 | 3 | this.lights = []; 4 | 5 | var ambient = new THREE.AmbientLight( 0x111111, 1, 0 ); 6 | ambient.position.set(0, 2000, 1000); 7 | 8 | var front = new THREE.PointLight( 0xffffff, 0.3, 0 ); 9 | 10 | var rightFill = new THREE.PointLight( 0xffffff, 1, 0 ); 11 | rightFill.position.set(3000, 2000, 5000); 12 | 13 | var rimBottom = new THREE.PointLight( 0xffffff, 1, 0 ); 14 | rimBottom.position.set(-1000, -1000, -1000); 15 | 16 | var rimBackLeft = new THREE.PointLight( 0xffffff, 2, 0 ); 17 | rimBackLeft.position.set(-700, 500, -1000); 18 | 19 | poem.scene.add( ambient ); 20 | // poem.camera.object.add( front ); 21 | poem.camera.object.add( rightFill ); 22 | poem.camera.object.add( rimBottom ); 23 | poem.camera.object.add( rimBackLeft ); 24 | 25 | }; 26 | 27 | module.exports = TrackCameraLights; 28 | 29 | TrackCameraLights.prototype = { 30 | 31 | }; -------------------------------------------------------------------------------- /js/components/models/tree.js: -------------------------------------------------------------------------------- 1 | var AssimpJSONLoader = require('../../vendor/AssimpJSONLoader') 2 | 3 | var statics = { 4 | tree : null 5 | } 6 | 7 | function _loadTreePromise() { 8 | 9 | return new Promise(function( resolve, reject ) { 10 | 11 | if( statics.tree ) { 12 | resolve( statics.tree ) 13 | return 14 | } 15 | 16 | var loader = new THREE.AssimpJSONLoader(); 17 | 18 | var doneLoading = function ( object ) { 19 | _updateMaterials( object ) 20 | statics.tree = object 21 | resolve( object ) 22 | } 23 | var onProgress = function() {} 24 | 25 | loader.load( 26 | './js/components/models/tree.json', 27 | doneLoading, 28 | onProgress, 29 | reject 30 | ); 31 | }) 32 | } 33 | 34 | function _updateMaterials( obj ) { 35 | 36 | if( obj.material ) { 37 | obj.material.side = THREE.DoubleSide 38 | obj.material.shading = THREE.SmoothShading 39 | obj.material.specular = new THREE.Color(0x555555) 40 | obj.material.shininess = 1 41 | } 42 | 43 | for( var i=0; i < obj.children.length; i++ ) { 44 | _updateMaterials( obj.children[i] ) 45 | } 46 | } 47 | 48 | module.exports = function createTree( poem, props ) { 49 | 50 | var config = _.extend({ 51 | position: [0,0,0], 52 | scale: [10,10,10], 53 | }, props) 54 | 55 | var geometry = new THREE.SphereGeometry( 20, 32, 32 ); 56 | var material = new THREE.MeshPhongMaterial( {color: 0xffff00} ); 57 | var sphere = new THREE.Mesh( geometry, material ); 58 | sphere.position.x = 20 59 | poem.scene.add( sphere ); 60 | 61 | return _loadTreePromise().then(function( tree ) { 62 | 63 | poem.scene.add( tree ) 64 | tree.position.fromArray( config.position ) 65 | tree.scale.fromArray( config.scale ) 66 | 67 | window.tree = tree.children[0].children[0] 68 | 69 | return tree 70 | }) 71 | } -------------------------------------------------------------------------------- /js/components/sound/Music.js: -------------------------------------------------------------------------------- 1 | var soundcloud = require('soundcloud-badge'); 2 | 3 | var Music = function( poem, properties ) { 4 | 5 | if(window.location.hash === "#musicoff") return; 6 | 7 | var audio; 8 | var alive = true; 9 | 10 | soundcloud({ 11 | client_id: '6057c9af862bf245d4c402179e317f52', 12 | song: properties.url, 13 | dark: false, 14 | getFonts: false 15 | }, function(err, src, data, div) { 16 | 17 | if( !alive ) return; 18 | if( err ) throw err; 19 | 20 | audio = new Audio(); 21 | audio.src = src; 22 | audio.play(); 23 | audio.loop = true; 24 | audio.volume = properties.volume || 0.6; 25 | 26 | $(audio).on('loadedmetadata', function() { 27 | audio.currentTime = properties.startTime || 0; 28 | }); 29 | 30 | var playing = true; 31 | 32 | $(window).on('keydown.Music', function(e) { 33 | if( e.keyCode !== 83 ) return; 34 | if( playing ) { 35 | audio.pause(); 36 | playing = false; 37 | } else { 38 | audio.play(); 39 | playing = true; 40 | } 41 | }); 42 | }); 43 | 44 | poem.emitter.on('destroy', function() { 45 | if(audio) { 46 | audio.pause(); 47 | audio = null; 48 | } 49 | $(window).off('keydown.Music'); 50 | $('.npm-scb-white').remove(); 51 | }); 52 | 53 | }; 54 | 55 | module.exports = Music; 56 | -------------------------------------------------------------------------------- /js/components/utils/Stats.js: -------------------------------------------------------------------------------- 1 | var MrDoobStats = require('../../vendor/Stats'); 2 | 3 | var Stats = function( poem ) { 4 | 5 | this.poem = poem; 6 | 7 | this.stats = new MrDoobStats(); 8 | this.stats.domElement.style.position = 'absolute'; 9 | this.stats.domElement.style.top = '0px'; 10 | $( this.poem.div ).append( this.stats.domElement ); 11 | 12 | this.poem.emitter.on( 'update', this.stats.update.bind( this.stats ) ); 13 | 14 | }; 15 | 16 | module.exports = Stats; -------------------------------------------------------------------------------- /js/components/utils/drag-scroll.js: -------------------------------------------------------------------------------- 1 | var Lerp = require('lerp') 2 | 3 | function _getWheelEventName() { 4 | 5 | if( "onwheel" in document.createElement("div") ) { 6 | return "wheel" 7 | } else if( document.onmousewheel !== undefined ) { 8 | return "mousewheel" 9 | } else { 10 | return "DOMMouseScroll" 11 | } 12 | } 13 | 14 | module.exports = function dragScroll( poem, properties ) { 15 | 16 | var config = _.extend({ 17 | distance : 0.1, 18 | resetSpeed : 0.05, 19 | center : poem.camera.object.position.clone() 20 | }, properties) 21 | 22 | var current = { 23 | center : config.center.clone() 24 | } 25 | 26 | poem.canvas.addEventListener( _getWheelEventName(), function handleMouseWheel(e) { 27 | current.center.y += config.distance * -e.deltaY 28 | current.center.x += config.distance * e.deltaX * 5 29 | 30 | }, false ); 31 | 32 | poem.emitter.on('update', function updateDragScroll() { 33 | current.center.y = Lerp( 34 | current.center.y, 35 | config.center.y, 36 | config.resetSpeed 37 | ) 38 | current.center.x = Lerp( 39 | current.center.x, 40 | config.center.x, 41 | config.resetSpeed 42 | ) 43 | current.center.z = Lerp( 44 | current.center.z, 45 | config.center.z, 46 | config.resetSpeed 47 | ) 48 | 49 | poem.camera.object.position.copy( current.center ) 50 | }) 51 | } -------------------------------------------------------------------------------- /js/core/manifestToPoem.js: -------------------------------------------------------------------------------- 1 | var createManifestLoader = require('poem-manifests'); 2 | var EventEmitter = require('events').EventEmitter; 3 | 4 | var _emitter = new EventEmitter(); 5 | var _loader = null; 6 | 7 | var init = function( createPoemGraph, manifests ) { 8 | 9 | _loader = createManifestLoader( manifests, { 10 | emitter : _emitter, 11 | getGraph : function( manifest, slug ) { return createPoemGraph( manifest, _emitter ); }, 12 | globalManifest : {} 13 | }); 14 | 15 | _emitter.on('load', function( e ) { 16 | window.poem = e.graph; 17 | }); 18 | 19 | }; 20 | 21 | var load = function( slug ) { 22 | return _loader.load( slug ); 23 | }; 24 | 25 | module.exports = { 26 | init : init, 27 | load : load, 28 | emitter : _emitter 29 | }; 30 | -------------------------------------------------------------------------------- /js/core/poem.js: -------------------------------------------------------------------------------- 1 | var Camera = require('../components/cameras/Camera') 2 | var CreateLoop = require('poem-loop') 3 | 4 | const RATIO = _.isNumber( window.devicePixelRatio ) ? window.devicePixelRatio : 1 5 | 6 | function _createFog( scene, properties, cameraPositionZ ) { 7 | 8 | var config = _.extend({ 9 | color : 0x222222, 10 | nearFactor : 0.5, 11 | farFactor : 2 12 | }, properties ) 13 | 14 | scene.fog = new THREE.Fog( 15 | config.color, 16 | cameraPositionZ * config.nearFactor, 17 | cameraPositionZ * config.farFactor 18 | ) 19 | 20 | } 21 | 22 | function _startAfterPromises( poem ) { 23 | 24 | var promisesUnfiltered = _.map( poem, function( component ) { 25 | return _.isObject( component ) ? component.promise : undefined 26 | }) 27 | var promises = _.filter(promisesUnfiltered, function( component ) { 28 | return !_.isUndefined( component ) 29 | }) 30 | 31 | Promise.all( promises ).then( 32 | function() { 33 | poem.emitter.emit('promises') 34 | poem.loop.start() 35 | }, 36 | console.log.bind(console) 37 | ) 38 | } 39 | 40 | module.exports = function createPoem( manifest, loaderEmitter ) { 41 | 42 | var config = _.extend({ 43 | camera : null, 44 | fog : null, 45 | renderer : null 46 | }, manifest.config) 47 | 48 | var poem = {} 49 | var loop = CreateLoop() 50 | var emitter = loop.emitter // Steal the emitter for the poem 51 | 52 | var scene = new THREE.Scene() 53 | var camera = new Camera( config.camera, scene, emitter ) 54 | 55 | _createFog( scene, config.fog, camera.object.position.z ) 56 | 57 | // Renderer( config.renderer, scene, camera.object, emitter ) 58 | 59 | loaderEmitter.once( 'load', _.partial( _startAfterPromises, poem ) ) 60 | 61 | loaderEmitter.on( 'unload', function() { 62 | loop.stop() 63 | emitter.emit('destroy') 64 | }) 65 | 66 | return _.extend( poem, { 67 | emitter : emitter, 68 | canvas : null, 69 | scene : scene, 70 | ratio : RATIO, 71 | camera : camera, 72 | $div : $("#container"), 73 | loop : loop, 74 | start : loop.start, 75 | stop : loop.stop 76 | }) 77 | } -------------------------------------------------------------------------------- /js/core/routing.js: -------------------------------------------------------------------------------- 1 | var crossroads = require('crossroads'); 2 | var hasher = require('hasher'); 3 | var manifestToPoem = require('./manifestToPoem'); 4 | 5 | var _baseUrl = '/sandbox'; 6 | var _defaultLevel 7 | 8 | var routing = { 9 | 10 | start : function( Poem, manifests ) { 11 | 12 | _defaultLevel = _.first( _.keys( manifests ) ) 13 | 14 | manifestToPoem.init( Poem, manifests ); 15 | 16 | function parseHash( newHash, oldHash ){ 17 | crossroads.parse( newHash ); 18 | } 19 | 20 | crossroads.addRoute( '/', routing.showMainTitles ); 21 | crossroads.addRoute( '/{name}', routing.loadUpALevel ); 22 | 23 | crossroads.addRoute( /.*/, function reRouteToMainTitlesIfNoMatch() { 24 | hasher.replaceHash(''); 25 | }); 26 | 27 | hasher.initialized.add(parseHash); // parse initial hash 28 | hasher.changed.add(parseHash); //parse hash changes 29 | hasher.init(); //start listening for history change 30 | 31 | }, 32 | 33 | showMainTitles : function() { 34 | 35 | _gaq.push( [ '_trackPageview', _baseUrl ] ); 36 | 37 | manifestToPoem.load( _defaultLevel ); 38 | 39 | }, 40 | 41 | loadUpALevel : function( levelName ) { 42 | 43 | _gaq.push( [ '_trackPageview', _baseUrl+'/#level/'+levelName ] ); 44 | 45 | var levelFound = manifestToPoem.load( levelName ); 46 | 47 | if( !levelFound ) { 48 | manifestToPoem.load( _defaultLevel ); 49 | } 50 | 51 | } 52 | 53 | }; 54 | 55 | module.exports = routing; -------------------------------------------------------------------------------- /js/core/ui.js: -------------------------------------------------------------------------------- 1 | var poemMenu = require('poem-menu'); 2 | var routing = require('./routing'); 3 | var mute = require('../sound/mute'); 4 | var manifestToPoem = require('./manifestToPoem'); 5 | 6 | window.mute = mute; 7 | 8 | function handlers( menu ) { 9 | 10 | var poem; 11 | 12 | manifestToPoem.emitter.on( 'load', function( e ) { 13 | poem = e.graph; 14 | }); 15 | 16 | menu.emitter.on('close', function() { 17 | if( poem ) poem.start(); 18 | }); 19 | 20 | menu.emitter.on('open', function() { 21 | if( poem ) poem.stop(); 22 | }); 23 | 24 | } 25 | 26 | //Start 27 | 28 | module.exports = function startUI( manifests ) { 29 | 30 | var menu = poemMenu( manifests, { 31 | top: "Three.js Sandbox", 32 | bottom : mute.el 33 | }); 34 | 35 | handlers( menu ); 36 | 37 | }; -------------------------------------------------------------------------------- /js/demos/EndlessTerrain/credits.js: -------------------------------------------------------------------------------- 1 | var LoadImage = require('../../utils/loadImage') 2 | 3 | var internals = { 4 | 5 | createTexture : function( video ) { 6 | 7 | var canvas = document.createElement( 'canvas' ) 8 | canvas.width = 1024 9 | canvas.height = 256 10 | 11 | var ctx2d = canvas.getContext( '2d' ) 12 | 13 | var texture = new THREE.Texture( canvas ) 14 | texture.minFilter = THREE.LinearFilter 15 | texture.magFilter = THREE.LinearFilter 16 | 17 | return [ canvas, ctx2d, texture ] 18 | }, 19 | 20 | createVideo : function() { 21 | 22 | return new Promise(function( resolve, reject ) { 23 | 24 | var video = document.createElement( 'video' ) 25 | var $video = $(video) 26 | 27 | // video.muted = true 28 | video.controls = false 29 | video.loop = false 30 | 31 | video.src = video.canPlayType("video/mp4") ? 32 | "assets/video/gene.sys.mp4" : 33 | "assets/video/gene.sys.webm" 34 | 35 | video.load() 36 | 37 | $(video).on('canplaythrough', () => { resolve( video ) }) 38 | $(video).on('error, stalled, abort', (e) => { reject( e.originalEvent ) }) 39 | }) 40 | 41 | }, 42 | 43 | createMesh : function( poem, texture, canvas ) { 44 | 45 | var mesh = new THREE.Mesh( 46 | new THREE.PlaneGeometry( canvas.width, canvas.height ), 47 | new THREE.MeshBasicMaterial({ 48 | color: 0xffffff 49 | , transparent: true 50 | , side: THREE.DoubleSide 51 | // , map: texture 52 | , alphaMap: texture 53 | }) 54 | ) 55 | return mesh 56 | }, 57 | 58 | updateFn : function( mesh, ctx2d, video, texture ) { 59 | 60 | return function() { 61 | 62 | if ( video.readyState === video.HAVE_ENOUGH_DATA && video.ended === false ) { 63 | 64 | ctx2d.drawImage( video, 0, 0 ) 65 | texture.needsUpdate = true 66 | } 67 | } 68 | }, 69 | 70 | add : ( cameraObj, mesh, video, update ) => { 71 | 72 | mesh.scale.set(0.005, 0.005, 0.005) 73 | mesh.position.z = -10 74 | mesh.position.y = 0.2 75 | cameraObj.add( mesh ) 76 | 77 | setTimeout(function() { 78 | console.warn('TODO: remove setTimeout') 79 | video.currentTime = 0 80 | video.play() 81 | 82 | poem.emitter.on( 'update', update ) 83 | 84 | }, 2000) 85 | }, 86 | 87 | remove : ( cameraObj, mesh, video, update ) => { 88 | 89 | cameraObj.remove( mesh ) 90 | video.pause(0) 91 | 92 | 93 | poem.emitter.removeListener( 'update', update ) 94 | } 95 | 96 | } 97 | 98 | module.exports = function( poem ) { 99 | 100 | var api = { 101 | promise : internals.createVideo() 102 | } 103 | 104 | api.promise.then( function( video ) { 105 | 106 | var [ canvas, ctx2d, texture ] = internals.createTexture( video ) 107 | var mesh = internals.createMesh( poem, texture, canvas ) 108 | 109 | var update = internals.updateFn( mesh, ctx2d, video, texture ) 110 | 111 | _.extend( api, { 112 | mesh : mesh 113 | , canvas : canvas 114 | , ctx2d : ctx2d 115 | , texture : texture 116 | , video : video 117 | , add : _.partial( internals.add, poem.camera.object, mesh, video, update ) 118 | , remove : _.partial( internals.remove, poem.camera.object, mesh, video, update ) 119 | }) 120 | }) 121 | 122 | return api 123 | } -------------------------------------------------------------------------------- /js/demos/EndlessTerrain/endless.frag: -------------------------------------------------------------------------------- 1 | #pragma glslify: hsv2rgb = require(glsl-hsv2rgb) 2 | uniform float width; 3 | uniform float heightFactor; 4 | 5 | varying float height; 6 | varying vec2 vUv; 7 | varying float vCameraDistance; 8 | 9 | void main() { 10 | 11 | float hueX = abs(0.5 - fract(vUv.x * 0.8)) * 2.0; 12 | float hueY = abs(0.5 - fract(vUv.y * 0.63)) * 2.0; 13 | 14 | gl_FragColor = vec4( 15 | hsv2rgb( 16 | vec3( 17 | // mod(xHue, 1.0), 18 | (hueX + hueY) * 0.2 + 0.3, 19 | mix(heightFactor, mix(height, 0.5, 0.8), 0.8), 20 | mix(heightFactor, mix(height, 1.2, 0.35), 0.35) 21 | ) 22 | ), 23 | 1.0 24 | ); 25 | 26 | float fogFactor = smoothstep( 0.0, 1.0, vCameraDistance / width ); 27 | vec3 fogColor = vec3( 0.14, 0.14, 0.14 ); 28 | 29 | gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor ); 30 | 31 | } -------------------------------------------------------------------------------- /js/demos/EndlessTerrain/endless.vert: -------------------------------------------------------------------------------- 1 | uniform sampler2D terrain; 2 | uniform float heightFactor; 3 | uniform float width; 4 | 5 | varying float height; 6 | varying vec2 vUv; 7 | varying float vCameraDistance; 8 | 9 | void main() { 10 | 11 | vec4 modelPosition = modelMatrix * vec4(position, 1.0); 12 | 13 | vUv = vec2( modelPosition.x, modelPosition.z ) / width; 14 | 15 | height = texture2D( terrain, vUv * 0.3 ).w; 16 | 17 | vCameraDistance = distance( modelPosition.xyz, cameraPosition ); 18 | 19 | 20 | vec4 modifiedPosition = vec4( 21 | position.x, 22 | position.y + height * width / 20.0 * heightFactor, 23 | position.z, 24 | 1.0 25 | ); 26 | 27 | gl_Position = projectionMatrix * modelViewMatrix * modifiedPosition; 28 | 29 | } -------------------------------------------------------------------------------- /js/demos/EndlessTerrain/keyframes.js: -------------------------------------------------------------------------------- 1 | var CubicBezier = require('cubic-bezier') 2 | var QuickIn = CubicBezier(.12,.51,.8,.85, 32) 3 | var Pi = Math.PI 4 | var HalfPi = Math.PI / 2 5 | 6 | module.exports = { 7 | loop : true, 8 | speed : 1, 9 | keyframes : [ 10 | { 11 | duration: 15, 12 | easing: QuickIn, 13 | actions: [ 14 | [ "camera.object.position.x", [ 0, 0 ] ], 15 | [ "camera.object.position.y", [ -250, 0 ] ], 16 | [ "camera.object.position.z", [ 0, -5000 ] ], 17 | [ "camera.setAndUpdateFov", [ 5, 30 ] ], 18 | [ "endlessTerrain.height", [ 0, 1 ] ], 19 | [ "restrictedCamera.rotation.x", [ -0.3, 0 ] ], 20 | [ "restrictedCamera.rotation.y", [ -0.3, 0.1 ] ], 21 | 22 | [ "restrictedCamera.rotateAll", { x:-0.3, y:-0.3, z:0 }], 23 | 24 | [ "credits.mesh.position.z", [ -30, -10 ] ], 25 | [ "credits.add", {} ] 26 | 27 | ] 28 | }, 29 | { 30 | duration: 10, 31 | easing: "linear", 32 | isolate: false, 33 | startHere: false, 34 | actions: [ 35 | [ "credits.remove", {} ], 36 | 37 | [ "camera.object.position.x", [ 0, 0 ] ], 38 | [ "camera.object.position.y", [ 0, 0 ] ], 39 | [ "camera.object.position.z", [ -5000, -5700 ] ], 40 | [ "camera.setAndUpdateFov", [ 70, 40 ] ], 41 | 42 | [ "restrictedCamera.rotateAll", { x:-0.1, y:HalfPi, z: 0 }] 43 | ] 44 | }, 45 | { 46 | duration: 13, 47 | easing: "linear", 48 | isolate: false, 49 | actions: [ 50 | [ "camera.object.position.x", 600 ], 51 | [ "camera.object.position.y", [ 0, 0 ] ], 52 | [ "camera.object.position.z", [ -5700, -6000 ] ], 53 | [ "camera.setAndUpdateFov", [ 100, 50 ] ], 54 | 55 | [ "restrictedCamera.rotateAll", { x:-Pi*0.5, y:0, z: 0 }], 56 | 57 | [ "restrictedCamera.rotation.x", [ -Pi*0.5, 0 ] ] 58 | 59 | ] 60 | }, 61 | { 62 | duration: 10, 63 | easing: "linear", 64 | isolate: false, 65 | actions: [ 66 | [ "camera.object.position.x", 600 ], 67 | [ "camera.object.position.y", [ 0, 0 ] ], 68 | [ "camera.object.position.z", [ -5700, -6400 ] ], 69 | 70 | [ "restrictedCamera.rotateAll", { x:0, y:Pi, z: 0 }], 71 | 72 | // [ "restrictedCamera.rotation.x", [ -0.2, 0.2 ] ] 73 | 74 | ] 75 | } 76 | ] 77 | } -------------------------------------------------------------------------------- /js/demos/Grid.js: -------------------------------------------------------------------------------- 1 | var random = require('../utils/random'); 2 | 3 | var Grid = function( poem, properties ) { 4 | 5 | this.poem = poem; 6 | 7 | var lineMaterial = new THREE.LineBasicMaterial( { color: 0x303030 } ), 8 | geometry = new THREE.Geometry(), 9 | floor = -75, step = 25; 10 | 11 | for ( var i = 0; i <= 40; i ++ ) { 12 | 13 | geometry.vertices.push( new THREE.Vector3( - 500, floor, i * step - 500 ) ); 14 | geometry.vertices.push( new THREE.Vector3( 500, floor, i * step - 500 ) ); 15 | 16 | geometry.vertices.push( new THREE.Vector3( i * step - 500, floor, -500 ) ); 17 | geometry.vertices.push( new THREE.Vector3( i * step - 500, floor, 500 ) ); 18 | 19 | } 20 | 21 | this.grid = new THREE.Line( geometry, lineMaterial, THREE.LinePieces ); 22 | this.poem.scene.add( this.grid ); 23 | 24 | }; 25 | 26 | module.exports = Grid; -------------------------------------------------------------------------------- /js/demos/MeshGroupBoxDemo/index.js: -------------------------------------------------------------------------------- 1 | var MeshGroup = require('./MeshGroup') 2 | , random = require('../../utils/random') 3 | , twoPi = Math.PI * 2; 4 | 5 | var MeshGroupBoxDemo = function( poem, properties ) { 6 | 7 | this.poem = poem; 8 | 9 | this.count = 10000; 10 | 11 | this.poem.emitter.on('update', this.update.bind(this) ); 12 | 13 | this.group = new MeshGroup( poem ); 14 | 15 | this.boxes = this.generateBoxes( this.group ); 16 | 17 | this.group.build( poem.scene ); 18 | 19 | }; 20 | 21 | module.exports = MeshGroupBoxDemo; 22 | 23 | MeshGroupBoxDemo.prototype = { 24 | 25 | generateBoxes : function( group ) { 26 | 27 | var boxes = []; 28 | 29 | var geometry = new THREE.BoxGeometry( 1, 1, 1 ); 30 | var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); 31 | var box; 32 | 33 | var i = this.count; while (i--) { 34 | 35 | box = new THREE.Mesh( new THREE.BoxGeometry( 1, 1, 1 ) ); 36 | 37 | box.position.x = random.range( -100, 100 ); 38 | box.position.y = random.range( -100, 100 ); 39 | box.position.z = random.range( -100, 100 ); 40 | 41 | box.rotation.x = random.range( -twoPi, twoPi ); 42 | box.rotation.y = random.range( -twoPi, twoPi ); 43 | box.rotation.z = random.range( -twoPi, twoPi ); 44 | 45 | box.velocity = new THREE.Vector3( 46 | 47 | random.range( -1, 1 ), 48 | random.range( -1, 1 ), 49 | random.range( -1, 1 ) 50 | 51 | ).multiplyScalar(0.1); 52 | 53 | box.spin = new THREE.Vector3( 54 | 55 | random.range( -twoPi, twoPi ), 56 | random.range( -twoPi, twoPi ), 57 | random.range( -twoPi, twoPi ) 58 | 59 | ).multiplyScalar(0.01); 60 | 61 | box.scale.multiplyScalar( random.range( 1, 2) ); 62 | 63 | box.updateMatrix(); 64 | 65 | boxes.push( box ); 66 | 67 | group.add( box ); 68 | 69 | } 70 | 71 | return boxes; 72 | 73 | }, 74 | 75 | update : function( e ) { 76 | 77 | var box; 78 | 79 | for( var i = 0; i < this.count; i++ ) { 80 | 81 | box = this.boxes[i]; 82 | 83 | box.position.add( box.velocity ); 84 | 85 | box.rotation.x += box.spin.x; 86 | box.rotation.y += box.spin.y; 87 | box.rotation.z += box.spin.z; 88 | 89 | box.updateMatrix(); 90 | 91 | } 92 | 93 | } 94 | 95 | }; -------------------------------------------------------------------------------- /js/demos/MeshGroupBoxDemo/shader.frag: -------------------------------------------------------------------------------- 1 | uniform sampler2D texture; 2 | 3 | void main() { 4 | 5 | // gl_FragColor = texture2D( texture, gl_PointCoord ); 6 | 7 | gl_FragColor = vec4( 1.0, 1.0, 1.0, 1.0 ); 8 | 9 | } -------------------------------------------------------------------------------- /js/demos/MeshGroupBoxDemo/shader.vert: -------------------------------------------------------------------------------- 1 | attribute float size; 2 | attribute float transformMatrixIndex; 3 | 4 | uniform float time; 5 | uniform sampler2D texture; 6 | uniform sampler2D matricesTexture; 7 | uniform float matricesTextureWidth; 8 | 9 | vec3 wave; 10 | 11 | mat4 getMatrixFromTexture( const in float i ) { 12 | 13 | float j = i * 4.0; 14 | float x = mod( j, float( matricesTextureWidth ) ); 15 | float y = floor( j / float( matricesTextureWidth ) ); 16 | 17 | float dx = 1.0 / float( matricesTextureWidth ); 18 | float dy = 1.0 / float( matricesTextureWidth ); 19 | 20 | y = dy * ( y + 0.5 ); 21 | 22 | vec4 v1 = texture2D( matricesTexture, vec2( dx * ( x + 0.5 ), y ) ); 23 | vec4 v2 = texture2D( matricesTexture, vec2( dx * ( x + 1.5 ), y ) ); 24 | vec4 v3 = texture2D( matricesTexture, vec2( dx * ( x + 2.5 ), y ) ); 25 | vec4 v4 = texture2D( matricesTexture, vec2( dx * ( x + 3.5 ), y ) ); 26 | 27 | return mat4( v1, v2, v3, v4 ); 28 | 29 | // Debug: 30 | // return mat4( 31 | // 1.0, 0.0, 0.0, 0.0, 32 | // 0.0, 1.0, 0.0, 0.0, 33 | // 0.0, 0.0, 1.0, 0.0, 34 | // 0.0, 0.0, 0.0, 1.0 35 | // ); 36 | } 37 | 38 | void main() { 39 | 40 | mat4 transformMatrix = getMatrixFromTexture( transformMatrixIndex ); 41 | 42 | vec4 mvPosition = modelViewMatrix * transformMatrix * vec4( position, 1.0 ); 43 | 44 | gl_PointSize = 300.0 / length( mvPosition.xyz ); 45 | 46 | gl_Position = projectionMatrix * mvPosition; 47 | 48 | } -------------------------------------------------------------------------------- /js/demos/TexturePositionalMatrices/shader.frag: -------------------------------------------------------------------------------- 1 | uniform vec3 color; 2 | uniform sampler2D texture; 3 | 4 | varying vec3 vColor; 5 | 6 | void main() { 7 | 8 | gl_FragColor = vec4( color * vColor, 1.0 ); 9 | 10 | gl_FragColor = gl_FragColor * texture2D( texture, gl_PointCoord ); 11 | 12 | } -------------------------------------------------------------------------------- /js/demos/TexturePositionalMatrices/shader.vert: -------------------------------------------------------------------------------- 1 | attribute float size; 2 | attribute vec3 customColor; 3 | attribute float transformIndex; 4 | 5 | uniform float time; 6 | uniform sampler2D texture; 7 | uniform sampler2D matricesTexture; 8 | uniform float matricesTextureSize; 9 | 10 | varying vec3 vColor; 11 | 12 | vec3 wave; 13 | 14 | mat4 getMatrixFromTexture( const in float i ) { 15 | 16 | float j = i * 4.0; 17 | float x = mod( j, float( matricesTextureSize ) ); 18 | float y = floor( j / float( matricesTextureSize ) ); 19 | 20 | float dx = 1.0 / float( matricesTextureSize ); 21 | float dy = 1.0 / float( matricesTextureSize ); 22 | 23 | y = dy * ( y + 0.5 ); 24 | 25 | vec4 v1 = texture2D( matricesTexture, vec2( dx * ( x + 0.5 ), y ) ); 26 | vec4 v2 = texture2D( matricesTexture, vec2( dx * ( x + 1.5 ), y ) ); 27 | vec4 v3 = texture2D( matricesTexture, vec2( dx * ( x + 2.5 ), y ) ); 28 | vec4 v4 = texture2D( matricesTexture, vec2( dx * ( x + 3.5 ), y ) ); 29 | 30 | return mat4( v1, v2, v3, v4 ); 31 | 32 | } 33 | 34 | void main() { 35 | 36 | vColor = customColor; 37 | 38 | mat4 transformMatrix = getMatrixFromTexture( transformIndex ); 39 | 40 | vec4 mvPosition = modelViewMatrix * transformMatrix * vec4( position, 1.0 ); 41 | 42 | gl_PointSize = size * ( 300.0 / length( mvPosition.xyz ) ); 43 | 44 | gl_Position = projectionMatrix * mvPosition; 45 | 46 | } -------------------------------------------------------------------------------- /js/demos/UniformPositionalMatrices/shader.frag: -------------------------------------------------------------------------------- 1 | uniform vec3 color; 2 | uniform sampler2D texture; 3 | 4 | varying vec3 vColor; 5 | 6 | void main() { 7 | 8 | gl_FragColor = vec4( color * vColor, 1.0 ); 9 | 10 | gl_FragColor = gl_FragColor * texture2D( texture, gl_PointCoord ); 11 | 12 | } -------------------------------------------------------------------------------- /js/demos/UniformPositionalMatrices/shader.vert: -------------------------------------------------------------------------------- 1 | 2 | attribute float size; 3 | attribute vec3 customColor; 4 | attribute float transformIndex; 5 | 6 | uniform float time; 7 | uniform mat4 transformMatrix[ TRANSFORM_MATRIX_COUNT ]; 8 | 9 | varying vec3 vColor; 10 | 11 | vec3 wave; 12 | 13 | void main() { 14 | 15 | vColor = customColor; 16 | 17 | wave = position; 18 | 19 | wave.y += sin( (position.x / (10.0 + transformIndex) ) + ( time / 150.0 ) ) * 2.0; 20 | wave.y += sin( (position.z / (12.0 + transformIndex) ) + ( time / 160.0 ) ) * 2.0; 21 | wave.y += sin( (position.x / (30.0 + transformIndex) ) + ( time / 120.0 ) ) * 5.0; 22 | wave.y += sin( (position.z / (31.0 + transformIndex) ) + ( time / 130.0 ) ) * 5.0; 23 | 24 | vec4 mvPosition = modelViewMatrix * transformMatrix[ int(transformIndex) ] * vec4( wave, 1.0 ); 25 | 26 | gl_PointSize = size * ( 300.0 / length( mvPosition.xyz ) ); 27 | 28 | gl_Position = projectionMatrix * mvPosition; 29 | 30 | } -------------------------------------------------------------------------------- /js/demos/sine-gravity-cloud/sine.frag: -------------------------------------------------------------------------------- 1 | uniform vec3 color; 2 | uniform sampler2D texture; 3 | 4 | varying vec3 vColor; 5 | 6 | void main() { 7 | 8 | gl_FragColor = vec4( color * vColor, 1.0 ); 9 | 10 | gl_FragColor = gl_FragColor * texture2D( texture, gl_PointCoord ); 11 | 12 | } -------------------------------------------------------------------------------- /js/demos/sine-gravity-cloud/sine.vert: -------------------------------------------------------------------------------- 1 | attribute float size; 2 | attribute vec3 customColor; 3 | 4 | varying vec3 vColor; 5 | 6 | void main() { 7 | 8 | vColor = customColor; 9 | 10 | vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 ); 11 | 12 | gl_PointSize = size * ( 300.0 / length( mvPosition.xyz ) ); 13 | 14 | gl_Position = projectionMatrix * mvPosition; 15 | 16 | } -------------------------------------------------------------------------------- /js/demos/wire-terrain/credits.js: -------------------------------------------------------------------------------- 1 | var LoadImage = require('../../utils/loadImage') 2 | 3 | var internals = { 4 | 5 | createTexture : function( video ) { 6 | 7 | var canvas = document.createElement( 'canvas' ) 8 | canvas.width = 1024 9 | canvas.height = 256 10 | 11 | var ctx2d = canvas.getContext( '2d' ) 12 | 13 | var texture = new THREE.Texture( canvas ) 14 | texture.minFilter = THREE.LinearFilter 15 | texture.magFilter = THREE.LinearFilter 16 | 17 | return [ canvas, ctx2d, texture ] 18 | }, 19 | 20 | createVideo : function() { 21 | 22 | return new Promise(function( resolve, reject ) { 23 | 24 | var video = document.createElement( 'video' ) 25 | var $video = $(video) 26 | 27 | // video.muted = true 28 | video.controls = false 29 | video.loop = false 30 | 31 | video.src = video.canPlayType("video/mp4") ? 32 | "assets/video/gene.sys.mp4" : 33 | "assets/video/gene.sys.webm" 34 | 35 | video.load() 36 | 37 | $(video).on('canplaythrough', () => { resolve( video ) }) 38 | $(video).on('error, stalled, abort', (e) => { reject( e.originalEvent ) }) 39 | }) 40 | 41 | }, 42 | 43 | createMesh : function( poem, texture, canvas ) { 44 | 45 | var mesh = new THREE.Mesh( 46 | new THREE.PlaneGeometry( canvas.width, canvas.height ), 47 | new THREE.MeshBasicMaterial({ 48 | color: 0xffffff 49 | , transparent: true 50 | , side: THREE.DoubleSide 51 | // , map: texture 52 | , alphaMap: texture 53 | }) 54 | ) 55 | return mesh 56 | }, 57 | 58 | updateFn : function( mesh, ctx2d, video, texture ) { 59 | 60 | return function() { 61 | 62 | if ( video.readyState === video.HAVE_ENOUGH_DATA && video.ended === false ) { 63 | 64 | ctx2d.drawImage( video, 0, 0 ) 65 | texture.needsUpdate = true 66 | } 67 | } 68 | }, 69 | 70 | add : ( cameraObj, mesh, video, update ) => { 71 | 72 | mesh.scale.set(0.005, 0.005, 0.005) 73 | mesh.position.z = -10 74 | mesh.position.y = 0.2 75 | cameraObj.add( mesh ) 76 | 77 | setTimeout(function() { 78 | console.warn('TODO: remove setTimeout') 79 | video.currentTime = 0 80 | video.play() 81 | 82 | poem.emitter.on( 'update', update ) 83 | 84 | }, 2000) 85 | }, 86 | 87 | remove : ( cameraObj, mesh, video, update ) => { 88 | 89 | cameraObj.remove( mesh ) 90 | video.pause(0) 91 | 92 | 93 | poem.emitter.removeListener( 'update', update ) 94 | } 95 | 96 | } 97 | 98 | module.exports = function( poem ) { 99 | 100 | var api = { 101 | promise : internals.createVideo() 102 | } 103 | 104 | api.promise.then( function( video ) { 105 | 106 | var [ canvas, ctx2d, texture ] = internals.createTexture( video ) 107 | var mesh = internals.createMesh( poem, texture, canvas ) 108 | 109 | var update = internals.updateFn( mesh, ctx2d, video, texture ) 110 | 111 | _.extend( api, { 112 | mesh : mesh 113 | , canvas : canvas 114 | , ctx2d : ctx2d 115 | , texture : texture 116 | , video : video 117 | , add : _.partial( internals.add, poem.camera.object, mesh, video, update ) 118 | , remove : _.partial( internals.remove, poem.camera.object, mesh, video, update ) 119 | }) 120 | }) 121 | 122 | return api 123 | } -------------------------------------------------------------------------------- /js/demos/wire-terrain/keyframes.js: -------------------------------------------------------------------------------- 1 | var CubicBezier = require('cubic-bezier') 2 | var QuickIn = CubicBezier(.12,.51,.8,.85, 32) 3 | var Pi = Math.PI 4 | var HalfPi = Math.PI / 2 5 | 6 | module.exports = { 7 | loop : true, 8 | speed : 1, 9 | keyframes : [ 10 | { 11 | duration: 15, 12 | easing: QuickIn, 13 | actions: [ 14 | [ "camera.object.position.x", [ 0, 0 ] ], 15 | [ "camera.object.position.y", [ -250, 0 ] ], 16 | [ "camera.object.position.z", [ 0, -5000 ] ], 17 | [ "camera.setAndUpdateFov", [ 5, 30 ] ], 18 | [ "endlessTerrain.height", [ 0, 1 ] ], 19 | [ "restrictedCamera.rotation.x", [ -0.3, 0 ] ], 20 | [ "restrictedCamera.rotation.y", [ -0.3, 0.1 ] ], 21 | 22 | [ "restrictedCamera.rotateAll", { x:-0.3, y:-0.3, z:0 }], 23 | 24 | [ "credits.mesh.position.z", [ -30, -10 ] ], 25 | [ "credits.add", {} ] 26 | 27 | ] 28 | }, 29 | { 30 | duration: 10, 31 | easing: "linear", 32 | isolate: false, 33 | startHere: false, 34 | actions: [ 35 | [ "credits.remove", {} ], 36 | 37 | [ "camera.object.position.x", [ 0, 0 ] ], 38 | [ "camera.object.position.y", [ 0, 0 ] ], 39 | [ "camera.object.position.z", [ -5000, -5700 ] ], 40 | [ "camera.setAndUpdateFov", [ 70, 40 ] ], 41 | 42 | [ "restrictedCamera.rotateAll", { x:-0.1, y:HalfPi, z: 0 }] 43 | ] 44 | }, 45 | { 46 | duration: 13, 47 | easing: "linear", 48 | isolate: false, 49 | actions: [ 50 | [ "camera.object.position.x", 600 ], 51 | [ "camera.object.position.y", [ 0, 0 ] ], 52 | [ "camera.object.position.z", [ -5700, -6000 ] ], 53 | [ "camera.setAndUpdateFov", [ 100, 50 ] ], 54 | 55 | [ "restrictedCamera.rotateAll", { x:-Pi*0.5, y:0, z: 0 }], 56 | 57 | [ "restrictedCamera.rotation.x", [ -Pi*0.5, 0 ] ] 58 | 59 | ] 60 | }, 61 | { 62 | duration: 10, 63 | easing: "linear", 64 | isolate: false, 65 | actions: [ 66 | [ "camera.object.position.x", 600 ], 67 | [ "camera.object.position.y", [ 0, 0 ] ], 68 | [ "camera.object.position.z", [ -5700, -6400 ] ], 69 | 70 | [ "restrictedCamera.rotateAll", { x:0, y:Pi, z: 0 }], 71 | 72 | // [ "restrictedCamera.rotation.x", [ -0.2, 0.2 ] ] 73 | 74 | ] 75 | } 76 | ] 77 | } -------------------------------------------------------------------------------- /js/demos/wire-terrain/terrain.frag: -------------------------------------------------------------------------------- 1 | #pragma glslify: hsv2rgb = require(glsl-hsv2rgb) 2 | uniform float width; 3 | uniform float heightFactor; 4 | uniform float elapsed; 5 | 6 | varying float height; 7 | varying vec2 vUv; 8 | varying float vCameraDistance; 9 | 10 | void main() { 11 | 12 | float hueX = abs(0.5 - fract(vUv.x * 2.0)) * 2.0; 13 | float hueY = abs(0.5 - fract(vUv.y * 2.0)) * 2.0; 14 | 15 | float waveSpeed = 0.0005; 16 | float waveLength = 0.0001; 17 | float wave = mod((vCameraDistance * waveLength + elapsed * waveSpeed), 1.0); 18 | 19 | gl_FragColor = vec4( 20 | hsv2rgb( 21 | vec3( 22 | // mod(xHue, 1.0), 23 | (hueX + hueY) * 0.1 + 0.25, 24 | mix(heightFactor, mix(height, 0.5, 0.8), 0.8), 25 | mix(heightFactor, mix(height, 1.2, 0.35), 0.35) 26 | ) 27 | ), 28 | 1.0 - wave + 0.2 29 | ); 30 | 31 | float fogFactor = smoothstep( 0.0, 1.0, vCameraDistance / width ); 32 | vec3 fogColor = vec3( 0.14, 0.14, 0.14 ); 33 | 34 | gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor ); 35 | 36 | } -------------------------------------------------------------------------------- /js/demos/wire-terrain/terrain.vert: -------------------------------------------------------------------------------- 1 | uniform sampler2D terrain; 2 | uniform float heightFactor; 3 | uniform float width; 4 | uniform float elapsed; 5 | 6 | varying float height; 7 | varying vec2 vUv; 8 | varying float vCameraDistance; 9 | 10 | #pragma glslify: snoise3 = require(glsl-noise/simplex/3d) 11 | 12 | void main() { 13 | 14 | vec4 modelPosition = modelMatrix * vec4(position, 1.0); 15 | 16 | vUv = vec2( modelPosition.x, modelPosition.z + elapsed * 0.05 ) / width; 17 | 18 | float mainHeightShape = texture2D( terrain, vUv * 0.3 ).w; 19 | float smallNoiseySurface = texture2D( terrain, vUv * 5.0 ).w; 20 | float amountOfSmallNoise = snoise3(vec3( 21 | modelPosition.x * 0.001 * sin( elapsed * 0.001 ), 22 | modelPosition.z * 0.001 * sin( elapsed * 0.001 ), 23 | elapsed * 0.0001 24 | )); 25 | 26 | height = mainHeightShape + ( 27 | smallNoiseySurface * smallNoiseySurface * amountOfSmallNoise 28 | ); 29 | 30 | vCameraDistance = distance( modelPosition.xyz, cameraPosition ); 31 | 32 | vec4 modifiedPosition = vec4( 33 | position.x, 34 | position.y + height * width / 20.0 * heightFactor, 35 | position.z, 36 | 1.0 37 | ); 38 | 39 | gl_Position = projectionMatrix * modelViewMatrix * modifiedPosition; 40 | 41 | } -------------------------------------------------------------------------------- /js/index.js: -------------------------------------------------------------------------------- 1 | require('./utils/ThreeConsole'); 2 | require('es6-promise').polyfill(); 3 | 4 | var manifests = require('../manifests'); 5 | 6 | var routing = require('./core/routing'); 7 | var ui = require('./core/ui')( manifests ); 8 | 9 | routing.start( 10 | require('./core/poem'), 11 | manifests 12 | ); -------------------------------------------------------------------------------- /js/postprocessing/BokehPass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Depth-of-field post-process with bokeh shader 3 | */ 4 | 5 | 6 | THREE.BokehPass = function ( scene, camera, params ) { 7 | 8 | this.scene = scene; 9 | this.camera = camera; 10 | 11 | var focus = ( params.focus !== undefined ) ? params.focus : 1.0; 12 | var aspect = ( params.aspect !== undefined ) ? params.aspect : camera.aspect; 13 | var aperture = ( params.aperture !== undefined ) ? params.aperture : 0.025; 14 | var maxblur = ( params.maxblur !== undefined ) ? params.maxblur : 1.0; 15 | 16 | // render targets 17 | 18 | var width = params.width || window.innerWidth || 1; 19 | var height = params.height || window.innerHeight || 1; 20 | 21 | this.renderTargetColor = new THREE.WebGLRenderTarget( width, height, { 22 | minFilter: THREE.LinearFilter, 23 | magFilter: THREE.LinearFilter, 24 | format: THREE.RGBFormat 25 | } ); 26 | 27 | this.renderTargetDepth = this.renderTargetColor.clone(); 28 | 29 | // depth material 30 | 31 | this.materialDepth = new THREE.MeshDepthMaterial(); 32 | 33 | // bokeh material 34 | 35 | if ( THREE.BokehShader === undefined ) { 36 | console.error( "THREE.BokehPass relies on THREE.BokehShader" ); 37 | } 38 | 39 | var bokehShader = THREE.BokehShader; 40 | var bokehUniforms = THREE.UniformsUtils.clone( bokehShader.uniforms ); 41 | 42 | bokehUniforms[ "tDepth" ].value = this.renderTargetDepth; 43 | 44 | bokehUniforms[ "focus" ].value = focus; 45 | bokehUniforms[ "aspect" ].value = aspect; 46 | bokehUniforms[ "aperture" ].value = aperture; 47 | bokehUniforms[ "maxblur" ].value = maxblur; 48 | 49 | this.materialBokeh = new THREE.ShaderMaterial({ 50 | uniforms: bokehUniforms, 51 | vertexShader: bokehShader.vertexShader, 52 | fragmentShader: bokehShader.fragmentShader 53 | }); 54 | 55 | this.uniforms = bokehUniforms; 56 | this.enabled = true; 57 | this.needsSwap = false; 58 | this.renderToScreen = false; 59 | this.clear = false; 60 | 61 | this.camera2 = new THREE.OrthographicCamera( -1, 1, 1, -1, 0, 1 ); 62 | this.scene2 = new THREE.Scene(); 63 | 64 | this.quad2 = new THREE.Mesh( new THREE.PlaneGeometry( 2, 2 ), null ); 65 | this.scene2.add( this.quad2 ); 66 | 67 | }; 68 | 69 | THREE.BokehPass.prototype = { 70 | 71 | render: function ( renderer, writeBuffer, readBuffer, delta, maskActive ) { 72 | 73 | this.quad2.material = this.materialBokeh; 74 | 75 | // Render depth into texture 76 | 77 | this.scene.overrideMaterial = this.materialDepth; 78 | 79 | renderer.render( this.scene, this.camera, this.renderTargetDepth, true ); 80 | 81 | // Render bokeh composite 82 | 83 | this.uniforms[ "tColor" ].value = readBuffer; 84 | 85 | if ( this.renderToScreen ) { 86 | 87 | renderer.render( this.scene2, this.camera2 ); 88 | 89 | } else { 90 | 91 | renderer.render( this.scene2, this.camera2, writeBuffer, this.clear ); 92 | 93 | } 94 | 95 | this.scene.overrideMaterial = null; 96 | 97 | } 98 | 99 | }; 100 | 101 | -------------------------------------------------------------------------------- /js/postprocessing/ChromaticAberration/chromatic.frag: -------------------------------------------------------------------------------- 1 | #pragma glslify: random = require(glsl-random) 2 | 3 | uniform float opacity; 4 | 5 | uniform sampler2D tDiffuse; 6 | 7 | varying vec2 vUv; 8 | 9 | void main() { 10 | 11 | vec2 unitI_ToSide = (vUv * 2.0 - 1.0); 12 | 13 | unitI_ToSide = pow(unitI_ToSide, vec2(3.0, 5.0)) * random(vUv) * -0.01; 14 | 15 | vec4 texel = texture2D( tDiffuse, vUv ); 16 | vec4 smallshift = texture2D( tDiffuse, vUv + unitI_ToSide * 0.5 ); 17 | vec4 bigshift = texture2D( tDiffuse, vUv + unitI_ToSide ); 18 | 19 | gl_FragColor = opacity * vec4( bigshift.x, texel.y, smallshift.z, texel.w ); 20 | 21 | } -------------------------------------------------------------------------------- /js/postprocessing/ChromaticAberration/chromatic.vert: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | 3 | void main() { 4 | 5 | vUv = uv; 6 | gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); 7 | 8 | } -------------------------------------------------------------------------------- /js/postprocessing/ChromaticAberration/index.js: -------------------------------------------------------------------------------- 1 | var glslify = require('glslify'); 2 | 3 | var chromaticAberrationShader = new THREE.ShaderMaterial({ 4 | vertexShader: glslify('./chromatic.vert'), 5 | fragmentShader: glslify('./chromatic.frag'), 6 | uniforms: { 7 | opacity: { type: 'f', value: 1 }, 8 | } 9 | }) 10 | 11 | module.exports = chromaticAberrationShader; 12 | -------------------------------------------------------------------------------- /js/postprocessing/DotScreenPass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.DotScreenPass = function ( center, angle, scale ) { 6 | 7 | if ( THREE.DotScreenShader === undefined ) 8 | console.error( "THREE.DotScreenPass relies on THREE.DotScreenShader" ); 9 | 10 | var shader = THREE.DotScreenShader; 11 | 12 | this.uniforms = THREE.UniformsUtils.clone( shader.uniforms ); 13 | 14 | if ( center !== undefined ) this.uniforms[ "center" ].value.copy( center ); 15 | if ( angle !== undefined ) this.uniforms[ "angle"].value = angle; 16 | if ( scale !== undefined ) this.uniforms[ "scale"].value = scale; 17 | 18 | this.material = new THREE.ShaderMaterial( { 19 | 20 | uniforms: this.uniforms, 21 | vertexShader: shader.vertexShader, 22 | fragmentShader: shader.fragmentShader 23 | 24 | } ); 25 | 26 | this.enabled = true; 27 | this.renderToScreen = false; 28 | this.needsSwap = true; 29 | 30 | 31 | this.camera = new THREE.OrthographicCamera( -1, 1, 1, -1, 0, 1 ); 32 | this.scene = new THREE.Scene(); 33 | 34 | this.quad = new THREE.Mesh( new THREE.PlaneGeometry( 2, 2 ), null ); 35 | this.scene.add( this.quad ); 36 | 37 | }; 38 | 39 | THREE.DotScreenPass.prototype = { 40 | 41 | render: function ( renderer, writeBuffer, readBuffer, delta ) { 42 | 43 | this.uniforms[ "tDiffuse" ].value = readBuffer; 44 | this.uniforms[ "tSize" ].value.set( readBuffer.width, readBuffer.height ); 45 | 46 | this.quad.material = this.material; 47 | 48 | if ( this.renderToScreen ) { 49 | 50 | renderer.render( this.scene, this.camera ); 51 | 52 | } else { 53 | 54 | renderer.render( this.scene, this.camera, writeBuffer, false ); 55 | 56 | } 57 | 58 | } 59 | 60 | }; 61 | -------------------------------------------------------------------------------- /js/postprocessing/EffectComposer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.EffectComposer = function ( renderer, renderTarget ) { 6 | 7 | this.renderer = renderer; 8 | 9 | if ( renderTarget === undefined ) { 10 | 11 | var width = window.innerWidth || 1; 12 | var height = window.innerHeight || 1; 13 | var parameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBuffer: false }; 14 | 15 | renderTarget = new THREE.WebGLRenderTarget( width, height, parameters ); 16 | 17 | } 18 | 19 | this.renderTarget1 = renderTarget; 20 | this.renderTarget2 = renderTarget.clone(); 21 | 22 | this.writeBuffer = this.renderTarget1; 23 | this.readBuffer = this.renderTarget2; 24 | 25 | this.passes = []; 26 | 27 | if ( THREE.CopyShader === undefined ) 28 | console.error( "THREE.EffectComposer relies on THREE.CopyShader" ); 29 | 30 | this.copyPass = new THREE.ShaderPass( THREE.CopyShader ); 31 | 32 | }; 33 | 34 | THREE.EffectComposer.prototype = { 35 | 36 | swapBuffers: function() { 37 | 38 | var tmp = this.readBuffer; 39 | this.readBuffer = this.writeBuffer; 40 | this.writeBuffer = tmp; 41 | 42 | }, 43 | 44 | addPass: function ( pass ) { 45 | 46 | this.passes.push( pass ); 47 | 48 | }, 49 | 50 | insertPass: function ( pass, index ) { 51 | 52 | this.passes.splice( index, 0, pass ); 53 | 54 | }, 55 | 56 | render: function ( delta ) { 57 | 58 | this.writeBuffer = this.renderTarget1; 59 | this.readBuffer = this.renderTarget2; 60 | 61 | var maskActive = false; 62 | 63 | var pass, i, il = this.passes.length; 64 | 65 | for ( i = 0; i < il; i ++ ) { 66 | 67 | pass = this.passes[ i ]; 68 | 69 | if ( !pass.enabled ) continue; 70 | 71 | pass.render( this.renderer, this.writeBuffer, this.readBuffer, delta, maskActive ); 72 | 73 | if ( pass.needsSwap ) { 74 | 75 | if ( maskActive ) { 76 | 77 | var context = this.renderer.context; 78 | 79 | context.stencilFunc( context.NOTEQUAL, 1, 0xffffffff ); 80 | 81 | this.copyPass.render( this.renderer, this.writeBuffer, this.readBuffer, delta ); 82 | 83 | context.stencilFunc( context.EQUAL, 1, 0xffffffff ); 84 | 85 | } 86 | 87 | this.swapBuffers(); 88 | 89 | } 90 | 91 | if ( pass instanceof THREE.MaskPass ) { 92 | 93 | maskActive = true; 94 | 95 | } else if ( pass instanceof THREE.ClearMaskPass ) { 96 | 97 | maskActive = false; 98 | 99 | } 100 | 101 | } 102 | 103 | }, 104 | 105 | reset: function ( renderTarget ) { 106 | 107 | if ( renderTarget === undefined ) { 108 | 109 | renderTarget = this.renderTarget1.clone(); 110 | 111 | renderTarget.width = window.innerWidth; 112 | renderTarget.height = window.innerHeight; 113 | 114 | } 115 | 116 | this.renderTarget1 = renderTarget; 117 | this.renderTarget2 = renderTarget.clone(); 118 | 119 | this.writeBuffer = this.renderTarget1; 120 | this.readBuffer = this.renderTarget2; 121 | 122 | }, 123 | 124 | setSize: function ( width, height ) { 125 | 126 | var renderTarget = this.renderTarget1.clone(); 127 | 128 | renderTarget.width = width; 129 | renderTarget.height = height; 130 | 131 | this.reset( renderTarget ); 132 | 133 | } 134 | 135 | }; 136 | -------------------------------------------------------------------------------- /js/postprocessing/FilmPass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.FilmPass = function ( noiseIntensity, scanlinesIntensity, scanlinesCount, grayscale ) { 6 | 7 | if ( THREE.FilmShader === undefined ) 8 | console.error( "THREE.FilmPass relies on THREE.FilmShader" ); 9 | 10 | var shader = THREE.FilmShader; 11 | 12 | this.uniforms = THREE.UniformsUtils.clone( shader.uniforms ); 13 | 14 | this.material = new THREE.ShaderMaterial( { 15 | 16 | uniforms: this.uniforms, 17 | vertexShader: shader.vertexShader, 18 | fragmentShader: shader.fragmentShader 19 | 20 | } ); 21 | 22 | if ( grayscale !== undefined ) this.uniforms.grayscale.value = grayscale; 23 | if ( noiseIntensity !== undefined ) this.uniforms.nIntensity.value = noiseIntensity; 24 | if ( scanlinesIntensity !== undefined ) this.uniforms.sIntensity.value = scanlinesIntensity; 25 | if ( scanlinesCount !== undefined ) this.uniforms.sCount.value = scanlinesCount; 26 | 27 | this.enabled = true; 28 | this.renderToScreen = false; 29 | this.needsSwap = true; 30 | 31 | 32 | this.camera = new THREE.OrthographicCamera( -1, 1, 1, -1, 0, 1 ); 33 | this.scene = new THREE.Scene(); 34 | 35 | this.quad = new THREE.Mesh( new THREE.PlaneGeometry( 2, 2 ), null ); 36 | this.scene.add( this.quad ); 37 | 38 | }; 39 | 40 | THREE.FilmPass.prototype = { 41 | 42 | render: function ( renderer, writeBuffer, readBuffer, delta ) { 43 | 44 | this.uniforms[ "tDiffuse" ].value = readBuffer; 45 | this.uniforms[ "time" ].value += delta; 46 | 47 | this.quad.material = this.material; 48 | 49 | if ( this.renderToScreen ) { 50 | 51 | renderer.render( this.scene, this.camera ); 52 | 53 | } else { 54 | 55 | renderer.render( this.scene, this.camera, writeBuffer, false ); 56 | 57 | } 58 | 59 | } 60 | 61 | }; 62 | -------------------------------------------------------------------------------- /js/postprocessing/GlitchPass.js: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | */ 4 | 5 | THREE.GlitchPass = function ( dt_size ) { 6 | 7 | if ( THREE.DigitalGlitch === undefined ) console.error( "THREE.GlitchPass relies on THREE.DigitalGlitch" ); 8 | 9 | var shader = THREE.DigitalGlitch; 10 | this.uniforms = THREE.UniformsUtils.clone( shader.uniforms ); 11 | 12 | if(dt_size===undefined) dt_size=64; 13 | 14 | 15 | this.uniforms[ "tDisp"].value=this.generateHeightmap(dt_size); 16 | 17 | 18 | this.material = new THREE.ShaderMaterial({ 19 | uniforms: this.uniforms, 20 | vertexShader: shader.vertexShader, 21 | fragmentShader: shader.fragmentShader 22 | }); 23 | 24 | this.enabled = true; 25 | this.renderToScreen = false; 26 | this.needsSwap = true; 27 | 28 | 29 | this.camera = new THREE.OrthographicCamera( -1, 1, 1, -1, 0, 1 ); 30 | this.scene = new THREE.Scene(); 31 | 32 | this.quad = new THREE.Mesh( new THREE.PlaneGeometry( 2, 2 ), null ); 33 | this.scene.add( this.quad ); 34 | 35 | this.goWild=false; 36 | this.curF=0; 37 | this.generateTrigger(); 38 | 39 | }; 40 | 41 | THREE.GlitchPass.prototype = { 42 | 43 | render: function ( renderer, writeBuffer, readBuffer, delta ) 44 | { 45 | this.uniforms[ "tDiffuse" ].value = readBuffer; 46 | this.uniforms[ 'seed' ].value=Math.random();//default seeding 47 | this.uniforms[ 'byp' ].value=0; 48 | 49 | if(this.curF % this.randX ===0 || this.goWild===true) 50 | { 51 | this.uniforms[ 'amount' ].value=Math.random()/30; 52 | this.uniforms[ 'angle' ].value=THREE.Math.randFloat(-Math.PI,Math.PI); 53 | this.uniforms[ 'seed_x' ].value=THREE.Math.randFloat(-1,1); 54 | this.uniforms[ 'seed_y' ].value=THREE.Math.randFloat(-1,1); 55 | this.uniforms[ 'distortion_x' ].value=THREE.Math.randFloat(0,1); 56 | this.uniforms[ 'distortion_y' ].value=THREE.Math.randFloat(0,1); 57 | this.curF=0; 58 | this.generateTrigger(); 59 | } 60 | else if(this.curF % this.randX