├── .editorconfig ├── .eslintrc.json ├── .gitignore ├── LICENCES └── THREE.MeshLine.md ├── README.md ├── collage.jpg ├── index.html ├── lib ├── ConvolutionShader.js ├── Mirror.js ├── THREE.MeshLine.js ├── fxaa.js └── laser.js ├── nin.json ├── no-invitation.nfo ├── res ├── blue_particle.jpg ├── checkers_color.png ├── earth-map-detail.png ├── earth-map.png ├── end.png ├── ewerk.obj ├── ewerk_map.jpg ├── graph.json ├── ground_lightmap.jpg ├── inside_map.jpg ├── intro-overlay.png ├── music.mp3 ├── outro-overlay.png ├── pink_revision_logo_inner.png ├── pink_revision_logo_middle.png ├── pink_revision_logo_outer.png ├── revision_logo_inner.png ├── revision_logo_middle.png ├── revision_logo_outer.png ├── schmalibre-light.woff2 ├── schmalibre.woff2 ├── stage_map.jpg ├── testo.png ├── tree2_lightmap.jpg ├── tree3_lightmap.jpg └── tree_lightmap.jpg ├── screenshot.png └── src ├── AddNode.js ├── AlphaBlendNode.js ├── AtariRacer.js ├── BlurPassNode.js ├── CccBlendNode.js ├── FXAANode.js ├── LulleOverlay.js ├── OrthoCubeNode.js ├── ParticleSystem.js ├── SceneSwitcherNode.js ├── atarifxNode.js ├── bouncyGeometry.js ├── bouncyoverlayerNode.js ├── bowties.js ├── breakdown.js ├── carouselNode.js ├── ccc.js ├── cccOverlay.js ├── chromaTransitionNode.js ├── clockTransitionNode.js ├── cubes.js ├── ewerk.js ├── ewerkoverlayfeeder.js ├── fadeoutNode.js ├── fallintransitionNode.js ├── featurebg.js ├── features.js ├── featuretex.js ├── globetextures.js ├── griddymidNode.js ├── hexafont.js ├── holeTransitionNode.js ├── jaws.js ├── justTransitionNode.js ├── logotransition.js ├── logotransitionquadpassNode.js ├── lulleNode.js ├── metatron.js ├── metatronoverlayerNode.js ├── pyramidfxNode.js ├── pyramids.js ├── pyramidsoverlay.js ├── revisionBars.js ├── revisionLogoCenter.js ├── rotataroon.js ├── schmapple.js ├── shaders ├── Add │ ├── fragment.glsl │ ├── uniforms.json │ └── vertex.glsl ├── AlphaBlend │ ├── fragment.glsl │ ├── uniforms.json │ └── vertex.glsl ├── CccBlend │ ├── fragment.glsl │ ├── uniforms.json │ └── vertex.glsl ├── OrthoCube │ ├── fragment.glsl │ ├── uniforms.json │ └── vertex.glsl ├── ataribackground │ ├── fragment.glsl │ ├── uniforms.json │ └── vertex.glsl ├── atarifx │ ├── fragment.glsl │ ├── uniforms.json │ └── vertex.glsl ├── bouncyoverlayer │ ├── fragment.glsl │ ├── uniforms.json │ └── vertex.glsl ├── carousel │ ├── fragment.glsl │ ├── uniforms.json │ └── vertex.glsl ├── chess │ ├── fragment.glsl │ ├── uniforms.json │ └── vertex.glsl ├── chromaTransition │ ├── fragment.glsl │ ├── uniforms.json │ └── vertex.glsl ├── clockTransition │ ├── fragment.glsl │ ├── uniforms.json │ └── vertex.glsl ├── discowall │ ├── fragment.glsl │ ├── uniforms.json │ └── vertex.glsl ├── fadeout │ ├── fragment.glsl │ ├── uniforms.json │ └── vertex.glsl ├── fallintransition │ ├── fragment.glsl │ ├── uniforms.json │ └── vertex.glsl ├── gridball │ ├── fragment.glsl │ ├── uniforms.json │ └── vertex.glsl ├── griddymid │ ├── fragment.glsl │ ├── uniforms.json │ └── vertex.glsl ├── griddymidbox │ ├── fragment.glsl │ ├── uniforms.json │ └── vertex.glsl ├── holeTransition │ ├── fragment.glsl │ ├── uniforms.json │ └── vertex.glsl ├── justTransition │ ├── fragment.glsl │ ├── uniforms.json │ └── vertex.glsl ├── linycuba │ ├── fragment.glsl │ ├── uniforms.json │ └── vertex.glsl ├── logotransitionquadpass │ ├── fragment.glsl │ ├── uniforms.json │ └── vertex.glsl ├── lulle │ ├── fragment.glsl │ ├── uniforms.json │ └── vertex.glsl ├── metatronoverlayer │ ├── fragment.glsl │ ├── uniforms.json │ └── vertex.glsl ├── pyramidfx │ ├── fragment.glsl │ ├── uniforms.json │ └── vertex.glsl ├── slideTransition │ ├── fragment.glsl │ ├── uniforms.json │ └── vertex.glsl ├── tartan │ ├── fragment.glsl │ ├── uniforms.json │ └── vertex.glsl ├── tartarstuff │ ├── fragment.glsl │ ├── uniforms.json │ └── vertex.glsl └── textout │ ├── fragment.glsl │ ├── uniforms.json │ └── vertex.glsl ├── slideTransitionNode.js ├── tartarstuffNode.js ├── text.js ├── textigrades.js ├── textoutNode.js ├── tree.js └── trianglebg.js /.editorconfig: -------------------------------------------------------------------------------- 1 | [*] 2 | insert_final_newline = true 3 | charset = utf-8 4 | indent_style = space 5 | 6 | [*.{css,html,js}] 7 | indent_size = 2 8 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es6": true 5 | }, 6 | "extends": "eslint:recommended", 7 | "parserOptions": { 8 | "sourceType": "module" 9 | }, 10 | "rules": { 11 | "indent": [ 12 | "error", 13 | 2 14 | ], 15 | "linebreak-style": [ 16 | "error", 17 | "unix" 18 | ], 19 | "quotes": [ 20 | "error", 21 | "single" 22 | ], 23 | "semi": [ 24 | "error", 25 | "always" 26 | ] 27 | }, 28 | "globals": { 29 | "NIN": true, 30 | "THREE": true, 31 | "GU": true, 32 | "BEAT": true, 33 | "BEAN": true, 34 | "BEAN_FOR_FRAME": true, 35 | "FRAME_FOR_BEAN": true, 36 | "Loader": true, 37 | "SHADERS": true, 38 | "demo": true, 39 | "clamp": true, 40 | "lerp": true, 41 | "easeOut": true, 42 | "easeIn": true, 43 | "smoothstep": true, 44 | "elasticOut": true 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | gen/ 3 | .*.swp 4 | .DS_STORE 5 | .idea 6 | -------------------------------------------------------------------------------- /LICENCES/THREE.MeshLine.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Jaume Sanchez 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 all 13 | 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 THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # No invitation 2 | 3 | ![Screenshots](collage.jpg) 4 | -------------------------------------------------------------------------------- /collage.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ninjadev/revision-invite-2018/5b66355f75b18e894dcfcd2d257420f4dbee99d9/collage.jpg -------------------------------------------------------------------------------- /lib/ConvolutionShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * Convolution shader 5 | * ported from o3d sample to WebGL / GLSL 6 | * http://o3d.googlecode.com/svn/trunk/samples/convolution.html 7 | */ 8 | 9 | THREE.ConvolutionShader = { 10 | 11 | defines: { 12 | 13 | "KERNEL_SIZE_FLOAT": "25.0", 14 | "KERNEL_SIZE_INT": "25" 15 | 16 | }, 17 | 18 | uniforms: { 19 | 20 | "tDiffuse": { value: null }, 21 | "uImageIncrement": { value: new THREE.Vector2( 0.001953125, 0.0 ) }, 22 | "cKernel": { value: [] } 23 | 24 | }, 25 | 26 | vertexShader: [ 27 | 28 | "uniform vec2 uImageIncrement;", 29 | 30 | "varying vec2 vUv;", 31 | 32 | "void main() {", 33 | 34 | "vUv = uv - ( ( KERNEL_SIZE_FLOAT - 1.0 ) / 2.0 ) * uImageIncrement;", 35 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 36 | 37 | "}" 38 | 39 | ].join( "\n" ), 40 | 41 | fragmentShader: [ 42 | 43 | "uniform float cKernel[ KERNEL_SIZE_INT ];", 44 | 45 | "uniform sampler2D tDiffuse;", 46 | "uniform vec2 uImageIncrement;", 47 | 48 | "varying vec2 vUv;", 49 | 50 | "void main() {", 51 | 52 | "vec2 imageCoord = vUv;", 53 | "vec4 sum = vec4( 0.0, 0.0, 0.0, 0.0 );", 54 | 55 | "for( int i = 0; i < KERNEL_SIZE_INT; i ++ ) {", 56 | 57 | "sum += texture2D( tDiffuse, imageCoord ) * cKernel[ i ];", 58 | "imageCoord += uImageIncrement;", 59 | 60 | "}", 61 | 62 | "gl_FragColor = sum;", 63 | 64 | "}" 65 | 66 | 67 | ].join( "\n" ), 68 | 69 | buildKernel: function ( sigma ) { 70 | 71 | // We lop off the sqrt(2 * pi) * sigma term, since we're going to normalize anyway. 72 | 73 | function gauss( x, sigma ) { 74 | 75 | return Math.exp( - ( x * x ) / ( 2.0 * sigma * sigma ) ); 76 | 77 | } 78 | 79 | var i, values, sum, halfWidth, kMaxKernelSize = 25, kernelSize = 2 * Math.ceil( sigma * 3.0 ) + 1; 80 | 81 | if ( kernelSize > kMaxKernelSize ) kernelSize = kMaxKernelSize; 82 | halfWidth = ( kernelSize - 1 ) * 0.5; 83 | 84 | values = new Array( kernelSize ); 85 | sum = 0.0; 86 | for ( i = 0; i < kernelSize; ++ i ) { 87 | 88 | values[ i ] = gauss( i - halfWidth, sigma ); 89 | sum += values[ i ]; 90 | 91 | } 92 | 93 | // normalize the kernel 94 | 95 | for ( i = 0; i < kernelSize; ++ i ) values[ i ] /= sum; 96 | 97 | return values; 98 | 99 | } 100 | 101 | }; 102 | -------------------------------------------------------------------------------- /lib/Mirror.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Slayvin / http://slayvin.net 3 | */ 4 | 5 | THREE.ShaderLib[ 'mirror' ] = { 6 | 7 | uniforms: { 8 | "mirrorColor": { value: new THREE.Color( 0x7F7F7F ) }, 9 | "mirrorSampler": { value: null }, 10 | "textureMatrix" : { value: new THREE.Matrix4() } 11 | }, 12 | 13 | vertexShader: [ 14 | 15 | "uniform mat4 textureMatrix;", 16 | 17 | "varying vec4 mirrorCoord;", 18 | 19 | "void main() {", 20 | 21 | "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );", 22 | "vec4 worldPosition = modelMatrix * vec4( position, 1.0 );", 23 | "mirrorCoord = textureMatrix * worldPosition;", 24 | 25 | "gl_Position = projectionMatrix * mvPosition;", 26 | 27 | "}" 28 | 29 | ].join( "\n" ), 30 | 31 | fragmentShader: [ 32 | 33 | "uniform vec3 mirrorColor;", 34 | "uniform sampler2D mirrorSampler;", 35 | 36 | "varying vec4 mirrorCoord;", 37 | 38 | "float blendOverlay(float base, float blend) {", 39 | "return( base < 0.5 ? ( 2.0 * base * blend ) : (1.0 - 2.0 * ( 1.0 - base ) * ( 1.0 - blend ) ) );", 40 | "}", 41 | 42 | "void main() {", 43 | 44 | "vec4 color = texture2DProj(mirrorSampler, mirrorCoord);", 45 | "color = vec4(blendOverlay(mirrorColor.r, color.r), blendOverlay(mirrorColor.g, color.g), blendOverlay(mirrorColor.b, color.b), 1.0);", 46 | 47 | "gl_FragColor = color;", 48 | 49 | "}" 50 | 51 | ].join( "\n" ) 52 | 53 | }; 54 | 55 | THREE.Mirror = function ( renderer, camera, options ) { 56 | 57 | THREE.Object3D.call( this ); 58 | 59 | this.name = 'mirror_' + this.id; 60 | 61 | options = options || {}; 62 | 63 | this.matrixNeedsUpdate = true; 64 | 65 | var width = options.textureWidth !== undefined ? options.textureWidth : 512; 66 | var height = options.textureHeight !== undefined ? options.textureHeight : 512; 67 | 68 | this.clipBias = options.clipBias !== undefined ? options.clipBias : 0.0; 69 | 70 | var mirrorColor = options.color !== undefined ? new THREE.Color( options.color ) : new THREE.Color( 0x7F7F7F ); 71 | 72 | this.renderer = renderer; 73 | this.mirrorPlane = new THREE.Plane(); 74 | this.normal = new THREE.Vector3( 0, 0, 1 ); 75 | this.mirrorWorldPosition = new THREE.Vector3(); 76 | this.cameraWorldPosition = new THREE.Vector3(); 77 | this.rotationMatrix = new THREE.Matrix4(); 78 | this.lookAtPosition = new THREE.Vector3( 0, 0, - 1 ); 79 | this.clipPlane = new THREE.Vector4(); 80 | 81 | // For debug only, show the normal and plane of the mirror 82 | var debugMode = options.debugMode !== undefined ? options.debugMode : false; 83 | 84 | if ( debugMode ) { 85 | 86 | var arrow = new THREE.ArrowHelper( new THREE.Vector3( 0, 0, 1 ), new THREE.Vector3( 0, 0, 0 ), 10, 0xffff80 ); 87 | var planeGeometry = new THREE.Geometry(); 88 | planeGeometry.vertices.push( new THREE.Vector3( - 10, - 10, 0 ) ); 89 | planeGeometry.vertices.push( new THREE.Vector3( 10, - 10, 0 ) ); 90 | planeGeometry.vertices.push( new THREE.Vector3( 10, 10, 0 ) ); 91 | planeGeometry.vertices.push( new THREE.Vector3( - 10, 10, 0 ) ); 92 | planeGeometry.vertices.push( planeGeometry.vertices[ 0 ] ); 93 | var plane = new THREE.Line( planeGeometry, new THREE.LineBasicMaterial( { color: 0xffff80 } ) ); 94 | 95 | this.add( arrow ); 96 | this.add( plane ); 97 | 98 | } 99 | 100 | if ( camera instanceof THREE.PerspectiveCamera ) { 101 | 102 | this.camera = camera; 103 | 104 | } else { 105 | 106 | this.camera = new THREE.PerspectiveCamera(); 107 | console.log( this.name + ': camera is not a Perspective Camera!' ); 108 | 109 | } 110 | 111 | this.textureMatrix = new THREE.Matrix4(); 112 | 113 | this.mirrorCamera = this.camera.clone(); 114 | this.mirrorCamera.matrixAutoUpdate = true; 115 | 116 | var parameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBuffer: false }; 117 | 118 | this.renderTarget = new THREE.WebGLRenderTarget( width, height, parameters ); 119 | this.renderTarget2 = new THREE.WebGLRenderTarget( width, height, parameters ); 120 | 121 | var mirrorShader = THREE.ShaderLib[ "mirror" ]; 122 | var mirrorUniforms = THREE.UniformsUtils.clone( mirrorShader.uniforms ); 123 | 124 | this.material = new THREE.ShaderMaterial( { 125 | 126 | fragmentShader: mirrorShader.fragmentShader, 127 | vertexShader: mirrorShader.vertexShader, 128 | uniforms: mirrorUniforms 129 | 130 | } ); 131 | 132 | this.material.uniforms.mirrorSampler.value = this.renderTarget.texture; 133 | this.material.uniforms.mirrorColor.value = mirrorColor; 134 | this.material.uniforms.textureMatrix.value = this.textureMatrix; 135 | 136 | if ( ! THREE.Math.isPowerOfTwo( width ) || ! THREE.Math.isPowerOfTwo( height ) ) { 137 | 138 | this.renderTarget.texture.generateMipmaps = false; 139 | this.renderTarget2.texture.generateMipmaps = false; 140 | 141 | } 142 | 143 | this.updateTextureMatrix(); 144 | this.render(); 145 | 146 | }; 147 | 148 | THREE.Mirror.prototype = Object.create( THREE.Object3D.prototype ); 149 | THREE.Mirror.prototype.constructor = THREE.Mirror; 150 | 151 | THREE.Mirror.prototype.renderWithMirror = function ( otherMirror ) { 152 | 153 | // update the mirror matrix to mirror the current view 154 | this.updateTextureMatrix(); 155 | this.matrixNeedsUpdate = false; 156 | 157 | // set the camera of the other mirror so the mirrored view is the reference view 158 | var tempCamera = otherMirror.camera; 159 | otherMirror.camera = this.mirrorCamera; 160 | 161 | // render the other mirror in temp texture 162 | otherMirror.renderTemp(); 163 | otherMirror.material.uniforms.mirrorSampler.value = otherMirror.renderTarget2.texture; 164 | 165 | // render the current mirror 166 | this.render(); 167 | this.matrixNeedsUpdate = true; 168 | 169 | // restore material and camera of other mirror 170 | otherMirror.material.uniforms.mirrorSampler.value = otherMirror.renderTarget.texture; 171 | otherMirror.camera = tempCamera; 172 | 173 | // restore texture matrix of other mirror 174 | otherMirror.updateTextureMatrix(); 175 | 176 | }; 177 | 178 | THREE.Mirror.prototype.updateTextureMatrix = function () { 179 | 180 | this.updateMatrixWorld(); 181 | this.camera.updateMatrixWorld(); 182 | 183 | this.mirrorWorldPosition.setFromMatrixPosition( this.matrixWorld ); 184 | this.cameraWorldPosition.setFromMatrixPosition( this.camera.matrixWorld ); 185 | 186 | this.rotationMatrix.extractRotation( this.matrixWorld ); 187 | 188 | this.normal.set( 0, 0, 1 ); 189 | this.normal.applyMatrix4( this.rotationMatrix ); 190 | 191 | var view = this.mirrorWorldPosition.clone().sub( this.cameraWorldPosition ); 192 | view.reflect( this.normal ).negate(); 193 | view.add( this.mirrorWorldPosition ); 194 | 195 | this.rotationMatrix.extractRotation( this.camera.matrixWorld ); 196 | 197 | this.lookAtPosition.set( 0, 0, - 1 ); 198 | this.lookAtPosition.applyMatrix4( this.rotationMatrix ); 199 | this.lookAtPosition.add( this.cameraWorldPosition ); 200 | 201 | var target = this.mirrorWorldPosition.clone().sub( this.lookAtPosition ); 202 | target.reflect( this.normal ).negate(); 203 | target.add( this.mirrorWorldPosition ); 204 | 205 | this.up.set( 0, - 1, 0 ); 206 | this.up.applyMatrix4( this.rotationMatrix ); 207 | this.up.reflect( this.normal ).negate(); 208 | 209 | this.mirrorCamera.position.copy( view ); 210 | this.mirrorCamera.up = this.up; 211 | this.mirrorCamera.lookAt( target ); 212 | 213 | this.mirrorCamera.updateProjectionMatrix(); 214 | this.mirrorCamera.updateMatrixWorld(); 215 | this.mirrorCamera.matrixWorldInverse.getInverse( this.mirrorCamera.matrixWorld ); 216 | 217 | // Update the texture matrix 218 | this.textureMatrix.set( 0.5, 0.0, 0.0, 0.5, 219 | 0.0, 0.5, 0.0, 0.5, 220 | 0.0, 0.0, 0.5, 0.5, 221 | 0.0, 0.0, 0.0, 1.0 ); 222 | this.textureMatrix.multiply( this.mirrorCamera.projectionMatrix ); 223 | this.textureMatrix.multiply( this.mirrorCamera.matrixWorldInverse ); 224 | 225 | // Now update projection matrix with new clip plane, implementing code from: http://www.terathon.com/code/oblique.html 226 | // Paper explaining this technique: http://www.terathon.com/lengyel/Lengyel-Oblique.pdf 227 | this.mirrorPlane.setFromNormalAndCoplanarPoint( this.normal, this.mirrorWorldPosition ); 228 | this.mirrorPlane.applyMatrix4( this.mirrorCamera.matrixWorldInverse ); 229 | 230 | this.clipPlane.set( this.mirrorPlane.normal.x, this.mirrorPlane.normal.y, this.mirrorPlane.normal.z, this.mirrorPlane.constant ); 231 | 232 | var q = new THREE.Vector4(); 233 | var projectionMatrix = this.mirrorCamera.projectionMatrix; 234 | 235 | q.x = ( Math.sign( this.clipPlane.x ) + projectionMatrix.elements[ 8 ] ) / projectionMatrix.elements[ 0 ]; 236 | q.y = ( Math.sign( this.clipPlane.y ) + projectionMatrix.elements[ 9 ] ) / projectionMatrix.elements[ 5 ]; 237 | q.z = - 1.0; 238 | q.w = ( 1.0 + projectionMatrix.elements[ 10 ] ) / projectionMatrix.elements[ 14 ]; 239 | 240 | // Calculate the scaled plane vector 241 | var c = new THREE.Vector4(); 242 | c = this.clipPlane.multiplyScalar( 2.0 / this.clipPlane.dot( q ) ); 243 | 244 | // Replacing the third row of the projection matrix 245 | projectionMatrix.elements[ 2 ] = c.x; 246 | projectionMatrix.elements[ 6 ] = c.y; 247 | projectionMatrix.elements[ 10 ] = c.z + 1.0 - this.clipBias; 248 | projectionMatrix.elements[ 14 ] = c.w; 249 | 250 | }; 251 | 252 | THREE.Mirror.prototype.render = function () { 253 | 254 | if ( this.matrixNeedsUpdate ) this.updateTextureMatrix(); 255 | 256 | this.matrixNeedsUpdate = true; 257 | 258 | // Render the mirrored view of the current scene into the target texture 259 | var scene = this; 260 | 261 | while ( scene.parent !== null ) { 262 | 263 | scene = scene.parent; 264 | 265 | } 266 | 267 | if ( scene !== undefined && scene instanceof THREE.Scene ) { 268 | 269 | // We can't render ourself to ourself 270 | var visible = this.material.visible; 271 | this.material.visible = false; 272 | 273 | this.renderer.render( scene, this.mirrorCamera, this.renderTarget, true ); 274 | 275 | this.material.visible = visible; 276 | 277 | } 278 | 279 | }; 280 | 281 | THREE.Mirror.prototype.renderTemp = function () { 282 | 283 | if ( this.matrixNeedsUpdate ) this.updateTextureMatrix(); 284 | 285 | this.matrixNeedsUpdate = true; 286 | 287 | // Render the mirrored view of the current scene into the target texture 288 | var scene = this; 289 | 290 | while ( scene.parent !== null ) { 291 | 292 | scene = scene.parent; 293 | 294 | } 295 | 296 | if ( scene !== undefined && scene instanceof THREE.Scene ) { 297 | 298 | this.renderer.render( scene, this.mirrorCamera, this.renderTarget2, true ); 299 | 300 | } 301 | 302 | }; 303 | -------------------------------------------------------------------------------- /lib/fxaa.js: -------------------------------------------------------------------------------- 1 | function threeShaderFXAA (opt) { 2 | if (typeof THREE === 'undefined') { 3 | throw new TypeError('You must have THREE in global scope for this module.') 4 | } 5 | opt = opt || {} 6 | return { 7 | uniforms: { 8 | tDiffuse: { type: 't', value: null }, 9 | resolution: { type: 'v2', value: opt.resolution || new THREE.Vector2() } 10 | }, 11 | vertexShader: "#define GLSLIFY 1\nvarying vec2 vUv;\n\nvarying vec2 v_rgbNW;\nvarying vec2 v_rgbNE;\nvarying vec2 v_rgbSW;\nvarying vec2 v_rgbSE;\nvarying vec2 v_rgbM;\n\nuniform vec2 resolution;\n\nvoid main() {\n vUv = uv;\n vec2 fragCoord = uv * resolution;\n vec2 inverseVP = 1.0 / resolution.xy;\n v_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP;\n v_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP;\n v_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP;\n v_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP;\n v_rgbM = vec2(fragCoord * inverseVP);\n\n gl_Position = projectionMatrix *\n modelViewMatrix *\n vec4(position,1.0);\n}\n", 12 | fragmentShader: "#define GLSLIFY 1\nvarying vec2 vUv;\n\n//texcoords computed in vertex step\n//to avoid dependent texture reads\nvarying vec2 v_rgbNW;\nvarying vec2 v_rgbNE;\nvarying vec2 v_rgbSW;\nvarying vec2 v_rgbSE;\nvarying vec2 v_rgbM;\n\n//make sure to have a resolution uniform set to the screen size\nuniform vec2 resolution;\nuniform sampler2D tDiffuse;\n\n/**\nBasic FXAA implementation based on the code on geeks3d.com with the\nmodification that the texture2DLod stuff was removed since it's\nunsupported by WebGL.\n\n--\n\nFrom:\nhttps://github.com/mitsuhiko/webgl-meincraft\n\nCopyright (c) 2011 by Armin Ronacher.\n\nSome rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n * Redistributions of source code must retain the above copyright\n notice, this list of conditions and the following disclaimer.\n\n * Redistributions in binary form must reproduce the above\n copyright notice, this list of conditions and the following\n disclaimer in the documentation and/or other materials provided\n with the distribution.\n\n * The names of the contributors may not be used to endorse or\n promote products derived from this software without specific\n prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n#ifndef FXAA_REDUCE_MIN\n #define FXAA_REDUCE_MIN (1.0/ 128.0)\n#endif\n#ifndef FXAA_REDUCE_MUL\n #define FXAA_REDUCE_MUL (1.0 / 8.0)\n#endif\n#ifndef FXAA_SPAN_MAX\n #define FXAA_SPAN_MAX 8.0\n#endif\n\n//optimized version for mobile, where dependent \n//texture reads can be a bottleneck\nvec4 fxaa_1540259130(sampler2D tex, vec2 fragCoord, vec2 resolution,\n vec2 v_rgbNW, vec2 v_rgbNE, \n vec2 v_rgbSW, vec2 v_rgbSE, \n vec2 v_rgbM) {\n vec4 color;\n mediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y);\n vec3 rgbNW = texture2D(tex, v_rgbNW).xyz;\n vec3 rgbNE = texture2D(tex, v_rgbNE).xyz;\n vec3 rgbSW = texture2D(tex, v_rgbSW).xyz;\n vec3 rgbSE = texture2D(tex, v_rgbSE).xyz;\n vec4 texColor = texture2D(tex, v_rgbM);\n vec3 rgbM = texColor.xyz;\n vec3 luma = vec3(0.299, 0.587, 0.114);\n float lumaNW = dot(rgbNW, luma);\n float lumaNE = dot(rgbNE, luma);\n float lumaSW = dot(rgbSW, luma);\n float lumaSE = dot(rgbSE, luma);\n float lumaM = dot(rgbM, luma);\n float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));\n float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));\n \n mediump vec2 dir;\n dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));\n dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));\n \n float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) *\n (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN);\n \n float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce);\n dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX),\n max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),\n dir * rcpDirMin)) * inverseVP;\n \n vec3 rgbA = 0.5 * (\n texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz +\n texture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz);\n vec3 rgbB = rgbA * 0.5 + 0.25 * (\n texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz +\n texture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz);\n\n float lumaB = dot(rgbB, luma);\n if ((lumaB < lumaMin) || (lumaB > lumaMax))\n color = vec4(rgbA, texColor.a);\n else\n color = vec4(rgbB, texColor.a);\n return color;\n}\n\nvoid main() {\n vec2 fragCoord = vUv * resolution; \n gl_FragColor = fxaa_1540259130(tDiffuse, fragCoord, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM);\n}\n" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /lib/laser.js: -------------------------------------------------------------------------------- 1 | (function(global) { 2 | class Laser { 3 | constructor() { 4 | this.object3d = new THREE.Object3D(); 5 | 6 | const canvas = this.generateLaserBodyCanvas(); 7 | const texture = new THREE.Texture(canvas); 8 | texture.needsUpdate = true; 9 | this.shaker = new THREE.Object3D(); 10 | this.shaker.frustumCulled = false; 11 | this.object3d.add(this.shaker); 12 | this.object3d.frustumCulled = false; 13 | 14 | const material = new THREE.MeshBasicMaterial({ 15 | map: texture, 16 | blending : THREE.AdditiveBlending, 17 | color: 0x449955, 18 | side: THREE.DoubleSide, 19 | depthWrite: false, 20 | depthTest: true, 21 | transparent: true, 22 | }); 23 | const geometry = new THREE.PlaneGeometry(1, 0.1); 24 | const numberOfPlanes = 16; 25 | for (var i = 0; i < numberOfPlanes; i++) { 26 | const mesh = new THREE.Mesh(geometry, material); 27 | mesh.position.x = 1 / 2; 28 | mesh.rotation.x = i / numberOfPlanes * Math.PI * 2; 29 | this.shaker.add(mesh); 30 | mesh.frustumCulled = false; 31 | } 32 | 33 | const particleTexture = Loader.loadTexture('res/blue_particle.jpg'); 34 | const particleMaterial = new THREE.SpriteMaterial({ 35 | map: particleTexture, 36 | blending: THREE.AdditiveBlending, 37 | }); 38 | 39 | const sprite = new THREE.Sprite(particleMaterial); 40 | sprite.scale.x = 0.5; 41 | sprite.scale.y = 2; 42 | sprite.frustumCulled = false; 43 | 44 | sprite.position.x = 1 - 0.01; 45 | this.object3d.add(sprite); 46 | this.sprite = sprite; 47 | } 48 | 49 | update(rand1, rand2, rand3, rand4, rand5) { 50 | this.sprite.scale.x = 0.5 / this.object3d.scale.x; 51 | this.sprite.scale.y = 0.5 / this.object3d.scale.y; 52 | const scale = 1 + (rand1 - 0.5) * 0.9; 53 | this.shaker.scale.y = scale; 54 | this.shaker.scale.z = scale; 55 | this.shaker.position.y = (rand2 - 0.5) * 0.05; 56 | this.shaker.position.z = (rand3 - 0.5) * 0.05; 57 | this.sprite.material.rotation = rand4 * Math.PI * 2; 58 | const color = 1 + 0.5 * rand5; 59 | this.sprite.material.color = new THREE.Color(color, color, color); 60 | } 61 | 62 | generateLaserBodyCanvas(){ 63 | const canvas = document.createElement('canvas'); 64 | const context = canvas.getContext('2d'); 65 | canvas.width = 1; 66 | canvas.height = 64; 67 | 68 | var gradient = context.createLinearGradient(0, 0, canvas.width, canvas.height); 69 | gradient.addColorStop(0 , 'rgba( 0, 0, 0,0.1)'); 70 | gradient.addColorStop(0.1, 'rgba(160,160,160,0.3)'); 71 | gradient.addColorStop(0.5, 'rgba(255,255,255,0.5)'); 72 | gradient.addColorStop(0.9, 'rgba(160,160,160,0.3)'); 73 | gradient.addColorStop(1.0, 'rgba( 0, 0, 0,0.1)'); 74 | 75 | context.fillStyle = gradient; 76 | context.fillRect(0, 0, canvas.width, canvas.height); 77 | 78 | return canvas; 79 | } 80 | } 81 | 82 | global.Laser = Laser; 83 | })(this); 84 | -------------------------------------------------------------------------------- /nin.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "No Invitation", 3 | "authors": [ 4 | "capitalism", 5 | "sigveseb", 6 | "stiaje", 7 | "cristea", 8 | "iverjo", 9 | "run", 10 | "lionleaf", 11 | "lulle" 12 | ], 13 | "description": "Invitation for Revision 2018.", 14 | "previewImage": "https://raw.githubusercontent.com/ninjadev/nin/master/nin/frontend/app/images/nin-dark.png", 15 | "music": { 16 | "path": "res/music.mp3", 17 | "bpm": 115, 18 | "subdivision": 12, 19 | "BEANOffset": 48 20 | }, 21 | "googleAnalyticsID": "UA-97441881-3", 22 | "labels": [ 23 | { 24 | "name": "Pre-intro", 25 | "BEAN": 48 26 | }, 27 | { 28 | "name": "Intro", 29 | "BEAN": 240 30 | }, 31 | { 32 | "name": "A", 33 | "BEAN": 672 34 | }, 35 | { 36 | "name": "B", 37 | "BEAN": 1056 38 | }, 39 | { 40 | "name": "A", 41 | "BEAN": 1440 42 | }, 43 | { 44 | "name": "C", 45 | "BEAN": 1824 46 | }, 47 | { 48 | "name": "C", 49 | "BEAN": 2208 50 | }, 51 | { 52 | "name": "B lowdown", 53 | "BEAN": 2592 54 | }, 55 | { 56 | "name": "piano snippet", 57 | "BEAN": 2736 58 | }, 59 | { 60 | "name": "B groovy", 61 | "BEAN": 2976 62 | }, 63 | { 64 | "name": "A breakdown", 65 | "BEAN": 3360 66 | }, 67 | { 68 | "name": "B + A merger", 69 | "BEAN": 3672 70 | }, 71 | { 72 | "name": "A outro", 73 | "BEAN": 4056 74 | } 75 | ] 76 | } 77 | -------------------------------------------------------------------------------- /no-invitation.nfo: -------------------------------------------------------------------------------- 1 | 2 | .===============================================================. 3 | |||||||||||||||||||\ || 4 | |||CODE/GFX|||||||||. || 5 | ||||||||||||||||||||| || 6 | |||capitalism|||||||\ || 7 | |||cristea|||||||||||. | _ . | ___ _ ___. _ . | || 8 | |||iverjo||||||||||||| |\|| | ||\|\ /| | |-| | || ||\| || 9 | |||lionleaf||||||||||\ | '`-` '| ' ' ' | ' ' | '`-`| ' || 10 | |||lulle||||||||||||||. || 11 | |||run||||||||||||||||| by || 12 | |||sigveseb|||||||||||\ || 13 | |||stiaje||||||||||||||. Ninjadev || 14 | |||||||||||||||||||||||| || 15 | |||||||||||||||||||||||\ || 16 | |||MUSIC||||||||||||||||. No theme, no fuss, no limit, just || 17 | ||||||||||||||||||||||||| Revision 2018. See you there! || 18 | |||sigveseb|||||||||||||\ || 19 | |||||||||||||||||||||||||. || 20 | `===============================================================' 21 | 22 | -------------------------------------------------------------------------------- /res/blue_particle.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ninjadev/revision-invite-2018/5b66355f75b18e894dcfcd2d257420f4dbee99d9/res/blue_particle.jpg -------------------------------------------------------------------------------- /res/checkers_color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ninjadev/revision-invite-2018/5b66355f75b18e894dcfcd2d257420f4dbee99d9/res/checkers_color.png -------------------------------------------------------------------------------- /res/earth-map-detail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ninjadev/revision-invite-2018/5b66355f75b18e894dcfcd2d257420f4dbee99d9/res/earth-map-detail.png -------------------------------------------------------------------------------- /res/earth-map.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ninjadev/revision-invite-2018/5b66355f75b18e894dcfcd2d257420f4dbee99d9/res/earth-map.png -------------------------------------------------------------------------------- /res/end.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ninjadev/revision-invite-2018/5b66355f75b18e894dcfcd2d257420f4dbee99d9/res/end.png -------------------------------------------------------------------------------- /res/ewerk_map.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ninjadev/revision-invite-2018/5b66355f75b18e894dcfcd2d257420f4dbee99d9/res/ewerk_map.jpg -------------------------------------------------------------------------------- /res/ground_lightmap.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ninjadev/revision-invite-2018/5b66355f75b18e894dcfcd2d257420f4dbee99d9/res/ground_lightmap.jpg -------------------------------------------------------------------------------- /res/inside_map.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ninjadev/revision-invite-2018/5b66355f75b18e894dcfcd2d257420f4dbee99d9/res/inside_map.jpg -------------------------------------------------------------------------------- /res/intro-overlay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ninjadev/revision-invite-2018/5b66355f75b18e894dcfcd2d257420f4dbee99d9/res/intro-overlay.png -------------------------------------------------------------------------------- /res/music.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ninjadev/revision-invite-2018/5b66355f75b18e894dcfcd2d257420f4dbee99d9/res/music.mp3 -------------------------------------------------------------------------------- /res/outro-overlay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ninjadev/revision-invite-2018/5b66355f75b18e894dcfcd2d257420f4dbee99d9/res/outro-overlay.png -------------------------------------------------------------------------------- /res/pink_revision_logo_inner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ninjadev/revision-invite-2018/5b66355f75b18e894dcfcd2d257420f4dbee99d9/res/pink_revision_logo_inner.png -------------------------------------------------------------------------------- /res/pink_revision_logo_middle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ninjadev/revision-invite-2018/5b66355f75b18e894dcfcd2d257420f4dbee99d9/res/pink_revision_logo_middle.png -------------------------------------------------------------------------------- /res/pink_revision_logo_outer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ninjadev/revision-invite-2018/5b66355f75b18e894dcfcd2d257420f4dbee99d9/res/pink_revision_logo_outer.png -------------------------------------------------------------------------------- /res/revision_logo_inner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ninjadev/revision-invite-2018/5b66355f75b18e894dcfcd2d257420f4dbee99d9/res/revision_logo_inner.png -------------------------------------------------------------------------------- /res/revision_logo_middle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ninjadev/revision-invite-2018/5b66355f75b18e894dcfcd2d257420f4dbee99d9/res/revision_logo_middle.png -------------------------------------------------------------------------------- /res/revision_logo_outer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ninjadev/revision-invite-2018/5b66355f75b18e894dcfcd2d257420f4dbee99d9/res/revision_logo_outer.png -------------------------------------------------------------------------------- /res/schmalibre-light.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ninjadev/revision-invite-2018/5b66355f75b18e894dcfcd2d257420f4dbee99d9/res/schmalibre-light.woff2 -------------------------------------------------------------------------------- /res/schmalibre.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ninjadev/revision-invite-2018/5b66355f75b18e894dcfcd2d257420f4dbee99d9/res/schmalibre.woff2 -------------------------------------------------------------------------------- /res/stage_map.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ninjadev/revision-invite-2018/5b66355f75b18e894dcfcd2d257420f4dbee99d9/res/stage_map.jpg -------------------------------------------------------------------------------- /res/testo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ninjadev/revision-invite-2018/5b66355f75b18e894dcfcd2d257420f4dbee99d9/res/testo.png -------------------------------------------------------------------------------- /res/tree2_lightmap.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ninjadev/revision-invite-2018/5b66355f75b18e894dcfcd2d257420f4dbee99d9/res/tree2_lightmap.jpg -------------------------------------------------------------------------------- /res/tree3_lightmap.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ninjadev/revision-invite-2018/5b66355f75b18e894dcfcd2d257420f4dbee99d9/res/tree3_lightmap.jpg -------------------------------------------------------------------------------- /res/tree_lightmap.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ninjadev/revision-invite-2018/5b66355f75b18e894dcfcd2d257420f4dbee99d9/res/tree_lightmap.jpg -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ninjadev/revision-invite-2018/5b66355f75b18e894dcfcd2d257420f4dbee99d9/screenshot.png -------------------------------------------------------------------------------- /src/AddNode.js: -------------------------------------------------------------------------------- 1 | (function(global) { 2 | class AddNode extends NIN.ShaderNode { 3 | constructor(id, options) { 4 | options.inputs = { 5 | A: new NIN.TextureInput(), 6 | B: new NIN.TextureInput(), 7 | }; 8 | super(id, options); 9 | this.opacity = options.opacity; 10 | } 11 | 12 | warmup(renderer) { 13 | this.update(0); 14 | this.render(renderer); 15 | } 16 | 17 | update(frame) { 18 | this.uniforms.opacity.value = this.opacity; 19 | this.uniforms.A.value = this.inputs.A.getValue(); 20 | this.uniforms.B.value = this.inputs.B.getValue(); 21 | } 22 | } 23 | 24 | global.AddNode = AddNode; 25 | })(this); 26 | -------------------------------------------------------------------------------- /src/AlphaBlendNode.js: -------------------------------------------------------------------------------- 1 | (function (global) { 2 | class AlphaBlendNode extends NIN.ShaderNode { 3 | constructor(id, options) { 4 | options.inputs = options.inputs || {}; 5 | options.inputs.under = new NIN.TextureInput(); 6 | options.inputs.over = new NIN.TextureInput(); 7 | super(id, options); 8 | } 9 | 10 | warmup(renderer) { 11 | this.update(0); 12 | this.render(renderer); 13 | } 14 | 15 | update(frame) { 16 | this.uniforms.frame.value = frame; 17 | this.uniforms.under.value = this.inputs.under.getValue(); 18 | this.uniforms.over.value = this.inputs.over.getValue(); 19 | } 20 | } 21 | 22 | global.AlphaBlendNode = AlphaBlendNode; 23 | })(this); 24 | -------------------------------------------------------------------------------- /src/BlurPassNode.js: -------------------------------------------------------------------------------- 1 | (function(global) { 2 | class BlurPassNode extends NIN.ShaderNode { 3 | constructor(id, options) { 4 | const kernelSize = 25; 5 | const sigma = 4.0; 6 | 7 | const convolutionShader = THREE.ConvolutionShader; 8 | options.shader = { 9 | uniforms: convolutionShader.uniforms, 10 | vertexShader: convolutionShader.vertexShader, 11 | fragmentShader: convolutionShader.fragmentShader, 12 | defines: { 13 | KERNEL_SIZE_FLOAT: kernelSize.toFixed(1), 14 | KERNEL_SIZE_INT: kernelSize.toFixed(0) 15 | } 16 | }; 17 | options.inputs = { 18 | tDiffuse: new NIN.TextureInput() 19 | }; 20 | super(id, options); 21 | if(options.direction == 'x') { 22 | this.uniforms.uImageIncrement.value = new THREE.Vector2(0.001953125, 0.0); 23 | } else { 24 | this.uniforms.uImageIncrement.value = new THREE.Vector2(0.0, 0.001953125); 25 | } 26 | this.uniforms.cKernel.value = THREE.ConvolutionShader.buildKernel(sigma); 27 | this.resize(); 28 | } 29 | 30 | resize() { 31 | const scale = 4; 32 | this.renderTarget.setSize(16 * GU / scale, 9 * GU / scale); 33 | } 34 | 35 | warmup(renderer) { 36 | this.update(0); 37 | this.render(renderer); 38 | } 39 | 40 | update() { 41 | this.uniforms.tDiffuse.value = this.inputs.tDiffuse.getValue(); 42 | } 43 | } 44 | 45 | global.BlurPassNode = BlurPassNode; 46 | })(this); 47 | -------------------------------------------------------------------------------- /src/CccBlendNode.js: -------------------------------------------------------------------------------- 1 | (function(global) { 2 | class CccBlendNode extends NIN.ShaderNode { 3 | constructor(id, options) { 4 | options.inputs = { 5 | A: new NIN.TextureInput(), 6 | B: new NIN.TextureInput(), 7 | }; 8 | super(id, options); 9 | } 10 | 11 | warmup(renderer) { 12 | this.update(6778); 13 | this.render(renderer); 14 | } 15 | 16 | update(frame) { 17 | this.uniforms.frame.value = frame; 18 | this.uniforms.A.value = this.inputs.A.getValue(); 19 | this.uniforms.B.value = this.inputs.B.getValue(); 20 | } 21 | } 22 | 23 | global.CccBlendNode = CccBlendNode; 24 | })(this); 25 | -------------------------------------------------------------------------------- /src/FXAANode.js: -------------------------------------------------------------------------------- 1 | (function(global) { 2 | class FXAANode extends NIN.ShaderNode { 3 | constructor(id, options) { 4 | const optionsClone = Object.assign({}, options); 5 | optionsClone.inputs = {}; 6 | optionsClone.inputs.tDiffuse = new NIN.TextureInput(); 7 | optionsClone.shader = global.threeShaderFXAA(); 8 | super(id, optionsClone); 9 | } 10 | 11 | resize() { 12 | super.resize(); 13 | this.uniforms.resolution.value.x = 16 * GU; 14 | this.uniforms.resolution.value.y = 9 * GU; 15 | } 16 | 17 | warmup(renderer) { 18 | this.update(9896); 19 | this.render(renderer); 20 | } 21 | 22 | update(frame) { 23 | this.uniforms.tDiffuse.value = this.inputs.tDiffuse.getValue(); 24 | } 25 | } 26 | 27 | global.FXAANode = FXAANode; 28 | })(this); 29 | -------------------------------------------------------------------------------- /src/LulleOverlay.js: -------------------------------------------------------------------------------- 1 | (function (global) { 2 | function timer(startBean, endBean, frame) { 3 | const startFrame = FRAME_FOR_BEAN(startBean); 4 | const endFrame = FRAME_FOR_BEAN(endBean); 5 | return (frame - startFrame) / (endFrame - startFrame); 6 | } 7 | 8 | class LulleOverlay extends NIN.Node { 9 | constructor(id) { 10 | super(id, { 11 | outputs: { 12 | render: new NIN.TextureOutput() 13 | } 14 | }); 15 | this.snareThrob = 0; 16 | this.canvas = document.createElement('canvas'); 17 | this.ctx = this.canvas.getContext('2d'); 18 | this.resize(); 19 | this.output = new THREE.CanvasTexture(this.canvas); 20 | this.output.minFilter = THREE.LinearFilter; 21 | this.output.magFilter = THREE.LinearFilter; 22 | } 23 | 24 | update(frame) { 25 | this.snareThrob *= 0.99; 26 | this.frame = frame; 27 | if (BEAT && BEAN % 24 == 12) { 28 | this.snareThrob = 1; 29 | } 30 | } 31 | 32 | render(renderer) { 33 | const frame = this.frame; 34 | this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); 35 | 36 | this.ctx.globalAlpha = 0.90 + this.snareThrob * 0.1; 37 | 38 | this.ctx.save(); 39 | this.ctx.scale(GU, GU); 40 | 41 | const t = timer(1945 - 12, 1945, frame); 42 | const t2 = timer(2041 - 12, 2041, frame); 43 | const leftOffset = easeIn(easeIn(-2, 0, t), -2, t2); 44 | 45 | const t3 = timer(2041 - 9, 2041, frame); 46 | const t4 = timer(2139 - 9, 2139, frame); 47 | const rightOffset = easeIn(easeIn(2, 0, t3), 2, t4); 48 | 49 | this.ctx.fillStyle = 'rgba(255,255,255,1.0)'; 50 | this.ctx.fillRect(0 + leftOffset, 0, 1.8, 9); 51 | this.ctx.fillStyle = 'rgba(255,255,255,1.0)'; 52 | this.ctx.fillRect(16 - 1.8 + rightOffset, 0, 1.8, 9); 53 | 54 | this.ctx.save(); 55 | this.ctx.translate(1, 4.5); 56 | this.ctx.rotate(Math.PI / 2); 57 | this.ctx.font = '0.95pt schmalibre'; 58 | this.ctx.textAlign = 'center'; 59 | this.ctx.textBaseline = 'alphabetic'; 60 | this.ctx.fillStyle = '#373c3f'; 61 | this.ctx.fillText('THIS TIME', 0., -leftOffset + 0.51); 62 | this.ctx.restore(); 63 | 64 | this.ctx.save(); 65 | this.ctx.translate(16 - 1, 4.5); 66 | this.ctx.rotate(-Math.PI / 2); 67 | this.ctx.font = '0.95pt schmalibre'; 68 | this.ctx.textAlign = 'center'; 69 | this.ctx.textBaseline = 'alphabetic'; 70 | this.ctx.fillStyle = '#373c3f'; 71 | this.ctx.fillText('NO METABALLS', 0., rightOffset + 0.51); 72 | this.ctx.restore(); 73 | 74 | this.ctx.restore(); 75 | 76 | this.output.needsUpdate = true; 77 | this.outputs.render.setValue(this.output); 78 | } 79 | 80 | resize() { 81 | this.canvas.width = 16 * GU; 82 | this.canvas.height = 9 * GU; 83 | } 84 | } 85 | 86 | global.LulleOverlay = LulleOverlay; 87 | })(this); 88 | -------------------------------------------------------------------------------- /src/OrthoCubeNode.js: -------------------------------------------------------------------------------- 1 | (function(global) { 2 | class OrthoCubeNode extends NIN.ShaderNode { 3 | constructor(id, options) { 4 | super(id, options); 5 | this.kickThrob = 0.0; 6 | } 7 | 8 | warmup(renderer) { 9 | this.update(673); 10 | this.render(renderer); 11 | } 12 | 13 | update(frame) { 14 | demo.nm.nodes.bloom.opacity = 0; 15 | this.kickThrob *= 0.8; 16 | if(BEAN % 12 == 0) { 17 | this.kickThrob = 1; 18 | } 19 | 20 | this.uniforms.kickThrob.value = this.kickThrob; 21 | this.uniforms.frame.value = frame; 22 | this.uniforms.BEAN.value = BEAN; 23 | 24 | let lastBeanFrame = FRAME_FOR_BEAN(BEAN); 25 | let nextBeanFrame = FRAME_FOR_BEAN(BEAN+1); 26 | 27 | let f = (frame - lastBeanFrame)/(nextBeanFrame - lastBeanFrame) 28 | let interBean = lerp(BEAN, BEAN+1, f); 29 | let beat = (interBean - 240.0)/12.0; 30 | //let beat = (INTERBEAN - 240.0)/12.0; For new nin 31 | let rotX = 0.0; 32 | let rotY = 0.0; 33 | let rotZ = 0.0; 34 | let cubeSize = 2.1; 35 | 36 | //Pre-scene 37 | if(beat < 0.0){ //Pre-scene (begins at 208) 38 | cubeSize = elasticOut(0, 2.1, 1.0, clamp(0, (beat + 2 / 12 + 1.0)/1.0, 1)); 39 | } 40 | 41 | 42 | //PART 1 43 | else if(beat < 1.0){ 44 | //spin right 45 | rotZ = 0.5 * Math.PI * easeOut(0.0, 1.0, (beat - 0.0)/1.0); 46 | }else if(beat < 2.0){ 47 | //pause 48 | }else if(beat < 3.0){ 49 | //spin left 50 | rotZ = -0.5 * Math.PI * easeOut(0.0, 1.0, (beat - 2.0)/1.0); 51 | }else if(beat < 4.0){ 52 | } 53 | 54 | 55 | //PART 2 56 | else if(beat < 5.0){ 57 | rotY = 0.5 * Math.PI * easeOut(0.0, 1.0, (beat - 4.0)/1.0); 58 | } 59 | else if(beat < 6.0){ //hold for a beat and a half 60 | //pause 61 | } 62 | else if(beat < 7.0){ //half beat for a half spin 63 | rotX = 0.5 * Math.PI * easeOut(0.0, 1.0, (beat - 6.0)/1.0); 64 | } 65 | else if(beat < 8.0){ 66 | //pause 67 | } 68 | 69 | 70 | //PART 3 (With lead) 71 | //Leads: 8.0, 8.75, 10.0, 10.75, 11.5 72 | else if(beat < 8.5){ 73 | rotX = -0.25 * Math.PI * easeOut(0.0, 1.0, (beat - 8.0)/0.5); 74 | } 75 | else if(beat < 8.75){ 76 | rotX = -0.25 * Math.PI; 77 | } 78 | else if(beat < 9.5){ 79 | rotX = -0.25 * Math.PI * easeOut(1.0, 2.0, (beat - 8.75)/0.75); 80 | } 81 | else if(beat < 10.0){ 82 | 83 | } 84 | else if(beat < 10.25){ 85 | rotY = -0.25 * Math.PI * easeOut(0.0, 1.0, (beat - 10.0)/0.25); 86 | } 87 | else if(beat < 10.75){ 88 | rotY = -0.25 * Math.PI; 89 | } 90 | else if(beat < 11.0){ 91 | rotY = -0.25 * Math.PI * easeOut(1.0, 2.0, (beat - 10.75)/0.25); 92 | } 93 | else if(beat < 11.5){ 94 | } 95 | else if(beat < 14.0){ 96 | rotY = (1 + 0.25) * Math.PI * easeOut(0.0, 1.0, (beat - 11.5)/2.5); 97 | rotX = (1 + 0.19591111) * Math.PI * easeOut(0.0, 1.0, (beat - 11.5)/2.5); 98 | } 99 | 100 | //PART 4 (with wooo) 101 | else if(beat <= 15.0){ 102 | rotY = 0.25 * Math.PI; 103 | rotX = 0.19591111 * Math.PI; 104 | } 105 | else if(beat <= 15.25){ 106 | rotY = 0.25 * Math.PI; 107 | rotX = 0.19591111 * Math.PI; 108 | cubeSize += easeOut(0, 1.1, (beat - 15.0)/0.25); 109 | }else if(beat <= 15.75){ 110 | rotY = 0.25 * Math.PI; 111 | rotX = 0.19591111 * Math.PI; 112 | cubeSize += 1.1 - easeOut(0, 3.2, (beat - 15.5)/0.5); 113 | }else{ 114 | cubeSize = 0; 115 | } 116 | 117 | this.uniforms.cubeSize.value = cubeSize; 118 | this.uniforms.rotX.value = rotX; 119 | this.uniforms.rotY.value = rotY; 120 | this.uniforms.rotZ.value = rotZ; 121 | } 122 | } 123 | global.OrthoCubeNode = OrthoCubeNode; 124 | })(this); 125 | 126 | -------------------------------------------------------------------------------- /src/ParticleSystem.js: -------------------------------------------------------------------------------- 1 | function ParticleSystem(options) { 2 | this.options = options; 3 | var amount = options.amount || 10000; 4 | this.decayFactor = options.decayFactor || 0.95; 5 | this.gravity = typeof options.gravity === 'undefined' ? 0.001 : options.gravity; 6 | var positions = new Float32Array(amount * 3); 7 | this.velocities = new Float32Array(amount * 3); 8 | var colors = new Float32Array(amount * 3); 9 | var sizes = new Float32Array(amount); 10 | this.particleGeometry = new THREE.Geometry(); 11 | this.particleGeometry = new THREE.BufferGeometry(); 12 | this.index = 0; 13 | this.particleGeometry.addAttribute('position', new THREE.BufferAttribute(positions, 3)); 14 | this.particleGeometry.addAttribute('customColor', new THREE.BufferAttribute(colors, 3)); 15 | this.particleGeometry.addAttribute('size', new THREE.BufferAttribute(sizes, 1)); 16 | this.generateSprite = options.generateSprite || generateSprite; 17 | const sprite = new THREE.CanvasTexture(this.generateSprite()); 18 | const particleMaterial = new THREE.ShaderMaterial({ 19 | uniforms: { 20 | amplitude: {value: 1.0}, 21 | color: {value: new THREE.Color(0xffffff)}, 22 | texture: {value: sprite}, 23 | gu: {value: GU}, 24 | }, 25 | vertexShader: ParticleSystem.vertexShader, 26 | fragmentShader: ParticleSystem.fragmentShader, 27 | blending: THREE.AdditiveBlending, 28 | depthTest: false, 29 | transparent: true, 30 | }); 31 | this.particles = new THREE.Points(this.particleGeometry, particleMaterial); 32 | this.particles.frustumCulled = false; 33 | this.particleMaterial = particleMaterial; 34 | } 35 | 36 | ParticleSystem.prototype.spawn = function(position, velocity, size) { 37 | this.index = (this.index + 1) % this.particleGeometry.attributes.size.array.length; 38 | this.particleGeometry.attributes.position.array[this.index * 3] = position.x; 39 | this.particleGeometry.attributes.position.array[this.index * 3 + 1] = position.y; 40 | this.particleGeometry.attributes.position.array[this.index * 3 + 2] = position.z; 41 | this.particleGeometry.attributes.customColor.array[this.index * 3] = this.options.color.r; 42 | this.particleGeometry.attributes.customColor.array[this.index * 3 + 1] = this.options.color.g; 43 | this.particleGeometry.attributes.customColor.array[this.index * 3 + 2] = this.options.color.b; 44 | this.velocities[this.index * 3] = velocity.x; 45 | this.velocities[this.index * 3 + 1] = velocity.y; 46 | this.velocities[this.index * 3 + 2] = velocity.z; 47 | this.particleGeometry.attributes.size.array[this.index] = size || 20; 48 | }; 49 | 50 | ParticleSystem.prototype.update = function() { 51 | const attributes = this.particleGeometry.attributes; 52 | for(var i = 0; i < attributes.size.array.length; i++) { 53 | attributes.size.array[i] *= this.decayFactor; 54 | this.velocities[i * 3 + 1] -= this.gravity; 55 | attributes.position.array[i * 3] += this.velocities[i * 3]; 56 | attributes.position.array[i * 3 + 1] += this.velocities[i * 3 + 1]; 57 | attributes.position.array[i * 3 + 2] += this.velocities[i * 3 + 2]; 58 | } 59 | attributes.size.needsUpdate = true; 60 | }; 61 | 62 | ParticleSystem.prototype.render = function() { 63 | this.particleGeometry.attributes.size.needsUpdate = true; 64 | this.particleGeometry.attributes.position.needsUpdate = true; 65 | this.particleGeometry.attributes.customColor.needsUpdate = true; 66 | this.particleMaterial.uniforms.gu.value = GU; 67 | }; 68 | 69 | function generateSprite() { 70 | var canvas = document.createElement( 'canvas' ); 71 | canvas.width = 16; 72 | canvas.height = 16; 73 | var context = canvas.getContext( '2d' ); 74 | var gradient = context.createRadialGradient( canvas.width / 2, canvas.height / 2, 0, canvas.width / 2, canvas.height / 2, canvas.width / 2 ); 75 | gradient.addColorStop( 0, 'rgba(255,255,255,1)' ); 76 | gradient.addColorStop( 0.2, 'rgba(255,255,255,1)' ); 77 | gradient.addColorStop( 0.4, 'rgba(64,64,64,1)' ); 78 | gradient.addColorStop( 1, 'rgba(0,0,0,1)' ); 79 | context.fillStyle = gradient; 80 | context.fillRect( 0, 0, canvas.width, canvas.height ); 81 | return canvas; 82 | } 83 | 84 | ParticleSystem.vertexShader = ` 85 | uniform float amplitude; 86 | uniform float gu; 87 | varying float vSize; 88 | attribute float size; 89 | attribute vec3 customColor; 90 | 91 | varying vec3 vColor; 92 | 93 | void main() { 94 | vColor = customColor; 95 | vSize = size; 96 | vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 ); 97 | gl_PointSize = size * ( 300.0 / -mvPosition.z * gu); 98 | gl_Position = projectionMatrix * mvPosition; 99 | } 100 | `; 101 | 102 | 103 | ParticleSystem.fragmentShader = ` 104 | uniform vec3 color; 105 | uniform sampler2D texture; 106 | 107 | varying vec3 vColor; 108 | varying float vSize; 109 | 110 | void main() { 111 | if(vSize < 0.0005) { 112 | discard; 113 | } 114 | gl_FragColor = vec4(color * vColor, 0.5); 115 | gl_FragColor = gl_FragColor * texture2D(texture, gl_PointCoord); 116 | } 117 | `; 118 | -------------------------------------------------------------------------------- /src/SceneSwitcherNode.js: -------------------------------------------------------------------------------- 1 | (function (global) { 2 | class SceneSwitcherNode extends NIN.Node { 3 | constructor(id) { 4 | super(id, { 5 | inputs: { 6 | _00_silence: new NIN.TextureInput(), 7 | _01_pre_intro_with_car_rev_sounds: new NIN.TextureInput(), 8 | _02_intro_1: new NIN.TextureInput(), 9 | _03_intro_2: new NIN.TextureInput(), 10 | _04_car_rev_interstitial: new NIN.TextureInput(), 11 | _05_first_A_theme_1: new NIN.TextureInput(), 12 | _05_first_A_theme_1_2: new NIN.TextureInput(), 13 | _06_first_A_theme_2: new NIN.TextureInput(), 14 | _06_first_A_theme_2_2: new NIN.TextureInput(), 15 | _07_first_B_theme_1: new NIN.TextureInput(), 16 | _08_first_B_theme_2: new NIN.TextureInput(), 17 | _09_second_A_theme_1: new NIN.TextureInput(), 18 | _10_second_A_theme_2: new NIN.TextureInput(), 19 | _11_illuminati_confirmed: new NIN.TextureInput(), 20 | _12_first_C_theme_1: new NIN.TextureInput(), 21 | _13_first_C_theme_2: new NIN.TextureInput(), 22 | _14_second_C_theme_1: new NIN.TextureInput(), 23 | _15_second_C_theme_2: new NIN.TextureInput(), 24 | _16_low_down_B_theme_1: new NIN.TextureInput(), 25 | _17_low_down_B_theme_piano_snippet: new NIN.TextureInput(), 26 | _18_low_down_B_theme_2: new NIN.TextureInput(), 27 | _19_groovy_B_theme: new NIN.TextureInput(), 28 | _20_A_theme_breakdown_1: new NIN.TextureInput(), 29 | _20_A_theme_breakdown_2: new NIN.TextureInput(), 30 | _21_third_B_theme_1: new NIN.TextureInput(), 31 | _22_third_B_theme_2: new NIN.TextureInput(), 32 | _22_third_B_theme_3: new NIN.TextureInput(), 33 | _22_third_B_theme_4: new NIN.TextureInput(), 34 | _22_third_B_theme_5: new NIN.TextureInput(), 35 | _23_final_A_theme_rolldown: new NIN.TextureInput(), 36 | _24_outro: new NIN.TextureInput(), 37 | _25_outro_2: new NIN.TextureInput(), 38 | }, 39 | outputs: { 40 | render: new NIN.TextureOutput(), 41 | } 42 | }); 43 | } 44 | 45 | beforeUpdate() { 46 | this.inputs._00_silence.enabled = false; 47 | this.inputs._01_pre_intro_with_car_rev_sounds.enabled = false; 48 | this.inputs._02_intro_1.enabled = false; 49 | this.inputs._03_intro_2.enabled = false; 50 | this.inputs._04_car_rev_interstitial.enabled = false; 51 | this.inputs._05_first_A_theme_1.enabled = false; 52 | this.inputs._05_first_A_theme_1_2.enabled = false; 53 | this.inputs._06_first_A_theme_2.enabled = false; 54 | this.inputs._06_first_A_theme_2_2.enabled = false; 55 | this.inputs._07_first_B_theme_1.enabled = false; 56 | this.inputs._08_first_B_theme_2.enabled = false; 57 | this.inputs._09_second_A_theme_1.enabled = false; 58 | this.inputs._10_second_A_theme_2.enabled = false; 59 | this.inputs._11_illuminati_confirmed.enabled = false; 60 | this.inputs._12_first_C_theme_1.enabled = false; 61 | this.inputs._13_first_C_theme_2.enabled = false; 62 | this.inputs._14_second_C_theme_1.enabled = false; 63 | this.inputs._15_second_C_theme_2.enabled = false; 64 | this.inputs._16_low_down_B_theme_1.enabled = false; 65 | this.inputs._17_low_down_B_theme_piano_snippet.enabled = false; 66 | this.inputs._18_low_down_B_theme_2.enabled = false; 67 | this.inputs._19_groovy_B_theme.enabled = false; 68 | this.inputs._20_A_theme_breakdown_1.enabled = false; 69 | this.inputs._20_A_theme_breakdown_2.enabled = false; 70 | this.inputs._21_third_B_theme_1.enabled = false; 71 | this.inputs._22_third_B_theme_2.enabled = false; 72 | this.inputs._22_third_B_theme_3.enabled = false; 73 | this.inputs._22_third_B_theme_4.enabled = false; 74 | this.inputs._22_third_B_theme_5.enabled = false; 75 | this.inputs._23_final_A_theme_rolldown.enabled = false; 76 | this.inputs._24_outro.enabled = false; 77 | this.inputs._25_outro_2.enabled = false; 78 | 79 | let selectedScene; 80 | if (BEAN < 48 * 1) { 81 | selectedScene = this.inputs._00_silence; 82 | } else if (BEAN < 48 * 5) { 83 | selectedScene = this.inputs._01_pre_intro_with_car_rev_sounds; 84 | } else if (BEAN < 48 * 9) { 85 | selectedScene = this.inputs._02_intro_1; 86 | } else if (BEAN < 48 * 13) { 87 | selectedScene = this.inputs._03_intro_2; 88 | } else if (BEAN < 48 * 14) { 89 | selectedScene = this.inputs._04_car_rev_interstitial; 90 | } else if (BEAN < 48 * 16) { 91 | selectedScene = this.inputs._05_first_A_theme_1; 92 | } else if (BEAN < 48 * 18) { 93 | selectedScene = this.inputs._05_first_A_theme_1_2; 94 | } else if (BEAN < 48 * 21.5) { 95 | selectedScene = this.inputs._06_first_A_theme_2; 96 | } else if (BEAN < 48 * 22) { 97 | selectedScene = this.inputs._06_first_A_theme_2_2; 98 | } else if (BEAN < 48 * 26) { 99 | selectedScene = this.inputs._07_first_B_theme_1; 100 | } else if (BEAN < 48 * 30 + 1) { 101 | // We add one bean here to handle the transition to the next scene 102 | // properly as it ends slightly into the next one. 103 | selectedScene = this.inputs._08_first_B_theme_2; 104 | } else if (BEAN < 48 * 34) { 105 | selectedScene = this.inputs._09_second_A_theme_1; 106 | } else if (BEAN < 48 * 36) { 107 | selectedScene = this.inputs._10_second_A_theme_2; 108 | } else if (BEAN < 48 * 38) { 109 | selectedScene = this.inputs._11_illuminati_confirmed; 110 | } else if (BEAN < 48 * 42) { 111 | selectedScene = this.inputs._12_first_C_theme_1; 112 | } else if (BEAN < 48 * 46) { 113 | selectedScene = this.inputs._13_first_C_theme_2; 114 | } else if (BEAN < 48 * 50) { 115 | selectedScene = this.inputs._14_second_C_theme_1; 116 | } else if (BEAN < 48 * 54) { 117 | selectedScene = this.inputs._15_second_C_theme_2; 118 | } else if (BEAN < 48 * 57) { 119 | selectedScene = this.inputs._16_low_down_B_theme_1; 120 | } else if (BEAN < 48 * 58) { 121 | selectedScene = this.inputs._17_low_down_B_theme_piano_snippet; 122 | } else if (BEAN < 48 * 62) { 123 | selectedScene = this.inputs._18_low_down_B_theme_2; 124 | } else if (BEAN < 48 * 70) { 125 | selectedScene = this.inputs._19_groovy_B_theme; 126 | } else if (BEAN < 48 * 72.5) { 127 | selectedScene = this.inputs._20_A_theme_breakdown_1; 128 | } else if (BEAN < 48 * 76.5) { 129 | selectedScene = this.inputs._20_A_theme_breakdown_2; 130 | } else if (BEAN < 48 * 78.5) { 131 | selectedScene = this.inputs._21_third_B_theme_1; 132 | } else if (BEAN < 48 * 80) { 133 | selectedScene = this.inputs._22_third_B_theme_2; 134 | } else if (BEAN < 48 * 80.5) { 135 | selectedScene = this.inputs._22_third_B_theme_3; 136 | } else if (BEAN < 48 * 81.5) { 137 | selectedScene = this.inputs._22_third_B_theme_4; 138 | } else if (BEAN < 48 * 84.5 - 6) { 139 | selectedScene = this.inputs._22_third_B_theme_5; 140 | } else if (BEAN < 48 * 88.5 - 1) { 141 | selectedScene = this.inputs._23_final_A_theme_rolldown; 142 | } else if (BEAN < 48 * 90.5 - 6) { 143 | selectedScene = this.inputs._24_outro; 144 | } else { 145 | selectedScene = this.inputs._25_outro_2; 146 | } 147 | selectedScene.enabled = true; 148 | this.outputs.render.setValue(selectedScene.getValue()); 149 | } 150 | } 151 | 152 | global.SceneSwitcherNode = SceneSwitcherNode; 153 | })(this); 154 | -------------------------------------------------------------------------------- /src/atarifxNode.js: -------------------------------------------------------------------------------- 1 | (function(global) { 2 | class atarifxNode extends NIN.ShaderNode { 3 | constructor(id, options) { 4 | options.inputs = options.inputs || {}; 5 | options.inputs.tDiffuse = new NIN.TextureInput(); 6 | super(id, options); 7 | } 8 | 9 | warmup(renderer) { 10 | this.update(2297); 11 | this.render(renderer); 12 | } 13 | 14 | update(frame) { 15 | this.uniforms.frame.value = frame; 16 | this.uniforms.tDiffuse.value = this.inputs.tDiffuse.getValue(); 17 | demo.nm.nodes.bloom.opacity = 0.5; 18 | } 19 | } 20 | 21 | global.atarifxNode = atarifxNode; 22 | })(this); 23 | -------------------------------------------------------------------------------- /src/bouncyoverlayerNode.js: -------------------------------------------------------------------------------- 1 | (function (global) { 2 | 3 | function T(startBean, endBean, frame) { 4 | const startFrame = FRAME_FOR_BEAN(startBean); 5 | const endFrame = FRAME_FOR_BEAN(endBean); 6 | return (frame - startFrame) / (endFrame - startFrame); 7 | } 8 | 9 | class bouncyoverlayerNode extends NIN.ShaderNode { 10 | constructor(id, options) { 11 | options.inputs = options.inputs || {}; 12 | options.inputs.tDiffuse = new NIN.TextureInput(); 13 | super(id, options); 14 | 15 | this.canvas = document.createElement('canvas'); 16 | this.ctx = this.canvas.getContext('2d'); 17 | this.resize(); 18 | this.canvasTexture = new THREE.CanvasTexture(this.canvas); 19 | this.canvasTexture.magFilter = THREE.LinearFilter; 20 | this.canvasTexture.minFilter = THREE.LinearFilter; 21 | 22 | this.textCanvas = document.createElement('canvas'); 23 | this.textCtx = this.textCanvas.getContext('2d'); 24 | 25 | document.fonts.load('bold 1pt schmalibre').then(() => { 26 | this.resize(); 27 | }); 28 | } 29 | 30 | warmup(renderer) { 31 | this.update(7888); 32 | this.render(renderer); 33 | } 34 | 35 | resize() { 36 | super.resize(); 37 | if (this.canvas) { 38 | this.canvas.width = 16 * GU; 39 | this.canvas.height = 9 * GU; 40 | } 41 | if (this.textCanvas) { 42 | this.textCanvas.width = 9 * GU; 43 | this.textCanvas.height = 2 * GU; 44 | this.textCtx.save(); 45 | this.textCtx.scale(GU, GU); 46 | this.textCtx.translate(4.5, 1); 47 | this.textCtx.textAlign = 'center'; 48 | this.textCtx.textBaseline = 'alphabetic'; 49 | this.textCtx.font = 'bold 0.9pt schmalibre'; 50 | this.textCtx.fillStyle = 'white'; 51 | this.textCtx.fillText('NO STARFIELDS', 0, 0); 52 | this.textCtx.restore(); 53 | } 54 | } 55 | 56 | update(frame) { 57 | this.frame = frame; 58 | this.uniforms.frame.value = frame; 59 | let t = Math.pow(T(62 * 48, 62 * 48 + 12, frame), 1.5); 60 | 61 | this.uniforms.translationOverX.value = easeIn(0.5, 0, t); 62 | this.uniforms.translationUnderX.value = easeIn(0, -0.15, t); 63 | 64 | if (BEAN >= 3024) { 65 | t = 1 - T(3024 + 12 - 2, 3024 + 12 - 2 + 10, frame); 66 | this.uniforms.translationOverX.value = easeIn(0.5, 0, t); 67 | this.uniforms.translationUnderX.value = easeIn(0, -0.15, t); 68 | } 69 | 70 | this.uniforms.tDiffuse.value = this.inputs.tDiffuse.getValue(); 71 | } 72 | 73 | render(renderer) { 74 | this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); 75 | 76 | const nudger = 0.5; 77 | 78 | if (BEAN < 3072) { 79 | this.ctx.save(); 80 | this.ctx.scale(GU, GU); 81 | this.ctx.beginPath(); 82 | this.ctx.moveTo(0, 0); 83 | this.ctx.lineTo(16 / 3 - nudger, 0); 84 | this.ctx.lineTo(16 / 3 + nudger, 9); 85 | this.ctx.lineTo(0, 9); 86 | this.ctx.lineTo(0, 0); 87 | this.ctx.fillStyle = 'rgb(55, 60, 63)'; 88 | this.ctx.fillStyle = '#282b2d'; 89 | this.ctx.fill(); 90 | 91 | this.ctx.font = 'bold 1pt schmalibre'; 92 | this.ctx.textAlign = 'center'; 93 | this.ctx.textBaseline = 'top'; 94 | this.ctx.translate(16 / 3 - nudger, 9 / 2); 95 | this.ctx.rotate(Math.PI / 2 - 0.11); 96 | this.ctx.fillStyle = 'white'; 97 | this.ctx.translate(-4.5, -.5); 98 | this.ctx.translate(0, 1.5); 99 | const bouncyScale = 1 + 0.1 * Math.cos(this.frame / 60 / 60 * 115 * Math.PI * 2); 100 | this.ctx.scale(1 / GU, 1 / GU * bouncyScale); 101 | this.ctx.translate(0, -1.5 * GU); 102 | const step = 4; 103 | for (let i = 0; i < this.textCanvas.height; i += step) { 104 | this.ctx.drawImage( 105 | this.textCanvas, 106 | 0, 107 | i, 108 | this.textCanvas.width, 109 | step + 1, 110 | (1 - i / this.textCanvas.height) * 12 * Math.cos(this.frame / 60 / 60 * 115 * Math.PI), 111 | i, 112 | this.textCanvas.width, 113 | step + 1); 114 | } 115 | 116 | this.ctx.restore(); 117 | } 118 | 119 | this.ctx.save(); 120 | this.ctx.scale(GU, GU); 121 | this.ctx.translate(8, 0); 122 | this.ctx.font = 'bold 1pt schmalibre'; 123 | this.ctx.textBaseline = 'middle'; 124 | this.ctx.textAlign = 'center'; 125 | if (BEAN >= 3072) { 126 | const t = T(3072, 3072 + 48, this.frame); 127 | const t2 = 0.5 + (t > 0.5 ? 1 : -1) * Math.pow(Math.abs(2 * t - 1), 10.6) / 2; 128 | this.ctx.textBaseline = 'alphabetic'; 129 | this.uniforms.translationOverX.value = 0; 130 | this.ctx.fillStyle = 'black'; 131 | this.ctx.fillText('NO DEADLINES', lerp(16, -16, t2) - lerp(-3, 3, t), 4 / 5 * 9 + 0.51); 132 | } 133 | 134 | if (BEAN >= 3264 && BEAN < 3264 + 24 + 8) { 135 | this.ctx.fillStyle = 'black'; 136 | this.ctx.font = 'bold 1.66pt schmalibre'; 137 | this.ctx.fillText('WAIT, WHAT?', 0, 5.1); 138 | } else if (BEAN >= 3216 && BEAN < 3264 - 24) { 139 | this.uniforms.translationOverX.value = 0; 140 | this.ctx.fillStyle = 'white'; 141 | this.ctx.fillText('NO SUBMISSIONS', 0, 4.5); 142 | } else if (BEAN >= 3168 && BEAN < 3216 - 24) { 143 | this.uniforms.translationOverX.value = 0; 144 | this.ctx.fillStyle = 'white'; 145 | //this.ctx.fillText('NO LIVE CODING', 0, 4.5); 146 | } 147 | this.ctx.restore(); 148 | 149 | this.canvasTexture.needsUpdate = true; 150 | this.uniforms.overlay.value = this.canvasTexture; 151 | super.render(renderer); 152 | } 153 | } 154 | 155 | global.bouncyoverlayerNode = bouncyoverlayerNode; 156 | })(this); 157 | -------------------------------------------------------------------------------- /src/bowties.js: -------------------------------------------------------------------------------- 1 | (function(global) { 2 | class bowties extends NIN.Node { 3 | constructor(id) { 4 | super(id, { 5 | outputs: { 6 | render: new NIN.TextureOutput() 7 | } 8 | }); 9 | 10 | this.canvas = document.createElement('canvas'); 11 | this.ctx = this.canvas.getContext('2d'); 12 | this.resize(); 13 | this.output = new THREE.VideoTexture(this.canvas); 14 | this.output.minFilter = THREE.LinearFilter; 15 | this.output.magFilter = THREE.LinearFilter; 16 | } 17 | 18 | update(frame) { 19 | this.frame = frame; 20 | } 21 | 22 | resize() { 23 | this.canvas.width = 16 * GU; 24 | this.canvas.height = 9 * GU; 25 | } 26 | 27 | 28 | warmup(renderer) { 29 | this.update(9327); 30 | this.render(renderer); 31 | } 32 | 33 | render() { 34 | 35 | this.ctx.fillStyle = 'rgb(255, 73, 130)'; 36 | this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height); 37 | this.ctx.fillStyle = 'white'; 38 | this.ctx.lineWidth = 0.05; 39 | this.ctx.save(); 40 | this.ctx.scale(GU, GU); 41 | this.ctx.beginPath(); 42 | for(let i = 0; i < 20; i++) { 43 | for(let j = 0; j < 10; j++) { 44 | const x = i + (j % 2) * 0.5; 45 | const y = j; 46 | const r = 0.25 + Math.max(0, (i % 2) * 0.25 - (j % 2 == 0) * 0.25); 47 | this.ctx.save(); 48 | this.ctx.translate(x, y); 49 | let angle = (this.frame / 10) % (Math.PI * 2); 50 | angle = (angle + (i ^ j) / 2) % (Math.PI * 2); 51 | if(angle > Math.PI) { 52 | angle = Math.PI * 2 - angle; 53 | this.ctx.rotate(Math.PI / 2); 54 | } 55 | this.ctx.moveTo(0, 0); 56 | this.ctx.lineTo(r * Math.cos(-angle / 2), 57 | r * Math.sin(-angle / 2)); 58 | this.ctx.arc(0, 0, r, 59 | - angle / 2, 60 | + angle / 2); 61 | this.ctx.lineTo(0, 0); 62 | this.ctx.lineTo(r * Math.cos(Math.PI - angle / 2), 63 | r * Math.sin(Math.PI - angle / 2)); 64 | this.ctx.arc(0, 0, r, Math.PI -angle / 2, Math.PI + angle / 2); 65 | this.ctx.lineTo(0, 0); 66 | this.ctx.restore(); 67 | } 68 | } 69 | this.ctx.fill(); 70 | 71 | this.ctx.restore(); 72 | 73 | this.output.needsUpdate = true; 74 | this.outputs.render.setValue(this.output); 75 | } 76 | } 77 | 78 | global.bowties = bowties; 79 | })(this); 80 | -------------------------------------------------------------------------------- /src/carouselNode.js: -------------------------------------------------------------------------------- 1 | (function (global) { 2 | class carouselNode extends NIN.ShaderNode { 3 | constructor(id, options) { 4 | options.inputs = { 5 | overlay: new NIN.TextureInput(), 6 | overlay2: new NIN.TextureInput(), 7 | overlay3: new NIN.TextureInput(), 8 | nextScene: new NIN.TextureInput(), 9 | cameraValues: new NIN.TextureInput(), 10 | }; 11 | super(id, options); 12 | } 13 | 14 | warmup(renderer) { 15 | this.update(3771); 16 | this.render(renderer); 17 | } 18 | 19 | update(frame) { 20 | const t = (frame - FRAME_FOR_BEAN(4 * 12 * 30)) / 60; 21 | this.uniforms.frame.value = frame; 22 | const cameraValues = this.inputs.cameraValues.getValue(); 23 | if (cameraValues) { 24 | this.uniforms.cameraX.value = cameraValues.cameraX; 25 | this.uniforms.cameraY.value = cameraValues.cameraY; 26 | this.uniforms.cameraZoom.value = cameraValues.cameraZoom; 27 | this.uniforms.cameraRotate.value = cameraValues.cameraRotate; 28 | } 29 | this.uniforms.divisions.value = 6; 30 | this.uniforms.width.value = lerp( 31 | 1, 32 | 0, 33 | (frame - FRAME_FOR_BEAN(1536 - 24)) / 34 | (FRAME_FOR_BEAN(1536) - FRAME_FOR_BEAN(1536 - 24))); 35 | this.uniforms.width.value = 1; 36 | this.uniforms.foregroundColor.value = new THREE.Color(0xff4982); 37 | this.uniforms.foregroundColor2.value = new THREE.Color(204 / 255, 38 / 255, 90 / 255); 38 | this.uniforms.backgroundColor.value = new THREE.Color(0xffffff); 39 | //this.uniforms.backgroundColor.value = new THREE.Color(0x000000); 40 | this.uniforms.radiusMultiplier.value = easeIn(0, 50, t * 0.05); 41 | this.uniforms.thirdColor.value = new THREE.Color(119 / 255, 225 / 255, 93 / 255); 42 | this.uniforms.thirdColorRadius.value = lerp( 43 | 0.075, 44 | 10, 45 | (frame - FRAME_FOR_BEAN(32 * 48)) / (FRAME_FOR_BEAN(34 * 48) - FRAME_FOR_BEAN(32 * 48))); 46 | this.uniforms.origo.value = new THREE.Vector2(easeOut(0, 0.5, t / 8), 47 | easeOut(0, 0.5, t / 3)); 48 | this.uniforms.overlay.value = this.inputs.overlay.getValue(); 49 | this.uniforms.overlay2.value = this.inputs.overlay2.getValue(); 50 | this.uniforms.overlay3.value = this.inputs.overlay3.getValue(); 51 | this.uniforms.nextScene.value = this.inputs.nextScene.getValue(); 52 | this.uniforms.fadeOutT.value = easeOut(0, 1, (frame - FRAME_FOR_BEAN(32 * 48 + 70)) / 100); 53 | demo.nm.nodes.bloom.opacity = 0; 54 | } 55 | } 56 | 57 | global.carouselNode = carouselNode; 58 | })(this); 59 | -------------------------------------------------------------------------------- /src/cccOverlay.js: -------------------------------------------------------------------------------- 1 | (function (global) { 2 | class cccOverlay extends NIN.THREENode { 3 | constructor(id) { 4 | super(id, { 5 | outputs: { 6 | render: new NIN.TextureOutput() 7 | } 8 | }); 9 | 10 | this.canvas = document.createElement('canvas'); 11 | this.ctx = this.canvas.getContext('2d'); 12 | this.resize(); 13 | this.output = new THREE.VideoTexture(this.canvas); 14 | this.output.minFilter = THREE.LinearFilter; 15 | this.output.magFilter = THREE.LinearFilter; 16 | } 17 | 18 | warmup(renderer) { 19 | this.update(6778); 20 | this.render(renderer); 21 | } 22 | 23 | update(frame) { 24 | super.update(frame); 25 | 26 | this.frame = frame; 27 | } 28 | 29 | resize() { 30 | this.canvas.width = 16 * GU; 31 | this.canvas.height = 9 * GU; 32 | } 33 | 34 | render() { 35 | const frame = this.frame; 36 | 37 | // This clears the canvas 38 | this.canvas.width += 0; 39 | 40 | this.ctx.save(); 41 | this.ctx.scale(GU, GU); 42 | 43 | if (frame > 7320) { 44 | const t = lerp( 45 | 0, 46 | lerp(1, 0, (frame - 7532) / 20), 47 | (frame - 7397) / 20 48 | ); 49 | } else { 50 | const t = easeOut( 51 | 0, 52 | easeOut(1, 0, (frame - 7181) / 50), 53 | (frame - 7030) / 100 54 | ); 55 | } 56 | if (frame > 7300) { 57 | const t = easeOut( 58 | 0, 59 | easeOut(1, 0, (frame - 7622) / 30), 60 | (frame - 7377) / 30 61 | ); 62 | // NO GRAS || NO STARS 63 | this.ctx.fillStyle = 'rgba(152, 90, 152, 0.9)'; 64 | this.ctx.beginPath(); 65 | this.ctx.moveTo(0, 9); 66 | this.ctx.lineTo(easeIn(0, 5.5, t), 9); 67 | this.ctx.lineTo(0, easeIn(9, 3.5, t)); 68 | this.ctx.lineTo(0, 9); 69 | this.ctx.fill(); 70 | 71 | this.ctx.save(); 72 | this.ctx.translate(0, 9); 73 | this.ctx.rotate(Math.PI / 4); 74 | this.ctx.textAlign = 'center'; 75 | this.ctx.textBaseline = 'alphabetic'; 76 | this.ctx.font = 'bold 0.7pt schmalibre'; 77 | this.ctx.fillStyle = 'white'; 78 | this.ctx.globalCompositeOperation = 'xor'; 79 | 80 | this.ctx.fillText('NO RIBBONS', 0, easeIn(0.8, -3.5, t) + 0.51); 81 | this.ctx.fillText('', 0, easeIn(2.0, -2.8, t)); 82 | this.ctx.restore(); 83 | } else { 84 | const t = lerp( 85 | 0, 86 | lerp(1, 0, (frame - 7263 + 30) / 30), 87 | (frame - 7010 + 20) / 30 88 | ); 89 | // NO GRAS || NO STARS 90 | this.ctx.fillStyle = 'rgba(152, 90, 152, 0.9)'; 91 | this.ctx.beginPath(); 92 | this.ctx.moveTo(0, 9); 93 | this.ctx.lineTo(easeIn(0, 5.5, t), 9); 94 | this.ctx.lineTo(0, easeIn(9, 3.5, t)); 95 | this.ctx.lineTo(0, 9); 96 | this.ctx.fill(); 97 | 98 | this.ctx.save(); 99 | this.ctx.translate(0, 9); 100 | this.ctx.rotate(Math.PI / 4); 101 | this.ctx.textAlign = 'center'; 102 | this.ctx.textBaseline = 'alphabetic'; 103 | this.ctx.font = 'bold 0.7pt schmalibre'; 104 | this.ctx.fillStyle = 'white'; 105 | this.ctx.globalCompositeOperation = 'xor'; 106 | 107 | this.ctx.fillText('THIS TIME', 0, easeIn(0.8, -3.5, t) + 0.51); 108 | this.ctx.restore(); 109 | } 110 | 111 | 112 | this.ctx.restore(); 113 | this.output.needsUpdate = true; 114 | this.outputs.render.setValue(this.output); 115 | } 116 | } 117 | 118 | global.cccOverlay = cccOverlay; 119 | })(this); 120 | -------------------------------------------------------------------------------- /src/chromaTransitionNode.js: -------------------------------------------------------------------------------- 1 | (function(global) { 2 | class chromaTransitionNode extends NIN.ShaderNode { 3 | constructor(id, options) { 4 | options.inputs = { 5 | A: new NIN.TextureInput(), 6 | B: new NIN.TextureInput(), 7 | chroma: new NIN.TextureInput(), 8 | }; 9 | super(id, options); 10 | } 11 | 12 | warmup(renderer) { 13 | this.update(0); 14 | this.render(renderer); 15 | } 16 | 17 | update(frame) { 18 | this.uniforms.t.value = frame; 19 | this.uniforms.A.value = this.inputs.A.getValue(); 20 | this.uniforms.B.value = this.inputs.B.getValue(); 21 | this.uniforms.chroma.value = this.inputs.chroma.getValue(); 22 | } 23 | } 24 | 25 | global.chromaTransitionNode = chromaTransitionNode; 26 | })(this); 27 | -------------------------------------------------------------------------------- /src/clockTransitionNode.js: -------------------------------------------------------------------------------- 1 | (function (global) { 2 | class clockTransitionNode extends NIN.ShaderNode { 3 | constructor(id, options) { 4 | options.inputs = { 5 | A: new NIN.TextureInput(), 6 | B: new NIN.TextureInput() 7 | }; 8 | super(id, options); 9 | } 10 | 11 | beforeUpdate(frame) { 12 | const startClock = 3662; 13 | const endExpand = 3756; 14 | this.inputs.A.enabled = frame < endExpand; 15 | this.inputs.B.enabled = frame > startClock; 16 | } 17 | 18 | warmup(renderer) { 19 | this.update(0); 20 | this.render(renderer); 21 | } 22 | 23 | update(frame) { 24 | this.uniforms.t.value = frame; 25 | this.uniforms.A.value = this.inputs.A.getValue(); 26 | this.uniforms.B.value = this.inputs.B.getValue(); 27 | } 28 | } 29 | 30 | global.clockTransitionNode = clockTransitionNode; 31 | })(this); 32 | -------------------------------------------------------------------------------- /src/ewerkoverlayfeeder.js: -------------------------------------------------------------------------------- 1 | (function(global) { 2 | class ewerkoverlayfeeder extends NIN.Node { 3 | constructor(id, options) { 4 | super(id, { 5 | outputs: { 6 | render: new NIN.TextureOutput() 7 | } 8 | }); 9 | 10 | 11 | this.canvas = document.createElement('canvas'); 12 | this.ctx = this.canvas.getContext('2d'); 13 | this.canvasTexture = new THREE.CanvasTexture(this.canvas); 14 | this.canvasTexture.minFilter = THREE.LinearFilter; 15 | this.canvasTexture.magFilter = THREE.LinearFilter; 16 | this.canvas.width = 1920; 17 | this.canvas.height = 1080; 18 | this.beforeImage = document.createElement('img'); 19 | Loader.load('res/intro-overlay.png', this.beforeImage, () => {}); 20 | this.afterImage = document.createElement('img'); 21 | Loader.load('res/outro-overlay.png', this.afterImage, () => {}); 22 | } 23 | 24 | warmup(renderer) { 25 | this.update(11509); 26 | this.render(renderer); 27 | this.update(166); 28 | this.render(renderer); 29 | } 30 | 31 | update(frame) { 32 | this.frame = frame; 33 | } 34 | 35 | render() { 36 | this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); 37 | let t = lerp(0, 1, (this.frame - 112) / (124 - 112)); 38 | t = lerp(t, 0, (this.frame - 239 + 10) / (250 - 239)); 39 | t = lerp(t, 1, (this.frame - 11315) / 400); 40 | this.ctx.globalAlpha = easeIn(0, 1, t * 3); 41 | this.ctx.fillStyle = 'rgb(55, 60, 63)'; 42 | //this.ctx.fillRect(0, 800, 1920, 1000); 43 | if(BEAN < 1000) { 44 | this.ctx.drawImage(this.beforeImage, 0, easeIn(20, -20, t)); 45 | } else { 46 | this.ctx.drawImage(this.afterImage, 0, easeOut(100, -40, t)); 47 | } 48 | 49 | this.canvasTexture.needsUpdate = true; 50 | this.outputs.render.setValue(this.canvasTexture); 51 | } 52 | 53 | resize() { 54 | } 55 | } 56 | 57 | global.ewerkoverlayfeeder = ewerkoverlayfeeder; 58 | })(this); 59 | -------------------------------------------------------------------------------- /src/fadeoutNode.js: -------------------------------------------------------------------------------- 1 | (function(global) { 2 | class fadeoutNode extends NIN.ShaderNode { 3 | constructor(id, options) { 4 | options.inputs = { 5 | A: new NIN.TextureInput(), 6 | }; 7 | super(id, options); 8 | } 9 | 10 | warmup(renderer) { 11 | this.update(11694); 12 | this.render(renderer); 13 | } 14 | 15 | update(frame) { 16 | this.uniforms.t.value = clamp(0, (frame - FRAME_FOR_BEAN(94 * 12 * 4 + 24)) / 50, 1); 17 | this.uniforms.A.value = this.inputs.A.getValue(); 18 | } 19 | } 20 | 21 | global.fadeoutNode = fadeoutNode; 22 | })(this); 23 | -------------------------------------------------------------------------------- /src/fallintransitionNode.js: -------------------------------------------------------------------------------- 1 | (function(global) { 2 | class fallintransitionNode extends NIN.ShaderNode { 3 | constructor(id, options) { 4 | options.inputs = { 5 | A: new NIN.TextureInput(), 6 | B: new NIN.TextureInput(), 7 | }; 8 | super(id, options); 9 | } 10 | 11 | warmup(renderer) { 12 | this.update(6779); 13 | this.render(renderer); 14 | } 15 | 16 | update(frame) { 17 | this.uniforms.t.value = easeIn( 18 | -1, 19 | easeOut( 20 | 0, 21 | easeIn( 22 | -.12, 23 | easeOut( 24 | 0, 25 | easeIn(-.06, 0, (frame - 6790) / 7), 26 | (frame - 6785) / 7 27 | ), 28 | (frame - 6775) / 10 29 | ), 30 | (frame - 6765) / 10 31 | ), 32 | (frame - 6745) / 20 33 | ); 34 | this.uniforms.A.value = this.inputs.A.getValue(); 35 | this.uniforms.B.value = this.inputs.B.getValue(); 36 | 37 | demo.nm.nodes.bloom.opacity = lerp(2, 0.25, (frame - 6745) / 20); 38 | } 39 | } 40 | 41 | global.fallintransitionNode = fallintransitionNode; 42 | })(this); 43 | -------------------------------------------------------------------------------- /src/featurebg.js: -------------------------------------------------------------------------------- 1 | (function (global) { 2 | class featurebg extends NIN.Node { 3 | constructor(id) { 4 | super(id, { 5 | outputs: { 6 | render: new NIN.TextureOutput() 7 | } 8 | }); 9 | 10 | this.canvas = document.createElement('canvas'); 11 | this.ctx = this.canvas.getContext('2d'); 12 | this.resize(); 13 | this.output = new THREE.CanvasTexture(this.canvas); 14 | this.output.minFilter = THREE.LinearFilter; 15 | this.output.magFilter = THREE.LinearFilter; 16 | 17 | this.lines = []; 18 | for (let i = 0; i < 100; i++) { 19 | const width = 0.05 * Math.random(); 20 | const height = 1 + Math.random(); 21 | this.lines.push({ 22 | width, 23 | height, 24 | x: Math.random() * (16 - width), 25 | y: Math.random() * 13 - 2, 26 | dy: (1 + Math.random()) * 0.8, 27 | }); 28 | } 29 | } 30 | 31 | warmup(renderer) { 32 | this.update(9896); 33 | this.render(renderer); 34 | } 35 | 36 | update(frame) { 37 | this.frame = frame; 38 | } 39 | 40 | render() { 41 | this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); 42 | 43 | this.ctx.save(); 44 | this.ctx.scale(GU, GU); 45 | this.ctx.translate(16 / 2, 9 / 2); 46 | 47 | let t = (this.frame - FRAME_FOR_BEAN(3720 - 6)) / ( 48 | FRAME_FOR_BEAN(3720) - FRAME_FOR_BEAN(3720 - 6)); 49 | 50 | if (t < 0.9999) { 51 | this.ctx.save(); 52 | this.ctx.translate( 53 | easeIn(0, -16, t), 54 | easeIn(0, -9 / 3 / 2, t)); 55 | this.ctx.fillStyle = '#82052c'; 56 | const fudge = 0.05; 57 | this.ctx.translate(8, 4.5); 58 | this.ctx.scale(2, 2); 59 | this.ctx.beginPath(); 60 | this.ctx.moveTo(-8 + 0, -4.5 + 0); 61 | this.ctx.lineTo(-8 + 16, -4.5 + 0); 62 | this.ctx.lineTo(-8 + 16 + (9 / 3 / 2) * 16 / 9, -4.5 + fudge); 63 | this.ctx.lineTo(-8 + 16 / 3 / 2, -4.5 + 9 + fudge); 64 | this.ctx.lineTo(-8 + 0, -4.5 + 9 + fudge); 65 | this.ctx.lineTo(-8 + 0, -4.5 + 0); 66 | this.ctx.fill(); 67 | this.ctx.restore(); 68 | 69 | this.ctx.translate( 70 | easeIn(0, 16, t), 71 | 0); 72 | this.ctx.fillStyle = '#500019'; 73 | if (BEAN > 3750) { 74 | this.ctx.fillStyle = 'rgb(55, 60, 63)'; 75 | } 76 | this.ctx.save(); 77 | this.ctx.beginPath(); 78 | this.ctx.translate(8, 4.5); 79 | this.ctx.scale(2, 2); 80 | this.ctx.moveTo(-8 + 16, -4.5 + 9 / 3 / 2); 81 | this.ctx.lineTo(-8 + 16, -4.5 + 9); 82 | this.ctx.lineTo(-8 + 16 / 3 / 2, -4.5 + 9); 83 | this.ctx.lineTo(-8 + 16, -4.5 + 9 / 3 / 2); 84 | this.ctx.fill(); 85 | this.ctx.restore(); 86 | } 87 | 88 | t = (this.frame - FRAME_FOR_BEAN(3672)) / ( 89 | FRAME_FOR_BEAN(3672 + 6) - FRAME_FOR_BEAN(3672)); 90 | 91 | if (BEAN < 3720) { 92 | this.ctx.fillStyle = 'white'; 93 | this.ctx.font = 'bold 1pt schmalibre'; 94 | this.ctx.textBaseline = 'alphabetic'; 95 | this.ctx.textAlign = 'center'; 96 | this.ctx.translate(easeIn(-4, 4.22, t), 4.5); 97 | const scaleT = (this.frame - FRAME_FOR_BEAN(3672 + 6)) / 98 | (FRAME_FOR_BEAN(3672 + 12) - FRAME_FOR_BEAN(3672 + 6)); 99 | let scaleX = easeIn(1.5, 1, t * t); 100 | let scaleY = easeIn(0.5, 1, t * t * t); 101 | if (BEAN >= 3672 + 6) { 102 | scaleX *= easeOut(1.2, 1, scaleT); 103 | scaleY *= easeOut(1.2, 1, scaleT); 104 | } 105 | this.ctx.scale(scaleX, scaleY); 106 | if (BEAN < 3750) { 107 | this.ctx.fillText('JUST', 0, 0.51); 108 | } 109 | } 110 | this.ctx.restore(); 111 | 112 | 113 | this.ctx.save(); 114 | this.ctx.scale(GU, GU); 115 | this.ctx.translate(16 / 2, 9 / 2); 116 | if (BEAN >= 3768 - 6) { 117 | t = (this.frame - FRAME_FOR_BEAN(3768 - 6)) / ( 118 | FRAME_FOR_BEAN(3768) - FRAME_FOR_BEAN(3768 - 6)); 119 | this.ctx.fillStyle = '#ff4982'; 120 | this.ctx.fillStyle = 'rgb(55, 60, 63)'; 121 | this.ctx.fillRect(-16, easeIn(-18, -9, t), 16 + 8, 9 * 2); 122 | this.ctx.fillRect(8, easeIn(9, -9, t), 16 + 8, 18); 123 | 124 | this.ctx.fillStyle = 'white'; 125 | this.ctx.fillStyle = '#77e15d'; 126 | this.ctx.fillStyle = '#ff4982'; 127 | if (BEAN >= 3768) { 128 | for (let i = 0; i < this.lines.length; i++) { 129 | const line = this.lines[i]; 130 | this.ctx.fillRect(line.x, line.y, line.width * 2, line.height); 131 | line.y = line.y - line.dy; 132 | if (line.y + 2 < 0) { 133 | line.y += 9 + line.height; 134 | line.x = Math.random() * (16 - line.width); 135 | } 136 | } 137 | } 138 | } 139 | 140 | this.ctx.restore(); 141 | 142 | this.output.needsUpdate = true; 143 | this.outputs.render.setValue(this.output); 144 | } 145 | 146 | resize() { 147 | this.canvas.width = 16 * GU * 2; 148 | this.canvas.height = 9 * GU * 2; 149 | } 150 | } 151 | 152 | global.featurebg = featurebg; 153 | })(this); 154 | -------------------------------------------------------------------------------- /src/featuretex.js: -------------------------------------------------------------------------------- 1 | (function (global) { 2 | class featuretex extends NIN.Node { 3 | constructor(id) { 4 | super(id, { 5 | outputs: { 6 | render: new NIN.TextureOutput() 7 | } 8 | }); 9 | 10 | this.canvas = document.createElement('canvas'); 11 | this.ctx = this.canvas.getContext('2d'); 12 | this.resize(); 13 | this.output = new THREE.VideoTexture(this.canvas); 14 | this.output.minFilter = THREE.LinearFilter; 15 | this.output.magFilter = THREE.LinearFilter; 16 | this.texts = [ 17 | 'PARTY', 18 | 'VISITORS', 19 | 'MUSIC', 20 | 'DEMOS', 21 | 'AND', 22 | 'MORE', 23 | ]; 24 | } 25 | 26 | warmup(renderer) { 27 | this.update(9896); 28 | this.render(renderer); 29 | } 30 | 31 | update(frame) { 32 | this.frame = frame; 33 | } 34 | 35 | render() { 36 | this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); 37 | 38 | this.ctx.save(); 39 | this.ctx.translate(this.canvas.width / 2, this.canvas.height / 2); 40 | this.ctx.scale(GU / 3, GU / 2); 41 | 42 | this.ctx.fillStyle = 'white'; 43 | this.ctx.font = 'bold 8pt schmalibre'; 44 | this.ctx.textBaseline = 'middle'; 45 | this.ctx.textAlign = 'center'; 46 | const index = (BEAN - 3672) / 24 | 0; 47 | if (this.texts[index]) { 48 | this.ctx.fillText(this.texts[index], 0, 2.3); 49 | } 50 | 51 | const rotation = -0.43; 52 | if (BEAN >= 3816+16) { 53 | this.ctx.save(); 54 | this.ctx.font = '1.1pt schmalibre'; 55 | this.ctx.rotate(rotation); 56 | this.ctx.translate(-12, -6); 57 | this.ctx.fillText('ATARI', 0, 4); 58 | this.ctx.restore(); 59 | } 60 | if (BEAN >= 3816 + 12) { 61 | this.ctx.save(); 62 | this.ctx.font = '1.1pt schmalibre'; 63 | this.ctx.rotate(rotation); 64 | this.ctx.translate(-12, 1); 65 | this.ctx.fillText('LIVE-CODING', 0, 0.4); 66 | this.ctx.restore(); 67 | } 68 | 69 | if (BEAN >= 3816 + 15) { 70 | this.ctx.save(); 71 | this.ctx.font = '1.1pt schmalibre'; 72 | this.ctx.rotate(rotation - 0.0865); 73 | this.ctx.translate(-5.1, -13); 74 | this.ctx.fillText('BONFIRE', 0, 4); 75 | this.ctx.restore(); 76 | } 77 | if (BEAN >= 3816 + 1) { 78 | this.ctx.save(); 79 | this.ctx.font = '1.1pt schmalibre'; 80 | this.ctx.rotate(rotation - 0.083); 81 | this.ctx.translate(-5.0, -17.0); 82 | this.ctx.fillText('DRINKS', 0, 4); 83 | this.ctx.restore(); 84 | } 85 | if (BEAN >= 3816 + 7) { 86 | this.ctx.save(); 87 | this.ctx.font = '1.1pt schmalibre'; 88 | this.ctx.translate(-3.2, 6.0); 89 | this.ctx.rotate(rotation-0.09); 90 | this.ctx.fillText('OLDSKOOL', -0.5, 4); 91 | this.ctx.restore(); 92 | } 93 | 94 | if (BEAN >= 3816 + 0) { 95 | this.ctx.save(); 96 | this.ctx.font = '1.1pt schmalibre'; 97 | this.ctx.rotate(rotation - 0.02); 98 | this.ctx.translate(0, -6); 99 | this.ctx.fillText('AMIGA', 0, 4); 100 | this.ctx.restore(); 101 | } 102 | if (BEAN >= 3816 + 10) { 103 | this.ctx.save(); 104 | this.ctx.font = '1.1pt schmalibre'; 105 | this.ctx.rotate(rotation - 0.02); 106 | this.ctx.translate(0, 1); 107 | this.ctx.fillText('CONCERTS', 0, 0.4); 108 | this.ctx.restore(); 109 | } 110 | if (BEAN >= 3816 + 2) { 111 | this.ctx.save(); 112 | this.ctx.font = '1.1pt schmalibre'; 113 | this.ctx.rotate(rotation); 114 | this.ctx.translate(0, 1); 115 | this.ctx.fillText('MUSIC', 5, 7.0); 116 | this.ctx.restore(); 117 | } 118 | if (BEAN >= 3816 + 5) { 119 | this.ctx.save(); 120 | this.ctx.font = '1.1pt schmalibre'; 121 | this.ctx.rotate(rotation); 122 | this.ctx.translate(5.9, -8.5); 123 | this.ctx.fillText('FOOD', 0, 0); 124 | this.ctx.restore(); 125 | } 126 | if (BEAN >= 3816 + 3) { 127 | this.ctx.save(); 128 | this.ctx.font = '1.1pt schmalibre'; 129 | this.ctx.rotate(rotation); 130 | this.ctx.translate(5.2, 1); 131 | this.ctx.fillText('GRAPHICS', 0, 10.5); 132 | this.ctx.restore(); 133 | } 134 | if (BEAN >= 3816 + 9) { 135 | this.ctx.save(); 136 | this.ctx.font = '1.1pt schmalibre'; 137 | this.ctx.rotate(rotation); 138 | this.ctx.translate(12, -6); 139 | this.ctx.fillText('C64', 0, 4); 140 | this.ctx.restore(); 141 | } 142 | if (BEAN >= 3816 + 4) { 143 | this.ctx.save(); 144 | this.ctx.font = '1.1pt schmalibre'; 145 | this.ctx.translate(11.8, -4.4); 146 | this.ctx.rotate(rotation + 0.02); 147 | this.ctx.fillText('SEMINARS', 0, 0.4); 148 | this.ctx.restore(); 149 | } 150 | if (BEAN >= 3816 + 13) { 151 | this.ctx.save(); 152 | this.ctx.font = '1.1pt schmalibre'; 153 | this.ctx.translate(19, 1.5); 154 | this.ctx.rotate(rotation+0.16); 155 | this.ctx.fillText('FRIENDSHIP', 0, 0); 156 | this.ctx.restore(); 157 | } 158 | if (BEAN >= 3816 + 11) { 159 | this.ctx.save(); 160 | this.ctx.font = '1.1pt schmalibre'; 161 | this.ctx.rotate(rotation + 0.18); 162 | this.ctx.translate(19, 9.8); 163 | this.ctx.fillText('LIVESTREAM', 0, 0); 164 | this.ctx.restore(); 165 | } 166 | if (BEAN >= 3816 + 8) { 167 | this.ctx.save(); 168 | this.ctx.font = '1.1pt schmalibre'; 169 | this.ctx.translate(24.8, -9); 170 | this.ctx.rotate(rotation + 0.14); 171 | this.ctx.fillText('PHOTOWALL', 0, 0.4); 172 | this.ctx.restore(); 173 | } 174 | if (BEAN >= 3816 + 6) { 175 | this.ctx.save(); 176 | this.ctx.font = '1.1pt schmalibre'; 177 | this.ctx.translate(21.8, -11.5); 178 | this.ctx.rotate(rotation+0.12); 179 | this.ctx.fillText('PC', 0, 0.4); 180 | this.ctx.restore(); 181 | } 182 | if (BEAN >= 3816 + 14) { 183 | this.ctx.save(); 184 | this.ctx.font = '1.1pt schmalibre'; 185 | this.ctx.translate(30, 11.4); 186 | this.ctx.rotate(rotation + 0.32); 187 | this.ctx.fillText('WORKSHOP', 0, 0); 188 | this.ctx.restore(); 189 | } 190 | 191 | this.ctx.restore(); 192 | 193 | this.output.needsUpdate = true; 194 | this.outputs.render.setValue(this.output); 195 | } 196 | 197 | resize() { 198 | this.canvas.width = 2 * 16 * GU; 199 | this.canvas.height = 2 * 9 * GU; 200 | } 201 | } 202 | 203 | global.featuretex = featuretex; 204 | })(this); 205 | -------------------------------------------------------------------------------- /src/globetextures.js: -------------------------------------------------------------------------------- 1 | (function(global) { 2 | class globetextures extends NIN.Node { 3 | constructor(id, options) { 4 | super(id, { 5 | outputs: { 6 | globeTextures: new NIN.Output() 7 | } 8 | }); 9 | 10 | const mapDetail = Loader.loadTexture('res/earth-map-detail.png'); 11 | mapDetail.repeat.set(4, 4); 12 | mapDetail.offset.set(-1.5, -2.5); 13 | 14 | this.outputs.globeTextures.value = { 15 | map: Loader.loadTexture('res/earth-map.png'), 16 | mapDetail, 17 | }; 18 | } 19 | } 20 | 21 | global.globetextures = globetextures; 22 | })(this); 23 | -------------------------------------------------------------------------------- /src/griddymidNode.js: -------------------------------------------------------------------------------- 1 | (function(global) { 2 | class griddymidNode extends NIN.ShaderNode { 3 | constructor(id, options) { 4 | options.shader = 'griddymid'; 5 | super(id, options); 6 | 7 | this.renderTarget = new THREE.WebGLRenderTarget(640, 360, { 8 | minFilter: THREE.LinearFilter, 9 | magFilter: THREE.LinearFilter, 10 | format: THREE.RGBAFormat 11 | }); 12 | this.resize(); 13 | } 14 | 15 | resize() { 16 | this.renderTarget.setSize(640 / 2, 360 / 2); 17 | } 18 | 19 | warmup(renderer) { 20 | this.update(5773); 21 | this.render(renderer); 22 | } 23 | 24 | update(frame) { 25 | this.uniforms.frame.value = frame; 26 | } 27 | } 28 | 29 | global.griddymidNode = griddymidNode; 30 | })(this); 31 | -------------------------------------------------------------------------------- /src/holeTransitionNode.js: -------------------------------------------------------------------------------- 1 | (function(global) { 2 | class holeTransitionNode extends NIN.ShaderNode { 3 | constructor(id, options) { 4 | options.inputs = { 5 | A: new NIN.TextureInput(), 6 | B: new NIN.TextureInput() 7 | }; 8 | super(id, options); 9 | } 10 | 11 | beforeUpdate(frame) { 12 | this.inputs.A.enabled = true; 13 | this.inputs.B.enabled = BEAN >= 2948; 14 | } 15 | 16 | warmup(renderer) { 17 | this.update(4273); 18 | this.render(renderer); 19 | } 20 | 21 | update(frame) { 22 | this.uniforms.t.value = frame; 23 | this.uniforms.A.value = this.inputs.A.getValue(); 24 | this.uniforms.B.value = this.inputs.B.getValue(); 25 | } 26 | } 27 | 28 | global.holeTransitionNode = holeTransitionNode; 29 | })(this); 30 | -------------------------------------------------------------------------------- /src/jaws.js: -------------------------------------------------------------------------------- 1 | (function (global) { 2 | 3 | class jaws extends NIN.Node { 4 | constructor(id) { 5 | super(id, { 6 | outputs: { 7 | render: new NIN.TextureOutput(), 8 | } 9 | }); 10 | 11 | this.canvas = document.createElement('canvas'); 12 | this.ctx = this.canvas.getContext('2d'); 13 | this.resize(); 14 | this.output = new THREE.VideoTexture(this.canvas); 15 | this.output.minFilter = THREE.LinearFilter; 16 | this.output.magFilter = THREE.LinearFilter; 17 | 18 | const scrollolo = 'NO SCROLLERS JUST'; 19 | this.textCanvas = document.createElement('canvas'); 20 | const textCtx = this.textCanvas.getContext('2d'); 21 | 22 | document.fonts.load('bold 72px schmalibre').then(() => { 23 | textCtx.fillStyle = 'rgba(119, 225, 93, 1)'; 24 | textCtx.font = 'bold 72px schmalibre'; 25 | textCtx.textAlign = 'center'; 26 | textCtx.textBaseline = 'middle'; 27 | 28 | const scrolloloMeasured = textCtx.measureText(scrollolo); 29 | this.textCanvas.height = 64; 30 | this.textCanvas.width = scrolloloMeasured.width; 31 | 32 | textCtx.fillStyle = 'rgba(119, 225, 93, 1)'; 33 | textCtx.font = 'bold 72px schmalibre'; 34 | textCtx.textAlign = 'center'; 35 | textCtx.textBaseline = 'middle'; 36 | 37 | textCtx.fillText(scrollolo, this.textCanvas.width / 2, 11.5 + this.textCanvas.height / 2); 38 | }); 39 | } 40 | 41 | resize() { 42 | this.canvas.width = 16 * GU; 43 | this.canvas.height = 9 * GU; 44 | } 45 | 46 | warmup(renderer) { 47 | this.update(1586); 48 | this.render(renderer); 49 | } 50 | 51 | update(frame) { 52 | super.update(frame); 53 | this.frame = frame; 54 | } 55 | 56 | render() { 57 | this.ctx.fillStyle = 'rgb(55, 60, 63)'; 58 | this.ctx.strokeStyle = 'rgb(55, 60, 63)'; 59 | this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); 60 | this.ctx.save(); 61 | this.ctx.scale(GU, GU); 62 | 63 | this.ctx.lineWidth = 0.05; 64 | 65 | const startBEAN = 32 * 48; 66 | const timings = { 67 | 0: FRAME_FOR_BEAN(startBEAN), 68 | 2: FRAME_FOR_BEAN(startBEAN + 9), 69 | 4: FRAME_FOR_BEAN(startBEAN + 18), 70 | 6: FRAME_FOR_BEAN(startBEAN + 24), 71 | 8: FRAME_FOR_BEAN(startBEAN + 28), 72 | 10: FRAME_FOR_BEAN(startBEAN + 34), 73 | 12: FRAME_FOR_BEAN(startBEAN + 36), 74 | 14: FRAME_FOR_BEAN(startBEAN + 40), 75 | 16: FRAME_FOR_BEAN(startBEAN + 41), 76 | 18: FRAME_FOR_BEAN(startBEAN + 42), 77 | 20: FRAME_FOR_BEAN(startBEAN + 46), 78 | 22: FRAME_FOR_BEAN(startBEAN + 48), 79 | 24: FRAME_FOR_BEAN(startBEAN + 54), 80 | 26: FRAME_FOR_BEAN(startBEAN + 60), 81 | 28: FRAME_FOR_BEAN(startBEAN + 64), 82 | 30: FRAME_FOR_BEAN(startBEAN + 70), 83 | }; 84 | 85 | for (let i = 0; i < 32; i += 2) { 86 | if (i % 4 != 0) { 87 | this.ctx.fillStyle = 'rgb(255, 73, 130)'; 88 | this.ctx.fillStyle = '#77e15d'; 89 | this.ctx.fillStyle = 'white'; 90 | this.ctx.fillStyle = '#77e15d'; 91 | this.ctx.fillStyle = 'rgb(55, 60, 63)'; 92 | this.ctx.fillStyle = 'rgb(255, 73, 130)'; 93 | this.ctx.fillStyle = '#77e15d'; 94 | this.ctx.fillStyle = '#98d19b'; 95 | this.ctx.fillStyle = 'rgb(55, 60, 63)'; 96 | } else { 97 | this.ctx.fillStyle = 'rgb(255, 73, 130)'; 98 | this.ctx.fillStyle = '#77e15d'; 99 | this.ctx.fillStyle = 'rgb(55, 60, 53)'; 100 | this.ctx.fillStyle = 'rgb(255, 73, 130)'; 101 | this.ctx.fillStyle = 'white'; 102 | this.ctx.fillStyle = '#77e15d'; 103 | this.ctx.fillStyle = '#98d19b'; 104 | this.ctx.fillStyle = 'rgb(55, 60, 63)'; 105 | } 106 | const t = 107 | easeIn(1, 0, (this.frame - timings[i] + 15) / 15); 108 | this.ctx.save(); 109 | this.ctx.translate(8, 4.5); 110 | this.ctx.rotate(+Math.PI * 2 * i / 32 - this.frame / 100 + 1 + Math.PI / 2); 111 | this.ctx.beginPath(); 112 | this.ctx.moveTo(0, 10 * t); 113 | this.ctx.lineTo(0 - 1.5, 10 + 10 * t); 114 | this.ctx.lineTo(0 + 1.5, 10 + 10 * t); 115 | this.ctx.lineTo(0, 10 * t); 116 | this.ctx.fill(); 117 | this.ctx.stroke(); 118 | this.ctx.restore(); 119 | } 120 | 121 | this.ctx.fillStyle = 'rgb(55, 60, 63)'; 122 | this.ctx.beginPath(); 123 | let t2 = elasticOut(0, 0.4, 1.5, (this.frame - 4006 + 10) / 20); 124 | for (const timing of Object.values(timings)) { 125 | if (timing <= this.frame) { 126 | t2 = lerp(0.6, 0.4, (this.frame - timing) / 10); 127 | } 128 | } 129 | this.ctx.arc(8, 4.5, t2, 0, Math.PI * 2); 130 | this.ctx.fill(); 131 | 132 | this.ctx.save(); 133 | 134 | this.ctx.arc(8, 4.5, t2, 0, Math.PI * 2); 135 | this.ctx.clip(); 136 | 137 | this.ctx.translate(8, 4.5); 138 | this.ctx.scale(t2, -t2); 139 | this.ctx.scale(1 / 64, 1 / 64); 140 | 141 | const scrollOffset = lerp( 142 | 70, 143 | -20 - this.textCanvas.width, 144 | (this.frame - 4016) / (4215 - 4016) 145 | ); 146 | 147 | for (let pixelOffset = 0; pixelOffset < this.textCanvas.width; pixelOffset++) { 148 | this.ctx.drawImage( 149 | this.textCanvas, 150 | pixelOffset, 151 | 0, 152 | 2, 153 | this.textCanvas.height, 154 | scrollOffset + pixelOffset, 155 | -this.textCanvas.height / 2 + 20 * Math.sin(pixelOffset / 100 + this.frame / 60 / 60 * 115 * Math.PI), 156 | 2, 157 | this.textCanvas.height 158 | ); 159 | } 160 | 161 | this.ctx.restore(); 162 | this.ctx.restore(); 163 | 164 | this.output.needsUpdate = true; 165 | this.outputs.render.setValue(this.output); 166 | } 167 | } 168 | 169 | global.jaws = jaws; 170 | })(this); 171 | -------------------------------------------------------------------------------- /src/justTransitionNode.js: -------------------------------------------------------------------------------- 1 | (function (global) { 2 | class justTransitionNode extends NIN.ShaderNode { 3 | constructor(id, options) { 4 | options.inputs = { 5 | A: new NIN.TextureInput(), 6 | B: new NIN.TextureInput(), 7 | }; 8 | super(id, options); 9 | 10 | this.textCanvas = document.createElement('canvas'); 11 | this.textCtx = this.textCanvas.getContext('2d'); 12 | this.textTexture = new THREE.CanvasTexture(this.textCanvas); 13 | this.textTexture.minFilter = THREE.NearestFilter; 14 | this.textTexture.magFilter = THREE.NearestFilter; 15 | this.resize(); 16 | } 17 | 18 | resize() { 19 | super.resize(); 20 | if (this.textCanvas) { 21 | this.textCanvas.width = 16 * GU; 22 | this.textCanvas.height = 9 * GU; 23 | } 24 | } 25 | 26 | warmup(renderer) { 27 | this.update(2221); 28 | this.render(renderer); 29 | } 30 | 31 | beforeUpdate(frame) { 32 | const atariSceneStart = FRAME_FOR_BEAN(48 * 18); 33 | const animationFinished = FRAME_FOR_BEAN(48 * 18.25); 34 | 35 | this.inputs.A.enabled = frame < animationFinished; 36 | this.inputs.B.enabled = frame >= atariSceneStart - 200; 37 | } 38 | 39 | update(frame) { 40 | const t3 = (frame - FRAME_FOR_BEAN(864)) / ( 41 | FRAME_FOR_BEAN(864 + 0) - FRAME_FOR_BEAN(864)); 42 | const rectPositionY = easeOut(-2, 9, t3); 43 | 44 | this.textCtx.save(); 45 | this.textCtx.scale(GU, GU); 46 | 47 | this.textCtx.textBaseline = 'middle'; 48 | this.textCtx.fillStyle = '#ff0000'; 49 | this.textCtx.fillRect(0, 0, 16, rectPositionY); 50 | this.textCtx.fillStyle = '#0000ff'; 51 | this.textCtx.fillRect(0, 2.0 + rectPositionY, 16, 9); 52 | this.textCtx.fillStyle = '#ff0000'; 53 | const t = (frame - FRAME_FOR_BEAN(864 - 12)) / ( 54 | FRAME_FOR_BEAN(864 + 0 - 12) - FRAME_FOR_BEAN(864 - 12)); 55 | this.textCtx.fillRect(0, easeOut(-9, 0, t), 16 / 3, 9); 56 | 57 | const t2 = (frame - FRAME_FOR_BEAN(864 - 6)) / ( 58 | FRAME_FOR_BEAN(864 + 0 - 6) - FRAME_FOR_BEAN(864 - 6)); 59 | this.textCtx.fillRect(16 / 3, easeOut(-9, 0, t2), 16 / 3, 9); 60 | 61 | const t4 = (frame - FRAME_FOR_BEAN(864 + 9)) / ( 62 | FRAME_FOR_BEAN(864 + 9 + 3) - FRAME_FOR_BEAN(864 + 9)); 63 | this.textCtx.fillStyle = '#0000ff'; 64 | this.textCtx.fillRect(0, easeOut(3, 4.5, t4), 16, easeOut(3, 0, t4)); 65 | 66 | this.textCtx.restore(); 67 | this.textTexture.needsUpdate = true; 68 | this.uniforms.A.value = this.inputs.A.getValue(); 69 | this.uniforms.B.value = this.inputs.B.getValue(); 70 | this.uniforms.text.value = this.textTexture; 71 | } 72 | } 73 | 74 | global.justTransitionNode = justTransitionNode; 75 | })(this); 76 | -------------------------------------------------------------------------------- /src/logotransition.js: -------------------------------------------------------------------------------- 1 | /* @nocompile */ 2 | (function(global) { 3 | 4 | const paths = { 5 | boxes: [ 6 | new Path2D('M279,318l-7,200L427,633,544,533l25-138L460,271Z'), 7 | new Path2D('M656,326L780,580l55-3,53-287-60-32Z'), 8 | new Path2D('M610,395L535,607l75,116,88-39,45-231Z'), 9 | new Path2D('M901,398L827,662l50,55,116-16,29-307Z'), 10 | new Path2D('M1031,531L994,745l67,77,98-12,81-161L1136,490Z'), 11 | new Path2D('M1164,437l109,251,74-31L1226,401Z'), 12 | new Path2D('M1267,395l27,102,60,7,42-139-53-38Z'), 13 | new Path2D('M1420,313l-79,271,26,49,162,60,153-89-74-311Z'), 14 | ], 15 | letters: [ 16 | new Path2D('M511,503l-96-64s25.311-15.395,26-39c0.722-24.719-15.743-36.4-29-41-18.876-6.552-42.207,2.351-46,4s-33,13-33,13l68,167,28-10-30-71,81,53ZM369,391l16,35s33.737-9.524,23-32C397.959,372.982,369,391,369,391Z'), 17 | new Path2D('M620,451L593,636l73,12,4-27-46-8,9-57,28,4,4-25-29-4,7-49,49,8,4-27Z'), 18 | new Path2D('M716,349l73,175,34-3,14-208-30,3-7,164L744,343Z'), 19 | new Path2D('M914,438l-2,24,24,2L918,636l-23-1-2,20,24,7,47-2,2-20-24-2,19-172,24,2,2-24Z'), 20 | new Path2D('M1163,581s-42.68-45.023-88-17c-35.77,22.122-24.29,78.642,16,105,38.86,25.419,39.91,52.234,23,64-23.47,14.322-55-6-55-6l-5,30s52.25,25.169,80,1c30.19-26.292,25.58-74.069-10-99-31.51-22.082-50.87-42.78-37-67,16.65-29.063,57,6,57,6Z'), 21 | new Path2D('M1224,511l64,142,22-10-64-142Zm-9-64a14,14,0,1,1-14,14A14,14,0,0,1,1215,447Z'), 22 | new Path2D('M1304,415c-1.1,14.374,1.48,42.05,25,43,21.18,0.856,32.69-19.565,34-37,1.49-19.873-6.93-39.362-25-40C1318.38,380.308,1305.31,397.9,1304,415Zm20,4c-0.69,6.98-.42,15.017,7,16,7.84,1.039,12.59-7.13,13-14,0.36-5.973-1.38-13.119-9-14C1328.44,406.242,1324.81,410.77,1324,419Z'), 23 | new Path2D('M1433,366l-62,223,33,9,42-147,62,180,28,7,70-227-34-10-50,163-62-191Z'), 24 | new Path2D('M368,789l13,13s26.925-33.839,45-20c14.169,10.849,1.092,33.632-6,44-6.923,10.121-55,65-55,65v23l88,1V896H384s43.868-45.682,54-62c5.6-9.014,27.1-45.544,2-66-18.457-15.042-44.049-2.86-51,2C382.289,774.692,368,789,368,789Z'), 25 | new Path2D('M469,867c-0.363,22.425,16.543,48.437,40,49,23.01,0.552,48.2-24.3,35-57s-24.429-34.479-41-34C484.936,825.522,469.3,848.545,469,867Zm13,4c0.731,13.746,16.82,31.968,31,30s27.911-17.29,18-40c-8.563-19.622-18.417-24.28-29.627-21.775C484.635,842.965,481.348,858.732,482,871Z'), 26 | new Path2D('M546,772l1,10,26-4,2,144h15l-3-161-21,1Z'), 27 | new Path2D('M653,761c-15.514.874-28.973,11.913-28,31s19,31,19,31-20.122,22.843-16,53,18.942,48.348,41,45,38.989-38.4,35-60c-4.5-24.388-29-43-29-43s16.172-16.412,13-33C684.65,767.479,670.434,760.018,653,761Zm-15,31c0.4,7.809,7.749,22.272,19,20a21.942,21.942,0,0,0,17-25c-1.946-11.5-11.915-14.857-21-14C643.878,773.86,637.457,781.449,638,792Zm4,79c1.154,15.458,11.969,36.016,24,35s28.2-22.469,25-43c-2.851-18.286-13.236-31.151-28-29S640.642,852.8,642,871Z'), 28 | ] 29 | }; 30 | 31 | const animations = { 32 | letterEntry: [{ 33 | y: 1000, t: 1860 - 96, 34 | }, { 35 | y: -1000, 36 | t: 1862 - 96, 37 | }, { 38 | y: 1000, 39 | t: 1864 - 96, 40 | }, { 41 | y: -1000, 42 | t: 1866 - 96, 43 | }, { 44 | y: 1000, 45 | t: 1868 - 96, 46 | }, { 47 | y: -1000, 48 | t: 1870 - 96, 49 | }, { 50 | y: 1000, 51 | t: 1871 - 96, 52 | }, { 53 | y: -1000, 54 | t: 1872 - 96, 55 | }], 56 | letters: [{ 57 | x: 370, 58 | y: 100, 59 | scale: .55, 60 | rotation: 0.34, 61 | anchor: { 62 | x: 511 - 115, 63 | y: 503 - 60, 64 | } 65 | }, { 66 | x: 210, 67 | y: 0, 68 | scale: .515, 69 | rotation: -0.16, 70 | anchor: { 71 | x: 620 + 15, 72 | y: 451 + 93, 73 | } 74 | }, { 75 | x: 130, 76 | y: 125, 77 | scale: .49, 78 | rotation: 0.16, 79 | anchor: { 80 | x: 716 + 75, 81 | y: 349 + 70, 82 | } 83 | }, { 84 | x: 50, 85 | y: 0, 86 | scale: .45, 87 | rotation: -.09, 88 | anchor: { 89 | x: 914 + 26, 90 | y: 438 + 110, 91 | } 92 | }, { 93 | x: -50, 94 | y: -112, 95 | scale: .48, 96 | rotation: -0.08, 97 | anchor: { 98 | x: 1163 - 60, 99 | y: 581 + 80, 100 | } 101 | }, { 102 | x: -140, 103 | y: 5, 104 | scale: .45, 105 | rotation: .424, 106 | anchor: { 107 | x: 1224 + 25, 108 | y: 511 + 30, 109 | } 110 | }, { 111 | x: -160, 112 | y: 130, 113 | scale: 1.3, 114 | rotation: -.1, 115 | anchor: { 116 | x: 1304 + 30, 117 | y: 415 + 5, 118 | } 119 | }, { 120 | x: -220, 121 | y: 50, 122 | scale: .43, 123 | rotation: -.271, 124 | anchor: { 125 | x: 1433 + 60, 126 | y: 366 + 130, 127 | } 128 | }, 129 | ] 130 | }; 131 | 132 | class logotransition extends NIN.Node { 133 | constructor(id) { 134 | super(id, { 135 | outputs: { 136 | render: new NIN.TextureOutput() 137 | } 138 | }); 139 | 140 | this.canvas = document.createElement('canvas'); 141 | this.ctx = this.canvas.getContext('2d'); 142 | this.resize(); 143 | this.output = new THREE.VideoTexture(this.canvas); 144 | this.output.minFilter = THREE.LinearFilter; 145 | this.output.magFilter = THREE.LinearFilter; 146 | } 147 | 148 | resize() { 149 | this.canvas.width = 16 * GU; 150 | this.canvas.height = 9 * GU; 151 | } 152 | 153 | warmup(renderer) { 154 | this.update(4592); 155 | this.render(renderer); 156 | } 157 | 158 | update(frame) { 159 | super.update(frame); 160 | this.frame = frame; 161 | demo.nm.nodes.bloom.opacity = 0.1; 162 | } 163 | 164 | render() { 165 | const t = (this.frame - 4695 + 10) / 10; 166 | const r = smoothstep(55, 255, t); 167 | const g = smoothstep(60, 73, t); 168 | const b = smoothstep(63, 130, t); 169 | const a = smoothstep(0.1, 1, t); 170 | this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); 171 | this.ctx.fillStyle = `rgba(${r|0}, ${g|0}, ${b|0}, ${a})`; 172 | this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height); 173 | 174 | this.ctx.save(); 175 | this.ctx.scale(GU, GU); 176 | const scale = 16 / 1920; 177 | this.ctx.scale(scale, scale); 178 | 179 | const cameraZoomScale = 1.5; 180 | this.ctx.translate(1920 / 2, 1080 / 2); 181 | if(this.frame >= FRAME_FOR_BEAN(1775) && this.frame < FRAME_FOR_BEAN(1785)) { 182 | this.ctx.rotate(-0.1); 183 | this.ctx.scale(cameraZoomScale, cameraZoomScale); 184 | this.ctx.translate(-100, 10); 185 | } 186 | if(this.frame >= FRAME_FOR_BEAN(1785) && this.frame < FRAME_FOR_BEAN(1800)) { 187 | this.ctx.rotate(0.1); 188 | this.ctx.scale(0.9, 0.9); 189 | this.ctx.translate(-20, 0); 190 | } 191 | this.ctx.translate(-1920 / 2, -1080 / 2); 192 | 193 | { 194 | const shake = easeIn(0, 10, t / 2 + 1); 195 | const angle = Math.random() * Math.PI * 2; 196 | const x = shake * Math.cos(angle); 197 | const y = shake * Math.sin(angle); 198 | this.ctx.translate(x, y); 199 | } 200 | 201 | this.ctx.fillStyle = '#00e04f'; 202 | 203 | for(let item of ['boxes', 'letters']) { 204 | for(let i = 0; i < 8; i++) { 205 | this.ctx.save(); 206 | const animation = animations.letters[i]; 207 | const letterEntry = animations.letterEntry[i]; 208 | let y = easeIn(letterEntry.y, animation.y, (this.frame - FRAME_FOR_BEAN(letterEntry.t) + 20) / 20); 209 | const x = smoothstep(animation.x, 0, t); 210 | y = smoothstep(y, 0, t); 211 | const rotation = smoothstep(animation.rotation, 0, t); 212 | const scale = smoothstep(animation.scale, 1, t); 213 | this.ctx.translate(animation.anchor.x, animation.anchor.y); 214 | this.ctx.translate(x, y); 215 | this.ctx.rotate(rotation); 216 | this.ctx.scale(scale, scale); 217 | this.ctx.translate(-animation.anchor.x, -animation.anchor.y); 218 | if(item === 'boxes') { 219 | const r = 55; 220 | const g = 60; 221 | const b = 63; 222 | const a = smoothstep(0, 0.5, t); 223 | const bgA = smoothstep(0, 1, t); 224 | this.ctx.fillStyle = `rgba(0, 0, 0, ${a})`; 225 | const shadowOffset = 8 / scale; 226 | this.ctx.translate(shadowOffset, shadowOffset * 9 / 16); 227 | this.ctx.fill(paths.boxes[i]); 228 | this.ctx.translate(-shadowOffset, -shadowOffset * 9 / 16); 229 | this.ctx.fillStyle = `rgba(${r | 0}, ${g | 0}, ${b | 0}, ${bgA})`; 230 | this.ctx.fill(paths.boxes[i]); 231 | } else if(item === 'letters') { 232 | this.ctx.fillStyle = 'rgba(0, 0, 0, 0.9)'; 233 | const shadowOffset = 8 / scale; 234 | this.ctx.translate(shadowOffset, shadowOffset * 9 / 16); 235 | this.ctx.fill(paths.letters[i], 'evenodd'); 236 | const r = smoothstep(255, 255, t); 237 | const g = smoothstep(255, 255, t); 238 | const b = smoothstep(255, 255, t); 239 | this.ctx.translate(-shadowOffset, -shadowOffset * 9 / 16); 240 | this.ctx.fillStyle = `rgb(${r|0}, ${g|0}, ${b|0})`; 241 | this.ctx.fill(paths.letters[i], 'evenodd'); 242 | } 243 | 244 | this.ctx.restore(); 245 | } 246 | } 247 | this.ctx.save(); 248 | this.ctx.fillStyle = 'white'; 249 | this.ctx.strokeStyle = 'rgb(255, 73, 130)'; 250 | this.ctx.globalAlpha = smoothstep(0, 1, t); 251 | this.ctx.fill((paths.letters[8]), 'evenodd'); 252 | this.ctx.stroke((paths.letters[8])); 253 | this.ctx.fill((paths.letters[9]), 'evenodd'); 254 | this.ctx.stroke((paths.letters[9])); 255 | this.ctx.fill((paths.letters[10]), 'evenodd'); 256 | this.ctx.stroke((paths.letters[10])); 257 | this.ctx.fill((paths.letters[11]), 'evenodd'); 258 | this.ctx.stroke((paths.letters[11])); 259 | this.ctx.restore(); 260 | 261 | this.ctx.restore(); 262 | this.output.needsUpdate = true; 263 | this.outputs.render.setValue(this.output); 264 | } 265 | } 266 | 267 | global.logotransition = logotransition; 268 | })(this); 269 | -------------------------------------------------------------------------------- /src/logotransitionquadpassNode.js: -------------------------------------------------------------------------------- 1 | (function(global) { 2 | class logotransitionquadpassNode extends NIN.ShaderNode { 3 | constructor(id, options) { 4 | options.inputs = options.inputs || {}; 5 | options.inputs.scene = new NIN.TextureInput(); 6 | options.inputs.logo = new NIN.TextureInput(); 7 | super(id, options); 8 | } 9 | 10 | warmup(renderer) { 11 | this.update(4592); 12 | this.render(renderer); 13 | } 14 | 15 | update(frame) { 16 | this.uniforms.frame.value = frame; 17 | this.uniforms.scene.value = this.inputs.scene.getValue(); 18 | this.uniforms.logo.value = this.inputs.logo.getValue(); 19 | this.uniforms.yOffset.value = 0; 20 | 21 | if(frame >= FRAME_FOR_BEAN(1812)) { 22 | this.uniforms.yOffset.value -= 0.5; 23 | this.uniforms.yOffset.value -= (frame - FRAME_FOR_BEAN(1812)) / 1000; 24 | this.uniforms.yOffset.value += 0.05 * (Math.random() - 0.5); 25 | } 26 | if(frame >= FRAME_FOR_BEAN(1812 + 6)) { 27 | this.uniforms.yOffset.value += 0.5; 28 | this.uniforms.yOffset.value += 0.05 * (Math.random() - 0.5); 29 | } 30 | } 31 | } 32 | 33 | global.logotransitionquadpassNode = logotransitionquadpassNode; 34 | })(this); 35 | -------------------------------------------------------------------------------- /src/lulleNode.js: -------------------------------------------------------------------------------- 1 | (function (global) { 2 | class lulleNode extends NIN.ShaderNode { 3 | constructor(id, options) { 4 | options.inputs = options.inputs || {}; 5 | options.inputs.bg = new NIN.TextureInput(); 6 | super(id, options); 7 | this.balls = 0; 8 | 9 | this.myCamera = new THREE.PerspectiveCamera(45, 16 / 9, 1, 1000); 10 | } 11 | 12 | warmup(renderer) { 13 | this.update(4766); 14 | this.render(renderer); 15 | } 16 | 17 | update(frame) { 18 | const startBEAN = 1848; 19 | if (BEAN < startBEAN + 6) this.balls = 0; 20 | this.uniforms.frame.value = frame; 21 | this.uniforms.tDiffuse.value = this.inputs.bg.getValue(); 22 | this.uniforms.BEAN.value = BEAN; 23 | this.uniforms.BEAT.value = BEAT ? 1 : 0; 24 | demo.nm.nodes.bloom.opacity = easeOut(10, 2.0, Math.pow((frame - FRAME_FOR_BEAN(1824)) / ( 25 | FRAME_FOR_BEAN(1824 + 24) - FRAME_FOR_BEAN(1824)), 2)); 26 | 27 | if (BEAT) { 28 | switch (BEAN) { 29 | case startBEAN + 6: 30 | case startBEAN + 10: 31 | case startBEAN + 6 + 24: 32 | case startBEAN + 10 + 24: 33 | case startBEAN + 6 + 48: 34 | case startBEAN + 10 + 48: 35 | case startBEAN + 6 + 72: 36 | case startBEAN + 10 + 72: 37 | case startBEAN + 6 + 96: 38 | case startBEAN + 10 + 96: 39 | case startBEAN + 6 + 120: 40 | case startBEAN + 10 + 120: 41 | case startBEAN + 6 + 144: 42 | case startBEAN + 10 + 144: 43 | case startBEAN + 6 + 168: 44 | case startBEAN + 10 + 168: 45 | case startBEAN + 18: 46 | case startBEAN + 18 + 24: 47 | case startBEAN + 18 + 48: 48 | case startBEAN + 18 + 72: 49 | case startBEAN + 18 + 96: 50 | case startBEAN + 18 + 120: 51 | case startBEAN + 18 + 144: 52 | case startBEAN + 18 + 168: 53 | this.balls += 1; 54 | break; 55 | } 56 | } 57 | if (BEAN >= 2016) { 58 | this.balls = 9999; 59 | } 60 | this.uniforms.numOfBalls.value = this.balls; 61 | 62 | let cameraDirection = new THREE.Vector3(0, 0, 0); 63 | this.myCamera.position.set(0, 0, 20); 64 | if (BEAN >= 1992 + 12 + 10) { 65 | this.myCamera.position.set(0, 0, 20); 66 | } else if (BEAN >= 1992 + 12 + 4) { 67 | this.myCamera.position.set(-1, 1, 15); 68 | } else if (BEAN >= 1992 + 12) { 69 | this.myCamera.position.set(1, 1, 15); 70 | } else if (BEAN >= 1992 + 10) { 71 | this.myCamera.position.set(-1, -1, 15); 72 | } else if (BEAN >= 1992 + 4) { 73 | this.myCamera.position.set(1, -1, 15); 74 | } else if (BEAN >= 1992) { 75 | this.myCamera.position.set(-1, 0, 15); 76 | } 77 | 78 | this.uniforms.cameraDirection.value = cameraDirection; 79 | this.uniforms.myCameraPosition.value = this.myCamera.position; 80 | } 81 | } 82 | 83 | global.lulleNode = lulleNode; 84 | })(this); 85 | -------------------------------------------------------------------------------- /src/metatronoverlayerNode.js: -------------------------------------------------------------------------------- 1 | (function (global) { 2 | 3 | function T(startBean, endBean, frame) { 4 | const startFrame = FRAME_FOR_BEAN(startBean); 5 | const endFrame = FRAME_FOR_BEAN(endBean); 6 | return (frame - startFrame) / (endFrame - startFrame); 7 | } 8 | 9 | class metatronoverlayerNode extends NIN.ShaderNode { 10 | constructor(id, options) { 11 | options.inputs = options.inputs || {}; 12 | options.inputs.tDiffuse = new NIN.TextureInput(); 13 | super(id, options); 14 | 15 | this.canvas = document.createElement('canvas'); 16 | this.ctx = this.canvas.getContext('2d'); 17 | this.resize(); 18 | this.canvasTexture = new THREE.CanvasTexture(this.canvas); 19 | this.canvasTexture.magFilter = THREE.LinearFilter; 20 | this.canvasTexture.minFilter = THREE.LinearFilter; 21 | 22 | this.textCanvas = document.createElement('canvas'); 23 | this.textCtx = this.textCanvas.getContext('2d'); 24 | 25 | this.resize(); 26 | } 27 | 28 | warmup(renderer) { 29 | this.update(2764); 30 | this.render(renderer); 31 | } 32 | 33 | resize() { 34 | super.resize(); 35 | if (this.canvas) { 36 | this.canvas.width = 16 * GU; 37 | this.canvas.height = 9 * GU; 38 | } 39 | } 40 | 41 | update(frame) { 42 | if (this.textCanvas) { 43 | this.textCanvas.width = 9 * GU; 44 | this.textCanvas.height = 4 * GU; 45 | 46 | this.textCtx.save(); 47 | this.textCtx.scale(0.9 * GU, 0.9 * GU); 48 | this.textCtx.translate(5, 1); 49 | this.textCtx.textAlign = 'center'; 50 | this.textCtx.textBaseline = 'alphabetic'; 51 | this.textCtx.font = 'bold 1pt schmalibre'; 52 | this.textCtx.fillStyle = 'white'; 53 | this.textCtx.fillText('NO EUCLIDEAN', 0, 0.51); 54 | this.textCtx.restore(); 55 | 56 | this.textCtx.save(); 57 | this.textCtx.scale(0.9 * GU, 0.9 * GU); 58 | this.textCtx.translate(5, 2.5); 59 | this.textCtx.textAlign = 'center'; 60 | this.textCtx.textBaseline = 'alphabetic'; 61 | this.textCtx.font = 'bold 1pt schmalibre'; 62 | this.textCtx.fillStyle = 'white'; 63 | this.textCtx.fillText('GEOMETRIES', 0, 0.51); 64 | this.textCtx.restore(); 65 | } 66 | this.frame = frame; 67 | this.uniforms.frame.value = frame; 68 | var start = 23.11; 69 | let t = Math.pow(Math.max(0, T(start * 48, start * 48 + 12, frame)), 2.5); 70 | 71 | this.uniforms.translationOverX.value = easeIn(0.5, 0, t); 72 | this.uniforms.translationUnderX.value = easeIn(0, -0.15, t); 73 | 74 | var end = 24.75 - 3 / 48; 75 | if (BEAN >= end * 48) { 76 | t = 1 - T(end * 48, end * 48 + 12, frame); 77 | this.uniforms.translationOverX.value = easeIn(0.5, 0, t); 78 | this.uniforms.translationUnderX.value = easeIn(0, -0.15, t); 79 | } 80 | 81 | this.uniforms.tDiffuse.value = this.inputs.tDiffuse.getValue(); 82 | } 83 | 84 | render(renderer) { 85 | this.ctx.save(); 86 | this.ctx.scale(GU, GU); 87 | 88 | const nudger = 0.5; 89 | this.ctx.beginPath(); 90 | this.ctx.moveTo(0, 0); 91 | this.ctx.lineTo(16 / 3 - nudger, 0); 92 | this.ctx.lineTo(16 / 3 + nudger, 9); 93 | this.ctx.lineTo(0, 9); 94 | this.ctx.lineTo(0, 0); 95 | this.ctx.fillStyle = '#282b2d'; 96 | this.ctx.fill(); 97 | 98 | this.ctx.font = 'bold 1pt schmalibre'; 99 | this.ctx.textAlign = 'center'; 100 | this.ctx.textBaseline = 'top'; 101 | this.ctx.translate(16 / 3 - nudger, 9 / 2); 102 | this.ctx.rotate(Math.PI / 2 - 0.11); 103 | this.ctx.fillStyle = 'white'; 104 | this.ctx.translate(-4.5, -.5); 105 | this.ctx.translate(0, 1.5); 106 | const bouncyScale = 1; 107 | this.ctx.scale(1 / GU, 1 / GU * bouncyScale); 108 | this.ctx.translate(0, -1.5 * GU); 109 | const step = 4; 110 | for (let i = 0; i < this.textCanvas.height; i += step) { 111 | this.ctx.drawImage( 112 | this.textCanvas, 113 | 0, 114 | i, 115 | this.textCanvas.width, 116 | step + 1, 117 | 0, 118 | i, 119 | this.textCanvas.width, 120 | step + 1); 121 | } 122 | 123 | this.ctx.restore(); 124 | this.canvasTexture.needsUpdate = true; 125 | this.uniforms.overlay.value = this.canvasTexture; 126 | super.render(renderer); 127 | } 128 | } 129 | 130 | global.metatronoverlayerNode = metatronoverlayerNode; 131 | })(this); 132 | -------------------------------------------------------------------------------- /src/pyramidfxNode.js: -------------------------------------------------------------------------------- 1 | (function(global) { 2 | class pyramidfxNode extends NIN.ShaderNode { 3 | constructor(id, options) { 4 | options.inputs = options.inputs || {}; 5 | options.inputs.tDiffuse = new NIN.TextureInput(); 6 | super(id, options); 7 | } 8 | 9 | warmup(renderer) { 10 | this.update(5775); 11 | this.render(renderer); 12 | } 13 | 14 | update(frame) { 15 | this.uniforms.frame.value = frame; 16 | const startBean = 2400 - 1; 17 | const endBean = 2400 + 4; 18 | this.uniforms.barSize.value = elasticOut( 19 | 0, 20 | 0.15, 21 | 1.2, 22 | (frame - FRAME_FOR_BEAN(startBean)) / ( 23 | FRAME_FOR_BEAN(endBean) - FRAME_FOR_BEAN(startBean))); 24 | this.uniforms.tDiffuse.value = this.inputs.tDiffuse.getValue(); 25 | } 26 | } 27 | 28 | global.pyramidfxNode = pyramidfxNode; 29 | })(this); 30 | -------------------------------------------------------------------------------- /src/pyramidsoverlay.js: -------------------------------------------------------------------------------- 1 | (function (global) { 2 | 3 | function timer(startBean, endBean, frame) { 4 | const startFrame = FRAME_FOR_BEAN(startBean); 5 | const endFrame = FRAME_FOR_BEAN(endBean); 6 | return (frame - startFrame) / (endFrame - startFrame); 7 | } 8 | 9 | class pyramidsoverlay extends NIN.Node { 10 | constructor(id) { 11 | super(id, { 12 | outputs: { 13 | render: new NIN.TextureOutput() 14 | } 15 | }); 16 | this.snareThrob = 0; 17 | this.canvas = document.createElement('canvas'); 18 | this.ctx = this.canvas.getContext('2d'); 19 | this.resize(); 20 | this.output = new THREE.CanvasTexture(this.canvas); 21 | this.output.minFilter = THREE.LinearFilter; 22 | this.output.magFilter = THREE.LinearFilter; 23 | } 24 | 25 | warmup(renderer) { 26 | this.update(5775); 27 | this.render(renderer); 28 | } 29 | 30 | update(frame) { 31 | this.snareThrob *= 0.95; 32 | this.frame = frame; 33 | if (BEAT) { 34 | switch (BEAN) { 35 | case 2208: 36 | case 2232: 37 | case 2280: 38 | case 2328: 39 | case 2400: 40 | case 2424: 41 | case 2472: 42 | this.snareThrob = 1; 43 | } 44 | } 45 | } 46 | 47 | render(renderer) { 48 | const frame = this.frame; 49 | this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); 50 | 51 | this.ctx.save(); 52 | this.ctx.scale(GU, GU); 53 | 54 | this.ctx.fillStyle = 'rgb(8, 10, 12)'; 55 | this.ctx.fillRect(10.5, 9 / 3 * 2 - this.snareThrob * 0.25, 16, 1.5 + this.snareThrob * 0.5); 56 | this.ctx.textAlign = 'right'; 57 | this.ctx.textBaseline = 'alphabetic'; 58 | this.ctx.font = '0.7pt schmalibre-light'; 59 | this.ctx.fillStyle = '#88c2a0'; 60 | this.ctx.globalAlpha = 0.4 + Math.random() * 0.2; 61 | const t = timer(2208 + 12, 2208 + 24, frame); 62 | const t2 = timer(2208 + 48 + 12, 2208 + 48 + 24, frame); 63 | this.ctx.fillText('NO LASERS', 15.4 + easeIn(2, 0, t) - easeIn(0, -3, t2), 6.5 + 0.51); 64 | 65 | this.ctx.globalAlpha = 1; 66 | this.ctx.clearRect(10.5, 0, easeIn(5.5, 0, t) + easeIn(0, 5.5, t2), 9); 67 | 68 | this.ctx.fillStyle = 'rgb(8, 10, 12)'; 69 | this.ctx.fillRect(0, 2.5 - this.snareThrob * 0.25, 7, 1.5 + this.snareThrob * 0.5); 70 | this.ctx.textAlign = 'left'; 71 | this.ctx.textBaseline = 'alphabetic'; 72 | this.ctx.font = '0.7pt schmalibre-light'; 73 | this.ctx.fillStyle = '#88c2a0'; 74 | this.ctx.globalAlpha = 0.4 + Math.random() * 0.2; 75 | const t3 = timer(2208 + 96 + 12, 2208 + 96 + 24, frame); 76 | const t4 = timer(2208 + 96 + 48 + 12, 2208 + 96 + 48 + 24, frame); 77 | this.ctx.fillText('JUST REVISION', 0.6 - easeIn(2, 0, t3) - easeIn(0, 3, t4), 3 + 0.51); 78 | 79 | this.ctx.clearRect(easeIn(0, 7, t3) - easeIn(0, 7, t4), 0, 16, 5); 80 | 81 | 82 | this.ctx.globalAlpha = this.snareThrob * 0.25; 83 | this.ctx.fillRect(0, 0, 16, 9); 84 | 85 | this.ctx.restore(); 86 | this.output.needsUpdate = true; 87 | this.outputs.render.setValue(this.output); 88 | } 89 | 90 | resize() { 91 | this.canvas.width = 16 * GU; 92 | this.canvas.height = 9 * GU; 93 | } 94 | } 95 | 96 | global.pyramidsoverlay = pyramidsoverlay; 97 | })(this); 98 | -------------------------------------------------------------------------------- /src/revisionBars.js: -------------------------------------------------------------------------------- 1 | (function (global) { 2 | class revisionBars extends NIN.THREENode { 3 | constructor(id) { 4 | super(id, { 5 | outputs: { 6 | render: new NIN.TextureOutput(), 7 | cameraValues: new NIN.Output(), 8 | } 9 | }); 10 | 11 | this.throb = 0; 12 | 13 | this.cameraX = 0; 14 | this.cameraY = 0; 15 | this.cameraR = 0; 16 | this.cameraDX = 0; 17 | this.cameraDY = 0; 18 | this.cameraDR = 0; 19 | this.cameraDDX = 0; 20 | this.cameraDDY = 0; 21 | this.cameraDDR = 0; 22 | this.cameraPreviousX = 0; 23 | this.cameraPreviousY = 0; 24 | 25 | this.canvas = document.createElement('canvas'); 26 | this.ctx = this.canvas.getContext('2d'); 27 | this.resize(); 28 | this.output = new THREE.VideoTexture(this.canvas); 29 | this.output.minFilter = THREE.LinearFilter; 30 | this.output.magFilter = THREE.LinearFilter; 31 | this.outputs.cameraValues.value = { 32 | cameraX: 0, 33 | cameraY: 0, 34 | cameraZoom: 0, 35 | cameraRotate: 0, 36 | }; 37 | 38 | this.textScript = [ 39 | { 40 | letter: 'R', 41 | x: 0, 42 | height: 5, 43 | beanOffset: 0, 44 | }, 45 | { 46 | letter: 'E', 47 | x: 1, 48 | height: 4.5, 49 | beanOffset: 9, 50 | }, 51 | { 52 | letter: 'V', 53 | x: 2, 54 | height: 3, 55 | beanOffset: 24, 56 | }, 57 | { 58 | letter: 'I', 59 | x: 3, 60 | height: 3.5, 61 | beanOffset: 33, 62 | }, 63 | { 64 | letter: 'S', 65 | x: 4, 66 | height: 4, 67 | beanOffset: 42, 68 | }, 69 | { 70 | letter: 'I', 71 | x: 5, 72 | height: 5, 73 | beanOffset: 62, 74 | }, 75 | { 76 | letter: 'O', 77 | x: 6, 78 | height: 4.5, 79 | beanOffset: 62, 80 | }, 81 | { 82 | letter: 'N', 83 | x: 7, 84 | height: 3, 85 | beanOffset: 74, 86 | }, 87 | ]; 88 | 89 | for (let i = 0; i < this.textScript.length; i++) { 90 | const el = this.textScript[i]; 91 | el.x -= 8; 92 | } 93 | 94 | this.easings = { 95 | lerp, 96 | smoothstep, 97 | easeIn, 98 | easeOut, 99 | step: (a, b, t) => (t >= 1 ? b : a), 100 | }; 101 | 102 | this.cameraXPath = this.path([ 103 | { bean: 1440, easing: 'step', value: 6.5 }, 104 | 105 | { bean: 1440 + 9 - 3, easing: 'step', value: 6.5 }, 106 | { bean: 1440 + 9, easing: 'easeIn', value: 5.5 }, 107 | 108 | { bean: 1440 + 24 - 3, easing: 'step', value: 5.5 }, 109 | { bean: 1440 + 24, easing: 'easeIn', value: 4.5 }, 110 | 111 | { bean: 1440 + 24 + 9 - 3, easing: 'step', value: 4.5 }, 112 | { bean: 1440 + 24 + 9, easing: 'easeIn', value: 3.5 }, 113 | 114 | { bean: 1440 + 24 + 18 - 3, easing: 'step', value: 3.5 }, 115 | { bean: 1440 + 24 + 18, easing: 'easeIn', value: 2.5 }, 116 | 117 | { bean: 1440 + 48 + 12 - 3, easing: 'step', value: 2.5 }, 118 | { bean: 1440 + 48 + 12, easing: 'easeIn', value: 1.5 }, 119 | 120 | { bean: 1440 + 48 + 24 + 24, easing: 'easeOut', value: 0 }, 121 | ]); 122 | this.cameraYPath = this.path([ 123 | { bean: 1440, easing: 'step', value: 3.5 }, 124 | 125 | { bean: 1440 + 9 - 3, easing: 'step', value: 3.5 }, 126 | { bean: 1440 + 9, easing: 'easeIn', value: 2.5 }, 127 | 128 | { bean: 1440 + 24 - 3, easing: 'step', value: 2.5 }, 129 | { bean: 1440 + 24, easing: 'easeIn', value: 1.5 }, 130 | 131 | { bean: 1440 + 24 + 9 - 3, easing: 'step', value: 1.5 }, 132 | { bean: 1440 + 24 + 9, easing: 'easeIn', value: 0.5 }, 133 | 134 | { bean: 1440 + 24 + 18 - 3, easing: 'step', value: 0.5 }, 135 | { bean: 1440 + 24 + 18, easing: 'easeIn', value: -0.5 }, 136 | 137 | { bean: 1440 + 48 + 12 - 3, easing: 'step', value: -0.5 }, 138 | { bean: 1440 + 48 + 12, easing: 'easeIn', value: -1.5 }, 139 | 140 | { bean: 1440 + 48 + 24 + 24, easing: 'easeOut', value: 0 }, 141 | ]); 142 | this.cameraZoomPath = this.path([ 143 | { bean: 1440 + 48 + 12, easing: 'step', value: 3 }, 144 | { bean: 1440 + 48 + 24 + 6, easing: 'easeOut', value: 1 }, 145 | ]); 146 | this.cameraRotatePath = this.path([ 147 | { bean: 1440, easing: 'step', value: -0.1 }, 148 | 149 | { bean: 1440 + 9 - 3, easing: 'step', value: -0.1 }, 150 | { bean: 1440 + 9, easing: 'easeIn', value: 0.1 }, 151 | 152 | { bean: 1440 + 24 - 3, easing: 'step', value: 0.1 }, 153 | { bean: 1440 + 24, easing: 'easeIn', value: -0.1 }, 154 | 155 | { bean: 1440 + 24 + 9 - 3, easing: 'step', value: -0.1 }, 156 | { bean: 1440 + 24 + 9, easing: 'easeIn', value: 0.1 }, 157 | 158 | { bean: 1440 + 24 + 18 - 3, easing: 'step', value: 0.1 }, 159 | { bean: 1440 + 24 + 18, easing: 'easeIn', value: -0.1 }, 160 | 161 | { bean: 1440 + 48 + 12 - 3, easing: 'step', value: -0.1 }, 162 | { bean: 1440 + 48 + 12, easing: 'easeIn', value: 0.1 }, 163 | 164 | { bean: 1440 + 48 + 24, easing: 'easeOut', value: 0 }, 165 | ]); 166 | } 167 | 168 | path(points) { 169 | for (let i = 0; i < points.length; i++) { 170 | const point = points[i]; 171 | point.frame = FRAME_FOR_BEAN(point.bean); 172 | } 173 | return points; 174 | } 175 | 176 | getPoint(path, frame) { 177 | let from = path[0]; 178 | let to = path[0]; 179 | for (let i = 0; i < path.length; i++) { 180 | const current = path[i]; 181 | if (current.frame <= frame) { 182 | from = current; 183 | if (path[i + 1]) { 184 | to = path[i + 1]; 185 | } else { 186 | return to.value; 187 | } 188 | } else { 189 | break; 190 | } 191 | } 192 | return this.easings[to.easing]( 193 | from.value, 194 | to.value, 195 | (frame - from.frame) / (to.frame - from.frame)); 196 | } 197 | 198 | warmup(renderer) { 199 | this.update(3776); 200 | this.render(renderer); 201 | } 202 | 203 | update(frame) { 204 | super.update(frame); 205 | this.frame = frame; 206 | 207 | this.throb *= .85; 208 | if (BEAT && BEAN <= 1536) { 209 | switch (BEAN % 96) { 210 | case 0: 211 | case 9: 212 | case 24: 213 | case 24 + 9: 214 | case 24 + 18: 215 | case 48 + 12: 216 | case 48 + 24: 217 | this.throb = 1; 218 | this.cameraDX = (this.outputs.cameraValues.value.cameraX - 219 | this.cameraPreviousX) * 0.5; 220 | this.cameraDY = (this.outputs.cameraValues.value.cameraY - 221 | this.cameraPreviousY) * 0.5; 222 | } 223 | } 224 | 225 | this.cameraDDX = -this.cameraX * 0.1; 226 | this.cameraDDY = -this.cameraY * 0.1; 227 | this.cameraDDR = -this.cameraR * 0.1; 228 | this.cameraDX += this.cameraDDX; 229 | this.cameraDY += this.cameraDDY; 230 | this.cameraDR += this.cameraDDR; 231 | this.cameraDX *= 0.75; 232 | this.cameraDY *= 0.75; 233 | this.cameraDR *= 0.75; 234 | this.cameraX += this.cameraDX; 235 | this.cameraY += this.cameraDY; 236 | this.cameraR += this.cameraDR; 237 | 238 | const cameraX = this.getPoint(this.cameraXPath, frame); 239 | const cameraY = this.getPoint(this.cameraYPath, frame); 240 | const cameraZoom = this.getPoint(this.cameraZoomPath, frame); 241 | const cameraRotate = this.getPoint(this.cameraRotatePath, frame); 242 | this.cameraPreviousX = this.outputs.cameraValues.value.cameraX; 243 | this.cameraPreviousY = this.outputs.cameraValues.value.cameraY; 244 | this.outputs.cameraValues.value.cameraX = cameraX + this.cameraX; 245 | this.outputs.cameraValues.value.cameraY = cameraY + this.cameraY; 246 | this.outputs.cameraValues.value.cameraZoom = cameraZoom; 247 | this.outputs.cameraValues.value.cameraRotate = cameraRotate + this.cameraR; 248 | } 249 | 250 | render() { 251 | const frame = this.frame; 252 | // This clears the canvas 253 | this.canvas.width += 0; 254 | 255 | this.ctx.save(); 256 | this.ctx.scale(GU, GU); 257 | this.ctx.translate(8, 4.5); 258 | 259 | const scale = this.outputs.cameraValues.value.cameraZoom; 260 | this.ctx.scale(scale, scale); 261 | this.ctx.rotate(this.outputs.cameraValues.value.cameraRotate); 262 | this.ctx.translate(this.outputs.cameraValues.value.cameraX, 263 | this.outputs.cameraValues.value.cameraY); 264 | 265 | let i = 0; 266 | for (const letter of this.textScript.slice().reverse()) { 267 | const t = (frame - FRAME_FOR_BEAN(30 * 12 * 4 + letter.beanOffset) + 5) / 10; 268 | i++; 269 | 270 | this.ctx.save(); 271 | this.ctx.translate( 272 | 0, 273 | easeIn( 274 | 10 - elasticOut(0, 1.5 + i * 1, 1.2, t), 10, 275 | (frame - FRAME_FOR_BEAN(32 * 12 * 4)) / 20) - 4.5 276 | ); 277 | this.ctx.fillStyle = 'rgba(119, 225, 93, 1)'; 278 | this.ctx.beginPath(); 279 | this.ctx.moveTo(letter.x, 0); 280 | this.ctx.lineTo(letter.x + 1, -1); 281 | this.ctx.lineTo(letter.x + 1, 11); 282 | this.ctx.lineTo(letter.x, 11); 283 | this.ctx.fill(); 284 | this.ctx.beginPath(); 285 | this.ctx.fillStyle = 'rgba(119, 225, 93, 1)'; 286 | this.ctx.moveTo(letter.x + 1, 1); 287 | this.ctx.lineTo(letter.x, 2); 288 | this.ctx.lineTo(letter.x, 10); 289 | this.ctx.lineTo(letter.x + 1, 10); 290 | this.ctx.fill(); 291 | this.ctx.beginPath(); 292 | this.ctx.fillStyle = 'rgba(255, 255, 255, 0.2)'; 293 | this.ctx.moveTo(letter.x + 0.85, -0.85); 294 | this.ctx.lineTo(letter.x + 1, -1); 295 | this.ctx.lineTo(letter.x + 1, 10); 296 | this.ctx.lineTo(letter.x + 0.85, 10); 297 | this.ctx.fill(); 298 | 299 | this.ctx.font = '0.6pt schmalibre'; 300 | this.ctx.textAlign = 'center'; 301 | this.ctx.textBaseline = 'alphabetic'; 302 | this.ctx.fillStyle = 'white'; 303 | this.ctx.lineWidth = 0.2; 304 | this.ctx.translate(letter.x + 0.45, 0.35); 305 | this.ctx.fillStyle = 'rgba(119, 225, 93, 1)'; 306 | this.ctx.fillStyle = 'white'; 307 | this.ctx.fillText(letter.letter, 0, 0.51); 308 | this.ctx.restore(); 309 | } 310 | 311 | this.ctx.restore(); 312 | 313 | this.output.needsUpdate = true; 314 | this.outputs.render.setValue(this.output); 315 | } 316 | 317 | resize() { 318 | this.canvas.width = 16 * GU; 319 | this.canvas.height = 9 * GU; 320 | } 321 | } 322 | 323 | global.revisionBars = revisionBars; 324 | })(this); 325 | -------------------------------------------------------------------------------- /src/revisionLogoCenter.js: -------------------------------------------------------------------------------- 1 | (function(global) { 2 | class revisionLogoCenter extends NIN.THREENode { 3 | constructor(id) { 4 | super(id, { 5 | outputs: { 6 | render: new NIN.TextureOutput() 7 | } 8 | }); 9 | this.canvas = document.createElement('canvas'); 10 | this.ctx = this.canvas.getContext('2d'); 11 | this.resize(); 12 | this.output = new THREE.VideoTexture(this.canvas); 13 | this.output.minFilter = THREE.LinearFilter; 14 | this.output.magFilter = THREE.LinearFilter; 15 | 16 | this.revisionLogoInner = document.createElement('img'); 17 | this.revisionLogoOuter = document.createElement('img'); 18 | this.revisionLogoMiddle = document.createElement('img'); 19 | Loader.load('res/pink_revision_logo_inner.png', this.revisionLogoInner, () => { }); 20 | Loader.load('res/pink_revision_logo_outer.png', this.revisionLogoOuter, () => { }); 21 | Loader.load('res/pink_revision_logo_middle.png', this.revisionLogoMiddle, () => { }); 22 | } 23 | 24 | warmup(renderer) { 25 | this.update(3776); 26 | this.render(renderer); 27 | } 28 | 29 | update(frame) { 30 | super.update(frame); 31 | 32 | this.frame = frame; 33 | } 34 | 35 | resize() { 36 | super.resize(); 37 | 38 | this.canvas.width = 4 * GU; 39 | this.canvas.height = 4 * GU; 40 | } 41 | 42 | render() { 43 | const frame = this.frame; 44 | 45 | // This clears the canvas 46 | this.canvas.width += 0; 47 | 48 | let scaler = 3*GU / this.revisionLogoOuter.width; 49 | this.ctx.save(); 50 | this.ctx.translate(2*GU, 2*GU); 51 | this.ctx.scale(scaler, scaler); 52 | this.ctx.rotate(frame / 20); 53 | this.ctx.drawImage(this.revisionLogoOuter, -this.revisionLogoOuter.width / 2, -this.revisionLogoOuter.height / 2); 54 | this.ctx.restore(); 55 | 56 | scaler = 3*GU / this.revisionLogoInner.width; 57 | this.ctx.save(); 58 | this.ctx.translate(2*GU, 2*GU); 59 | this.ctx.scale(scaler, scaler); 60 | this.ctx.rotate(frame / 80); 61 | this.ctx.drawImage(this.revisionLogoInner, -this.revisionLogoInner.width / 2, -this.revisionLogoInner.height / 2); 62 | this.ctx.restore(); 63 | 64 | scaler = 3*GU / this.revisionLogoMiddle.width; 65 | this.ctx.save(); 66 | this.ctx.translate(2*GU, 2*GU); 67 | this.ctx.scale(scaler, scaler); 68 | this.ctx.rotate(frame / 80); 69 | this.ctx.drawImage(this.revisionLogoMiddle, -this.revisionLogoMiddle.width / 2, -this.revisionLogoMiddle.height / 2); 70 | this.ctx.restore(); 71 | 72 | this.output.needsUpdate = true; 73 | this.outputs.render.setValue(this.output); 74 | } 75 | } 76 | 77 | global.revisionLogoCenter = revisionLogoCenter; 78 | })(this); 79 | -------------------------------------------------------------------------------- /src/shaders/Add/fragment.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D A; 2 | uniform sampler2D B; 3 | uniform float opacity; 4 | 5 | varying vec2 vUv; 6 | 7 | void main() { 8 | gl_FragColor = vec4(texture2D(A, vUv).rgb + texture2D(B, vUv).rgb * opacity, 1.); 9 | } 10 | -------------------------------------------------------------------------------- /src/shaders/Add/uniforms.json: -------------------------------------------------------------------------------- 1 | { 2 | "A": { "type": "t", "value": null }, 3 | "B": { "type": "t", "value": null }, 4 | "opacity": { "type": "f", "value": 0.5 } 5 | } 6 | -------------------------------------------------------------------------------- /src/shaders/Add/vertex.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | 3 | void main() { 4 | vUv = uv; 5 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 6 | } 7 | -------------------------------------------------------------------------------- /src/shaders/AlphaBlend/fragment.glsl: -------------------------------------------------------------------------------- 1 | uniform float frame; 2 | uniform sampler2D under; 3 | uniform sampler2D over; 4 | 5 | varying vec2 vUv; 6 | 7 | void main() { 8 | vec4 underColor = texture2D(under, vUv); 9 | vec4 overColor = texture2D(over, vUv); 10 | vec4 color = mix(underColor, overColor, vec4(overColor.a)); 11 | gl_FragColor = color; 12 | } 13 | -------------------------------------------------------------------------------- /src/shaders/AlphaBlend/uniforms.json: -------------------------------------------------------------------------------- 1 | { 2 | "under": { "type": "t", "value": null }, 3 | "over": { "type": "t", "value": null }, 4 | "frame": { "type": "f", "value": 0.0 } 5 | } 6 | -------------------------------------------------------------------------------- /src/shaders/AlphaBlend/vertex.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tDiffuse; 2 | 3 | varying vec2 vUv; 4 | 5 | void main() { 6 | vUv = uv; 7 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 8 | } 9 | -------------------------------------------------------------------------------- /src/shaders/CccBlend/fragment.glsl: -------------------------------------------------------------------------------- 1 | uniform float frame; 2 | uniform sampler2D A; 3 | uniform sampler2D B; 4 | 5 | varying vec2 vUv; 6 | 7 | void main() { 8 | vec4 A = texture2D(A, vUv); 9 | vec4 B = texture2D(B, vUv); 10 | 11 | gl_FragColor = mix(B, A, A.a); 12 | } 13 | -------------------------------------------------------------------------------- /src/shaders/CccBlend/uniforms.json: -------------------------------------------------------------------------------- 1 | { 2 | "A": { "type": "t", "value": null }, 3 | "B": { "type": "t", "value": null }, 4 | "frame": { "type": "f", "value": 0.0 } 5 | } 6 | -------------------------------------------------------------------------------- /src/shaders/CccBlend/vertex.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tDiffuse; 2 | 3 | varying vec2 vUv; 4 | 5 | void main() { 6 | vUv = uv; 7 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 8 | } 9 | -------------------------------------------------------------------------------- /src/shaders/OrthoCube/fragment.glsl: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | #define M_PI 3.1415926535897932384626433832795 3 | 4 | uniform float frame; 5 | uniform float BEAN; 6 | uniform float kickThrob; 7 | uniform float rotX; 8 | uniform float rotY; 9 | uniform float rotZ; 10 | uniform float cubeSize; 11 | uniform sampler2D tDiffuse; 12 | varying vec2 vUv; 13 | 14 | const int MAX_MARCHING_STEPS = 180; 15 | const float EPSILON = 0.001; 16 | const float END = 100.0; 17 | const float START = 0.0; 18 | 19 | float uni(float d1, float d2) { 20 | return min(d1, d2); 21 | } 22 | 23 | float sub(float d1, float d2) { 24 | return max(-d1, d2); 25 | } 26 | 27 | float inter(float d1, float d2) { 28 | return max(d1, d2); 29 | } 30 | 31 | float sphere(vec3 p, float s) { 32 | return length(p)-s; 33 | } 34 | 35 | 36 | vec2 sphereCube(vec3 p, float sphereSize, float gap){ 37 | float d = END + EPSILON; 38 | float minD = d; 39 | float cD = 0.0; 40 | float oID = 1.0; 41 | float currentID = 0.0; 42 | for(float x = -1.0; x <= 1.0; x++){ 43 | for(float y = -1.0; y <= 1.0; y++){ 44 | for(float z = -1.0; z <= 1.0; z++){ 45 | cD = sphere((p-vec3(x*gap, y*gap, z*gap)), sphereSize); 46 | if(cD < d){ 47 | d = cD; 48 | currentID = oID; 49 | } 50 | oID = oID + 1.0; 51 | } 52 | } 53 | } 54 | return vec2(d, currentID); 55 | } 56 | 57 | mat4 rotateX(float theta) { 58 | float c = cos(-theta); 59 | float s = sin(-theta); 60 | 61 | return mat4( 62 | vec4(1, 0, 0, 0), 63 | vec4(0, c, -s, 0), 64 | vec4(0, s, c, 0), 65 | vec4(0, 0, 0, 1) 66 | ); 67 | } 68 | mat4 rotateY(float theta) { 69 | float c = cos(-theta); 70 | float s = sin(-theta); 71 | 72 | return mat4( 73 | vec4(c, 0, s, 0), 74 | vec4(0, 1, 0, 0), 75 | vec4(-s, 0, c, 0), 76 | vec4(0, 0, 0, 1) 77 | ); 78 | } 79 | mat4 rotateZ(float theta) { 80 | float c = cos(-theta); 81 | float s = sin(-theta); 82 | 83 | return mat4( 84 | vec4(c, -s, 0, 0), 85 | vec4(s, c, 0, 0), 86 | vec4(0, 0, 1, 0), 87 | vec4(0, 0, 0, 1) 88 | ); 89 | } 90 | 91 | vec2 sdf(vec3 p) { 92 | vec3 cubeP = p; 93 | 94 | cubeP = (rotateX(rotX) * vec4(p, 1.0)).xyz; 95 | cubeP = (rotateY(rotY) * vec4(cubeP, 1.0)).xyz; 96 | cubeP = (rotateZ(rotZ) * vec4(cubeP, 1.0)).xyz; 97 | 98 | float sphereSize = 0.6; 99 | 100 | if(BEAN >= 240.0){ 101 | sphereSize += 0.15 * kickThrob; 102 | } 103 | vec2 distoid = sphereCube(cubeP, sphereSize, cubeSize); 104 | return distoid; 105 | } 106 | 107 | 108 | //Returns vec4(depth, objectID, numberOfSteps) 109 | vec3 march(vec3 eye, vec3 dir, float start, float end) { 110 | float depth = start; 111 | float closestDist = END; 112 | vec2 distoid = vec2(0.0, 0.0); 113 | for (int i = 0; i < MAX_MARCHING_STEPS; i++) { 114 | distoid = sdf(eye + depth * dir); 115 | float dist = distoid.x; 116 | if(dist < closestDist){ 117 | closestDist = dist; 118 | } 119 | if (dist < EPSILON) { 120 | return vec3(depth, distoid.y, i); 121 | } 122 | depth+=dist; 123 | if (depth >= end) { 124 | return vec3(end, 0.0, i);; 125 | } 126 | } 127 | return vec3(END, 0.0, MAX_MARCHING_STEPS); 128 | } 129 | 130 | vec3 estimateNormal(vec3 p) { 131 | return normalize(vec3( 132 | sdf(vec3(p.x + EPSILON, p.yz)).x - sdf(vec3(p.x - EPSILON, p.yz)).x, 133 | sdf(vec3(p.x, p.y + EPSILON, p.z)).x - sdf(vec3(p.x, p.y - EPSILON, p.z)).x, 134 | sdf(vec3(p.xy, p.z + EPSILON)).x - sdf(vec3(p.xy, p.z - EPSILON)).x 135 | )); 136 | } 137 | 138 | void main() { 139 | vec3 color1 = vec3(255.0/255.0, 73.0/255.0, 130.0/255.0); 140 | vec3 color2 = vec3(119.0/255.0, 225.0/255.0, 93.0/255.0); 141 | vec3 white = vec3(1.0, 1.0, 1.0); 142 | vec3 dark = vec3(55.0/255.0, 60.0/255.0, 63.0/255.0); 143 | 144 | //vec3 pos = vec3(cos(frame/20.0)*10.0, 5.0, sin(frame/20.0)*10.0); 145 | vec3 pos = vec3(0.0, 0.0, -10.0); 146 | vec3 dir = normalize(-pos); 147 | 148 | vec2 propUV = vUv - vec2(0.5, 0.5); 149 | propUV = propUV * vec2(16.0, 9.0) * 1.4; 150 | 151 | //NOTE: Math assumes camera is always pointing in Z+ 152 | //do not rotate the camera without fixing math 153 | vec3 eye = pos + vec3(propUV, 0.0); 154 | 155 | vec3 distOid = march(eye, dir, START, END); 156 | float dist = distOid.x; 157 | 158 | vec3 color = vec3(0.0, 0.0, 0.0); 159 | 160 | if (dist >= END-EPSILON) { 161 | color = dark; 162 | }else{ 163 | float oID = distOid.y; 164 | 165 | vec3 p = eye + dir * dist; 166 | vec3 normal = estimateNormal(p); 167 | float fresnell = abs(dot(dir,normal)); 168 | 169 | if(fresnell < 0.5){ //border! 170 | color = dark; 171 | }else{ 172 | float beat = (BEAN - 240.0)/12.0; 173 | color = mod(oID, 2.0) == 0.0 ? white : color2; 174 | 175 | //Morph to white at the end 176 | color += vec3(1.0, 1.0, 1.0) * pow(max(0.0 , (beat-15.0) * 2.0), 2.0); 177 | } 178 | if(BEAN >= 240.0 && fresnell >= 0.5){ 179 | //color += 0.3 * kickThrob; 180 | } 181 | } 182 | 183 | gl_FragColor = vec4(color, 1.0); 184 | } 185 | 186 | -------------------------------------------------------------------------------- /src/shaders/OrthoCube/uniforms.json: -------------------------------------------------------------------------------- 1 | { 2 | "tDiffuse": { "type": "t", "value": null }, 3 | "frame": { "type": "f", "value": 0.0 }, 4 | "kickThrob": { "type": "f", "value": 0.0 }, 5 | "rotX": { "type": "f", "value": 0.0 }, 6 | "rotY": { "type": "f", "value": 0.0 }, 7 | "rotZ": { "type": "f", "value": 0.0 }, 8 | "cubeSize": { "type": "f", "value": 0.0 }, 9 | "BEAN": { "type": "f", "value": 0.0 } 10 | } 11 | -------------------------------------------------------------------------------- /src/shaders/OrthoCube/vertex.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tDiffuse; 2 | 3 | varying vec2 vUv; 4 | 5 | void main() { 6 | vUv = uv; 7 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 8 | } 9 | -------------------------------------------------------------------------------- /src/shaders/ataribackground/fragment.glsl: -------------------------------------------------------------------------------- 1 | uniform float frame; 2 | 3 | varying vec2 vUv; 4 | 5 | float rand(vec2 co){ 6 | return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); 7 | } 8 | 9 | void main() { 10 | float gridSize = 0.3 / 1.5 * 4.; 11 | float padding = gridSize / 10.0; 12 | float sliceWidth = gridSize / 10.0; 13 | vec2 uv = vUv; 14 | uv -= 0.5; 15 | uv *= vec2(16., 9.); 16 | uv.y += frame / 30.0; 17 | uv.x += frame / 30.0; 18 | uv = mod(uv, gridSize); 19 | 20 | float intensity = 1.0; 21 | float randomNoise = rand(vec2(vUv.x + frame * 0.0001, vUv.y + frame * 0.00001)); 22 | intensity *= (0.8 + randomNoise * 0.3); 23 | 24 | vec2 centeredLocalUv = abs(uv - gridSize / 2.0); 25 | float maxDist = max(centeredLocalUv.x, centeredLocalUv.y); 26 | if (!(maxDist > gridSize / 5.0 && maxDist < gridSize / 2.5)) { 27 | intensity *= 0.9; 28 | } 29 | intensity *= 1.; 30 | 31 | vec3 greenColor = vec3(55., 60., 63.) / 255.; 32 | intensity = clamp(intensity, 0.0, 1.0); 33 | gl_FragColor = vec4(intensity * greenColor, 1.0); 34 | } 35 | -------------------------------------------------------------------------------- /src/shaders/ataribackground/uniforms.json: -------------------------------------------------------------------------------- 1 | { 2 | "frame": { 3 | "type": "f", 4 | "value": 0.0 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/shaders/ataribackground/vertex.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tDiffuse; 2 | 3 | varying vec2 vUv; 4 | 5 | void main() { 6 | vUv = uv; 7 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 8 | } 9 | -------------------------------------------------------------------------------- /src/shaders/atarifx/fragment.glsl: -------------------------------------------------------------------------------- 1 | uniform float frame; 2 | uniform sampler2D tDiffuse; 3 | 4 | varying vec2 vUv; 5 | 6 | #define PI 3.14159265 7 | 8 | float rand(vec2 co){ 9 | return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); 10 | } 11 | 12 | void main() { 13 | 14 | float mixer = pow(clamp((frame - 2271.) / 10., 0., 1.), 4.); 15 | mixer = 1.; 16 | 17 | vec2 uv; 18 | vec3 color; 19 | 20 | /* tv frame */ 21 | uv = vUv; 22 | uv = (uv - 0.5) * mix(2., 2.4, mixer); 23 | 24 | float squircleAmount = mix(9999., 12., mixer); 25 | float squircle = pow(abs(uv.x), squircleAmount) + pow(abs(uv.y), squircleAmount); 26 | if(squircle > 1.) { 27 | float squircleHighlight = pow(abs(uv.x - 0.005), squircleAmount) + 28 | pow(abs(uv.y + 0.015), squircleAmount); 29 | 30 | color = vec3(55. + 100. * sin(uv.x + 5. * uv.y), 60., 63.) / 255. * 0.5; 31 | 32 | color = 0.25 + 0.4 * vec3(119., 225., 93.) / 255. * 33 | (1. - 0.2 * (1. + vec3(sin(uv.x * 16. * 16. * 2.) - sin(2. * uv.y * 16. * 9.)))); 34 | 35 | color *= 0.8; 36 | 37 | color += 0.2 * mix(vec3(0.), vec3(1.), clamp(vec3(1.35 - squircleHighlight), 0., 1.)); 38 | 39 | float light = length(uv * vec2(16., 9.) + vec2(-15.9, 8.9)); 40 | color = mix(color, vec3(119., 225., 93.) / 255. * 2., 1. - clamp(-0.2 + light / 0.2 * 2., 0., 1.)); 41 | 42 | for(float i = 0.; i < 2.9; i+=1.) { 43 | vec2 shadowUv = uv + vec2(0.002, -0.002); 44 | float shadow = length(shadowUv * vec2(16., 9.) + 45 | vec2(-15. + i * 1.5, 10.0)); 46 | color = mix(color, vec3(0.1) * 2., 1. - step(.51, shadow)); 47 | 48 | vec2 knobUv = uv * vec2(16., 9.) + vec2(-15. + i * 1.5, 10.0); 49 | float knob = length(knobUv); 50 | color = mix(color, vec3(0.5), 1. - step(.5, knob)); 51 | color *= 0.5 + 0.5 * clamp(15. * knob, 0., 1.); 52 | 53 | } 54 | 55 | color *= 2.; 56 | 57 | } else { 58 | /* lens distortion */ 59 | uv *= mix(1., 0.95, mixer); 60 | float len = length(uv); 61 | uv = uv * mix(1., len, len * 0.05 * mixer); 62 | 63 | vec4 originalColor = texture2D(tDiffuse, uv / 2. + 0.5); 64 | color = originalColor.xyz; 65 | 66 | /* vignette */ 67 | vec2 vignetteUv = uv * 0.75; 68 | color *= mix(1., (1. - abs(vignetteUv.x * vignetteUv.y) * .75), mixer); 69 | 70 | /* screen glare */ 71 | color += mixer * 0.05 * (mix( 72 | 0., 73 | 1., 74 | clamp( 75 | -100. + 100. * 2. * ((vUv.y - 0.5) + 0.5 * sin(0.75 * PI / 2. + vUv.x * PI / 4.)), 76 | 0., 1.) 77 | 78 | ) * mix( 79 | 0., 80 | 1., 81 | 2. * ((vUv.y - 0.5) + 0.5 * sin(0.75 * PI / 2. + vUv.x * PI / 4.)))); 82 | 83 | /* screen shadows */ 84 | float shadowSquircle = pow(abs(uv.x - 0.075), squircleAmount) + 85 | pow(abs(uv.y + 0.075), squircleAmount); 86 | color = color * (1. - shadowSquircle * .7); 87 | 88 | 89 | /* noise */ 90 | float noise = rand(vec2(vUv.x + frame * 0.0001, vUv.y + frame * 0.00001)); 91 | color += mixer * noise * 0.1; 92 | 93 | /* scanlines */ 94 | vec2 scanLinesUv = uv / 2.; 95 | float intensity = (1. + sin(scanLinesUv.y * 3.14159265 * 2. * 176.)) * 0.5; 96 | color *= mix(1., 1. - intensity * 0.1, mixer); 97 | } 98 | 99 | 100 | /* outer vignette */ 101 | vec2 vignetteUv2 = (vUv - 0.5) * 1.85; 102 | color *= mix(1., (1. - abs(vignetteUv2.x * vignetteUv2.y) * .8), mixer); 103 | 104 | /* color grading */ 105 | color = mix(color, pow(color, vec3(1.25)), vec3(mixer)); 106 | 107 | gl_FragColor = vec4(color, 1.); 108 | } 109 | -------------------------------------------------------------------------------- /src/shaders/atarifx/uniforms.json: -------------------------------------------------------------------------------- 1 | { 2 | "tDiffuse": { "type": "t", "value": null }, 3 | "frame": { "type": "f", "value": 0.0 } 4 | } 5 | -------------------------------------------------------------------------------- /src/shaders/atarifx/vertex.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tDiffuse; 2 | 3 | varying vec2 vUv; 4 | 5 | void main() { 6 | vUv = uv; 7 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 8 | } 9 | -------------------------------------------------------------------------------- /src/shaders/bouncyoverlayer/fragment.glsl: -------------------------------------------------------------------------------- 1 | uniform float frame; 2 | uniform float translationOverX; 3 | uniform float translationUnderX; 4 | uniform sampler2D tDiffuse; 5 | uniform sampler2D overlay; 6 | 7 | varying vec2 vUv; 8 | 9 | void main() { 10 | vec4 overlaySample = texture2D(overlay, vUv + vec2(translationOverX, 0.)); 11 | vec4 tDiffuseSample = texture2D(tDiffuse, vUv + vec2(translationUnderX, 0.)); 12 | gl_FragColor = vec4(mix( 13 | tDiffuseSample.rgb, 14 | overlaySample.rgb, 15 | overlaySample.a), 1.); 16 | } 17 | -------------------------------------------------------------------------------- /src/shaders/bouncyoverlayer/uniforms.json: -------------------------------------------------------------------------------- 1 | { 2 | "tDiffuse": { "type": "t", "value": null }, 3 | "overlay": { "type": "t", "value": null }, 4 | "frame": { "type": "f", "value": 0.0 }, 5 | "translationUnderX": { "type": "f", "value": 0.0 }, 6 | "translationOverX": { "type": "f", "value": 0.0 } 7 | } 8 | -------------------------------------------------------------------------------- /src/shaders/bouncyoverlayer/vertex.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tDiffuse; 2 | 3 | varying vec2 vUv; 4 | 5 | void main() { 6 | vUv = uv; 7 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 8 | } 9 | -------------------------------------------------------------------------------- /src/shaders/carousel/fragment.glsl: -------------------------------------------------------------------------------- 1 | uniform float t; 2 | uniform float fadeOutT; 3 | uniform float frame; 4 | uniform float width; 5 | uniform sampler2D overlay; 6 | uniform sampler2D overlay2; 7 | uniform sampler2D overlay3; 8 | uniform sampler2D nextScene; 9 | uniform float divisions; 10 | uniform vec3 foregroundColor; 11 | uniform vec3 foregroundColor2; 12 | uniform vec3 backgroundColor; 13 | uniform vec3 thirdColor; 14 | uniform float thirdColorRadius; 15 | uniform float radiusMultiplier; 16 | uniform vec2 origo; 17 | uniform float cameraX; 18 | uniform float cameraY; 19 | uniform float cameraZoom; 20 | uniform float cameraRotate; 21 | 22 | varying vec2 vUv; 23 | 24 | #define M_PI 3.1415926535897932384626433832795 25 | 26 | 27 | vec2 rotate(vec2 point, float angle) { 28 | float s = sin(angle); 29 | float c = cos(angle); 30 | return vec2(point.x * c - point.y * s, 31 | point.x * s + point.y * c); 32 | } 33 | 34 | void main() { 35 | 36 | vec2 uv = vUv; 37 | 38 | uv -= 0.5; 39 | uv *= vec2(16., 9.) / 9.; 40 | 41 | uv -= vec2(cameraX, cameraY) / 9.; 42 | uv /= cameraZoom; 43 | uv = rotate(uv, cameraRotate); 44 | 45 | vec2 coords = (uv - origo); 46 | coords = rotate(uv, -frame * M_PI * 2. / 60. / 60. * 115. / divisions); 47 | 48 | float radius = length(coords); 49 | float angle = atan(coords.y / coords.x) + t + radius * radiusMultiplier; 50 | float mod_angle = mod(angle, M_PI / divisions); 51 | vec3 colorOne = foregroundColor; 52 | if (radius < thirdColorRadius) { 53 | if(frame < 4006.) { 54 | colorOne = backgroundColor; 55 | } else { 56 | colorOne = thirdColor; 57 | } 58 | } 59 | vec4 color = vec4( 60 | mix(mix(colorOne, 61 | foregroundColor2, 62 | step(mod(angle - 0.0, M_PI / divisions), M_PI / (divisions * 2.)) 63 | ), 64 | backgroundColor, 65 | step(mod_angle + 0.5 * (1. - width) * M_PI / divisions, M_PI / (divisions * 2.))), 1.); 66 | vec4 overlayColor = texture2D(overlay, vUv); 67 | vec4 overlay2Color = texture2D(overlay2, 6. * vec2(coords.x, coords.y) + .5); 68 | overlay2Color.a = mix( 69 | overlay2Color.a, 70 | 0., 71 | clamp((frame - 3999.) / 3., 0., 1.)); 72 | 73 | vec4 overlay3Color = texture2D(overlay3, vec2(vUv.x, 1. - vUv.y)); 74 | vec4 layer2Color = mix(color, overlay2Color, overlay2Color.a); 75 | vec4 layer3Color = mix(layer2Color, overlayColor, overlayColor.a); 76 | gl_FragColor = mix(layer3Color, overlay3Color, overlay3Color.a); 77 | gl_FragColor = mix(gl_FragColor, vec4(0.), fadeOutT); 78 | 79 | vec4 nextSceneColor = texture2D(nextScene, vUv); 80 | if (nextSceneColor.r > 0.09) { 81 | gl_FragColor = texture2D(nextScene, vUv); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/shaders/carousel/uniforms.json: -------------------------------------------------------------------------------- 1 | { 2 | "tDiffuse": { "type": "t", "value": null }, 3 | "overlay": { "type": "t", "value": null }, 4 | "overlay2": { "type": "t", "value": null }, 5 | "overlay3": { "type": "t", "value": null }, 6 | "nextScene": { "type": "t", "value": null }, 7 | "t": { "type": "f", "value": 0.0 }, 8 | "fadeOutT": { "type": "f", "value": 0.0 }, 9 | "frame": { "type": "f", "value": 0.0 }, 10 | "divisions": { "type": "f", "value": 3.0}, 11 | "radiusMultiplier": { "type": "f", "value": 0.0}, 12 | "cameraX": { "type": "f", "value": 0.0}, 13 | "cameraY": { "type": "f", "value": 0.0}, 14 | "cameraZoom": { "type": "f", "value": 0.0}, 15 | "cameraRotate": { "type": "f", "value": 0.0}, 16 | "foregroundColor": { "type": "v3", "value": null }, 17 | "foregroundColor2": { "type": "v3", "value": null }, 18 | "backgroundColor": { "type": "v3", "value": null }, 19 | "thirdColor": { "type": "v3", "value": null }, 20 | "thirdColorRadius": { "type": "f", "value": 0.0 }, 21 | "width": { "type": "f", "value": 0.0 }, 22 | "origo": { "type": "v2", "value": null } 23 | } 24 | -------------------------------------------------------------------------------- /src/shaders/carousel/vertex.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tDiffuse; 2 | 3 | varying vec2 vUv; 4 | 5 | void main() { 6 | vUv = uv; 7 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 8 | } 9 | -------------------------------------------------------------------------------- /src/shaders/chess/fragment.glsl: -------------------------------------------------------------------------------- 1 | uniform float frame; 2 | uniform sampler2D tDiffuse; 3 | uniform vec4 foregroundColor; 4 | uniform vec4 backgroundColor; 5 | 6 | varying vec2 vUv; 7 | 8 | void main() { 9 | vec4 color; 10 | float total = floor(vUv.x * 40. * 16. / 9.) + floor(vUv.y * 40.); 11 | if (mod(total, 2.) == 0.0) { 12 | color = foregroundColor; 13 | } else { 14 | color = backgroundColor; 15 | } 16 | gl_FragColor = color; 17 | } 18 | -------------------------------------------------------------------------------- /src/shaders/chess/uniforms.json: -------------------------------------------------------------------------------- 1 | { 2 | "tDiffuse": { "type": "t", "value": null }, 3 | "frame": { "type": "f", "value": 0.0 }, 4 | "foregroundColor": { "type": "v4", "value": null }, 5 | "backgroundColor": { "type": "v4", "value": null } 6 | } 7 | -------------------------------------------------------------------------------- /src/shaders/chess/vertex.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tDiffuse; 2 | 3 | varying vec2 vUv; 4 | 5 | void main() { 6 | vUv = uv; 7 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 8 | } 9 | -------------------------------------------------------------------------------- /src/shaders/chromaTransition/fragment.glsl: -------------------------------------------------------------------------------- 1 | uniform float t; 2 | uniform sampler2D A; 3 | uniform sampler2D B; 4 | uniform sampler2D chroma; 5 | 6 | varying vec2 vUv; 7 | 8 | void main() { 9 | vec4 colorA = texture2D(A, vUv); 10 | vec4 colorB = texture2D(B, vUv); 11 | vec4 colorChroma = texture2D(chroma, vUv); 12 | gl_FragColor = mix(colorA, colorB, colorChroma.a); 13 | } 14 | -------------------------------------------------------------------------------- /src/shaders/chromaTransition/uniforms.json: -------------------------------------------------------------------------------- 1 | { 2 | "A": { "type": "t", "value": null }, 3 | "B": { "type": "t", "value": null }, 4 | "chroma": { "type": "t", "value": null }, 5 | "t": { "type": "f", "value": 0.0 } 6 | } 7 | -------------------------------------------------------------------------------- /src/shaders/chromaTransition/vertex.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tDiffuse; 2 | 3 | varying vec2 vUv; 4 | 5 | void main() { 6 | vUv = uv; 7 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 8 | } 9 | -------------------------------------------------------------------------------- /src/shaders/clockTransition/fragment.glsl: -------------------------------------------------------------------------------- 1 | uniform float t; 2 | uniform sampler2D A; 3 | uniform sampler2D B; 4 | 5 | varying vec2 vUv; 6 | 7 | #define start_clock 3662. 8 | #define start_expand 3724. 9 | #define end_expand 3756. 10 | #define circle_diameter 0.3832 // <- 25 minutes of math.... JK, tried random numbers and picked the one that looked best. 11 | #define PI 3.14159 12 | 13 | void main() 14 | { 15 | vec4 colorA = texture2D(A, vUv); 16 | vec4 colorB = texture2D(B, vUv); 17 | 18 | float spin_progess = (t - start_clock) / (start_expand - start_clock); 19 | spin_progess = max(min(spin_progess, 1.), 0.); 20 | float expand_progess = (t - start_expand) / (end_expand - start_expand); 21 | float radius = circle_diameter; 22 | float alpha = 0.; 23 | 24 | if (t > start_expand) 25 | { 26 | radius = circle_diameter + expand_progess * (1. - circle_diameter); 27 | } 28 | 29 | 30 | //if( distance(vUv / vec2(9./16., 1.) - vec2(0.25 * 16. / 9., 0.), vec2(.5, .5)) < 0.5) 31 | if( distance((vUv - vec2(0.5, 0.)) / vec2(9. / 16., 1.), vec2(0., .5)) < radius) 32 | { 33 | alpha = atan((vUv.x - .5) * 16. / 9., vUv.y - .5) / (PI * 2.);// + (mod(t, 100.)) / 100.); 34 | alpha = mod(alpha, 1.); 35 | 36 | alpha = alpha - 1. + spin_progess * 2.; 37 | alpha = (alpha - .5) * 10.; 38 | } 39 | 40 | gl_FragColor = mix(colorA, colorB, max(min(alpha, 1.), 0.)); 41 | } 42 | -------------------------------------------------------------------------------- /src/shaders/clockTransition/uniforms.json: -------------------------------------------------------------------------------- 1 | { 2 | "A": { "type": "t", "value": null }, 3 | "B": { "type": "t", "value": null }, 4 | "t": { "type": "f", "value": 0.0 } 5 | } 6 | -------------------------------------------------------------------------------- /src/shaders/clockTransition/vertex.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tDiffuse; 2 | 3 | varying vec2 vUv; 4 | 5 | void main() { 6 | vUv = uv; 7 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 8 | } 9 | -------------------------------------------------------------------------------- /src/shaders/discowall/fragment.glsl: -------------------------------------------------------------------------------- 1 | uniform float frame; 2 | uniform sampler2D walltexture; 3 | uniform sampler2D texttexture; 4 | 5 | varying vec2 vUv; 6 | 7 | #define PI 3.1415926535897932384626433832795 8 | 9 | void main() { 10 | 11 | vec2 uv = vUv; 12 | uv -= 0.5; 13 | uv *= vec2(16., 9.) / 8.; 14 | 15 | float light = 1.; 16 | vec2 grid = uv * 8.; 17 | light *= abs(sin(grid.x * PI * 2.)); 18 | light *= abs(cos(PI + grid.y * PI * 2.)); 19 | light = pow(light, .1); 20 | 21 | vec2 wallUV = vUv; 22 | wallUV += vec2(-0.25, 0.25); 23 | vec3 color = texture2D(walltexture, wallUV).xyz * 2.; 24 | 25 | vec2 textUV = vUv; 26 | textUV += vec2(-0.25, 0.25); 27 | 28 | color += texture2D(texttexture, textUV).xyz; 29 | color *= light; 30 | 31 | color *= 0.9; 32 | color += 0.1; 33 | 34 | gl_FragColor = vec4(color, 1.); 35 | } 36 | -------------------------------------------------------------------------------- /src/shaders/discowall/uniforms.json: -------------------------------------------------------------------------------- 1 | { 2 | "walltexture": { "type": "t", "value": null}, 3 | "texttexture": { "type": "t", "value": null}, 4 | "frame": { "type": "f", "value": 0.0 } 5 | } 6 | -------------------------------------------------------------------------------- /src/shaders/discowall/vertex.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tDiffuse; 2 | 3 | varying vec2 vUv; 4 | 5 | void main() { 6 | vUv = uv; 7 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 8 | } 9 | -------------------------------------------------------------------------------- /src/shaders/fadeout/fragment.glsl: -------------------------------------------------------------------------------- 1 | uniform float t; 2 | uniform sampler2D A; 3 | 4 | varying vec2 vUv; 5 | 6 | void main() { 7 | vec4 color = texture2D(A, vUv); 8 | gl_FragColor = mix(color, vec4(0., 0., 0., 1.), t); 9 | } 10 | -------------------------------------------------------------------------------- /src/shaders/fadeout/uniforms.json: -------------------------------------------------------------------------------- 1 | { 2 | "A": { "type": "t", "value": null }, 3 | "t": { "type": "f", "value": 0.0 } 4 | } 5 | -------------------------------------------------------------------------------- /src/shaders/fadeout/vertex.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tDiffuse; 2 | 3 | varying vec2 vUv; 4 | 5 | void main() { 6 | vUv = uv; 7 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 8 | } 9 | -------------------------------------------------------------------------------- /src/shaders/fallintransition/fragment.glsl: -------------------------------------------------------------------------------- 1 | uniform float t; 2 | uniform sampler2D A; 3 | uniform sampler2D B; 4 | 5 | varying vec2 vUv; 6 | 7 | void main() { 8 | gl_FragColor = texture2D(A, vUv); 9 | if (vUv.y + t > 0. && vUv.y + t < 1.) { 10 | gl_FragColor = texture2D(B, vec2(vUv.x, vUv.y + t)); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/shaders/fallintransition/uniforms.json: -------------------------------------------------------------------------------- 1 | { 2 | "A": { "type": "t", "value": null }, 3 | "B": { "type": "t", "value": null }, 4 | "t": { "type": "f", "value": 0.0 } 5 | } 6 | -------------------------------------------------------------------------------- /src/shaders/fallintransition/vertex.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tDiffuse; 2 | 3 | varying vec2 vUv; 4 | 5 | void main() { 6 | vUv = uv; 7 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 8 | } 9 | -------------------------------------------------------------------------------- /src/shaders/gridball/fragment.glsl: -------------------------------------------------------------------------------- 1 | uniform float frame; 2 | uniform sampler2D tDiffuse; 3 | uniform float gridMode; 4 | uniform float smoothPercentage; 5 | uniform float lineWidth; 6 | uniform float ballRadius; 7 | uniform float ambientLightIntensity; 8 | 9 | varying vec2 vUv; 10 | varying vec4 globalPosition; 11 | 12 | varying vec3 vNormal; 13 | 14 | void main() { 15 | vec2 uv = vUv; 16 | vec3 white = vec3(1.); 17 | vec4 color = vec4(white, 0.1); 18 | 19 | vec3 diffuseColor = vec3(102., 201., 115.) / 255.; 20 | vec3 directionalLight = normalize(vec3(1.)); 21 | 22 | float gridAmount = 0.; 23 | 24 | if(uv.y < lineWidth) { 25 | gridAmount = clamp(1. - (uv.y - lineWidth * (1. - smoothPercentage)) / lineWidth / smoothPercentage, 0., 1.); 26 | } 27 | if(uv.x > 1. - lineWidth) { 28 | gridAmount = clamp((uv.x - 1. + lineWidth) / lineWidth / smoothPercentage, 0., 1.); 29 | } 30 | if(uv.x < uv.y + lineWidth) { 31 | gridAmount = clamp(1. - (uv.x - uv.y - lineWidth * (1. - smoothPercentage)) / lineWidth / smoothPercentage, 0., 1.); 32 | } 33 | 34 | float ballSmoothPercentage = .25 * smoothPercentage; 35 | if(uv.x < ballRadius) { 36 | gridAmount += clamp(1. - (uv.x - ballRadius * (1. - ballSmoothPercentage)) / ballRadius / ballSmoothPercentage, 0., 1.); 37 | } 38 | if(uv.y > 1. - ballRadius) { 39 | gridAmount += clamp(1. - (1. - uv.y - ballRadius * (1. - ballSmoothPercentage)) / ballRadius / ballSmoothPercentage, 0., 1.); 40 | } 41 | if(uv.x > uv.y + 1. - ballRadius) { 42 | gridAmount += clamp(1. - (1. - uv.x + uv.y - ballRadius * (1. - ballSmoothPercentage)) / ballRadius / ballSmoothPercentage, 0., 1.); 43 | } 44 | gridAmount = clamp(gridAmount, 0., 1.); 45 | 46 | if(gridMode > 0.5) { 47 | color = vec4(vec3(.5), gridAmount); 48 | } else { 49 | float light = 1.; 50 | light = clamp(dot(vNormal, directionalLight), 0., 1.); 51 | float specular = pow(light, 16.); 52 | light = clamp(light, 0., 1.); 53 | light *= 0.5 + (1. - gridAmount) * 0.5; 54 | light = clamp(light, 0., 1.); 55 | light -= gridAmount * ambientLightIntensity * 0.25; 56 | light += ambientLightIntensity; 57 | light = clamp(light, 0., 1.); 58 | color = vec4(diffuseColor * light, 1.); 59 | color += specular * 0.1; 60 | } 61 | 62 | gl_FragColor = color; 63 | } 64 | -------------------------------------------------------------------------------- /src/shaders/gridball/uniforms.json: -------------------------------------------------------------------------------- 1 | { 2 | "tDiffuse": { "type": "t", "value": null }, 3 | "frame": { "type": "f", "value": 0.0 }, 4 | "ambientLightIntensity": { "type": "f", "value": 0.0 }, 5 | "lineWidth": { "type": "f", "value": 0.0 }, 6 | "ballRadius": { "type": "f", "value": 0.0 }, 7 | "smoothPercentage": { "type": "f", "value": 0.0 }, 8 | "gridMode": { "type": "f", "value": 0.0 } 9 | } 10 | -------------------------------------------------------------------------------- /src/shaders/gridball/vertex.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tDiffuse; 2 | uniform float frame; 3 | 4 | varying vec2 vUv; 5 | varying vec4 globalPosition; 6 | varying vec3 vNormal; 7 | 8 | void main() { 9 | vUv = uv; 10 | vNormal = normalMatrix * normal; 11 | globalPosition = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 12 | gl_Position = globalPosition; 13 | } 14 | -------------------------------------------------------------------------------- /src/shaders/griddymid/fragment.glsl: -------------------------------------------------------------------------------- 1 | uniform float frame; 2 | uniform float upper; 3 | uniform float lower; 4 | uniform sampler2D tDiffuse; 5 | 6 | varying vec2 vUv; 7 | 8 | void main() { 9 | vec2 uv = vUv; 10 | vec3 orange = vec3(227. / 255., 82. / 255., 175. / 255.); 11 | vec4 color = vec4(0.); 12 | 13 | if(sin(uv.y * 70. - frame / 5.) > 0.95) { 14 | color = vec4(orange, 0.2); 15 | } 16 | 17 | float lineWidth = 0.005; 18 | if(uv.y < 0.02 + lineWidth) { 19 | color = vec4(orange, 1.); 20 | } 21 | 22 | if(uv.x > 0.25 - lineWidth && uv.x < 0.25) { 23 | color = vec4(orange, 1.); 24 | } 25 | if(uv.x > 0.5 - lineWidth && uv.x < 0.5) { 26 | color = vec4(orange, 1.); 27 | } 28 | if(uv.x > 0.75 - lineWidth && uv.x < 0.75) { 29 | color = vec4(orange, 1.); 30 | } 31 | if(uv.x > 1. - lineWidth && uv.x < 1.) { 32 | color = vec4(orange, 1.); 33 | } 34 | if(uv.x > 0. && uv.x < 0.25 && (uv.x - 0.) * 4. < uv.y + lineWidth * 4.) { 35 | color = vec4(orange, 1.); 36 | } 37 | if(uv.x > 0.25 && uv.x < 0.5 && (uv.x - 0.25) * 4. < uv.y + lineWidth * 4.) { 38 | color = vec4(orange, 1.); 39 | } 40 | if(uv.x > 0.5 && uv.x < 0.75 && (uv.x - 0.5) * 4. < uv.y + lineWidth * 4.) { 41 | color = vec4(orange, 1.); 42 | } 43 | if(uv.x > 0.75 && ((uv.x - 0.75) * 4.) < uv.y + lineWidth * 4.) { 44 | color = vec4(orange, 1.); 45 | } 46 | 47 | if(uv.y > 0.85) { 48 | color = vec4(orange, 1.); 49 | } 50 | 51 | color *= step(uv.y, upper); 52 | color *= 1. - step(uv.y, lower); 53 | 54 | gl_FragColor = color; 55 | } 56 | -------------------------------------------------------------------------------- /src/shaders/griddymid/uniforms.json: -------------------------------------------------------------------------------- 1 | { 2 | "tDiffuse": { "type": "t", "value": null }, 3 | "frame": { "type": "f", "value": 0.0 }, 4 | "lower": { "type": "f", "value": 0.0 }, 5 | "upper": { "type": "f", "value": 0.0 } 6 | } 7 | -------------------------------------------------------------------------------- /src/shaders/griddymid/vertex.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tDiffuse; 2 | 3 | varying vec2 vUv; 4 | 5 | void main() { 6 | vUv = uv; 7 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 8 | } 9 | -------------------------------------------------------------------------------- /src/shaders/griddymidbox/fragment.glsl: -------------------------------------------------------------------------------- 1 | uniform float frame; 2 | uniform sampler2D tDiffuse; 3 | 4 | varying vec2 vUv; 5 | 6 | void main() { 7 | vec2 uv = vUv; 8 | vec3 orange = vec3(153. / 255., 224. / 255., 182. / 255.) * 0.5; 9 | vec4 color = vec4(orange * 0.1, 1.); 10 | 11 | float lineWidth = 0.02; 12 | if(uv.y < 0. + lineWidth) { 13 | color = vec4(orange, 1.); 14 | } 15 | 16 | if(uv.y > 1. - lineWidth) { 17 | color = vec4(orange, 1.); 18 | } 19 | 20 | if(uv.x < 0. + lineWidth) { 21 | color = vec4(orange, 1.); 22 | } 23 | 24 | if(uv.x > 1. - lineWidth) { 25 | color = vec4(orange, 1.); 26 | } 27 | 28 | gl_FragColor = color; 29 | } 30 | -------------------------------------------------------------------------------- /src/shaders/griddymidbox/uniforms.json: -------------------------------------------------------------------------------- 1 | { 2 | "tDiffuse": { "type": "t", "value": null }, 3 | "frame": { "type": "f", "value": 0.0 }, 4 | "lower": { "type": "f", "value": 0.0 }, 5 | "upper": { "type": "f", "value": 0.0 } 6 | } 7 | -------------------------------------------------------------------------------- /src/shaders/griddymidbox/vertex.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tDiffuse; 2 | 3 | varying vec2 vUv; 4 | 5 | void main() { 6 | vUv = uv; 7 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 8 | } 9 | -------------------------------------------------------------------------------- /src/shaders/holeTransition/fragment.glsl: -------------------------------------------------------------------------------- 1 | uniform float t; 2 | uniform sampler2D A; 3 | uniform sampler2D B; 4 | 5 | varying vec2 vUv; 6 | 7 | #define start_hole 7690. // frame number 8 | #define end_hole 7710. // frame number 9 | 10 | void main() 11 | { 12 | vec4 colorA = texture2D(A, vUv); 13 | vec4 colorB = texture2D(B, vUv); 14 | float alpha = 0.; 15 | 16 | float expand_progess = 1.0 - (t - start_hole) / (end_hole - start_hole); 17 | float radius = expand_progess; 18 | 19 | if(distance((vUv - vec2(0.5, 0.)) / vec2(9. / 16., 1.), vec2(0., .5)) < radius) { 20 | alpha = 0.0; 21 | } else { 22 | alpha = 1.0; 23 | } 24 | 25 | gl_FragColor = mix(colorA, colorB, max(min(alpha, 1.), 0.)); 26 | } 27 | -------------------------------------------------------------------------------- /src/shaders/holeTransition/uniforms.json: -------------------------------------------------------------------------------- 1 | { 2 | "A": { "type": "t", "value": null }, 3 | "B": { "type": "t", "value": null }, 4 | "t": { "type": "f", "value": 0.0 } 5 | } 6 | -------------------------------------------------------------------------------- /src/shaders/holeTransition/vertex.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tDiffuse; 2 | 3 | varying vec2 vUv; 4 | 5 | void main() { 6 | vUv = uv; 7 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 8 | } 9 | -------------------------------------------------------------------------------- /src/shaders/justTransition/fragment.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D A; 2 | uniform sampler2D B; 3 | uniform sampler2D text; 4 | 5 | varying vec2 vUv; 6 | 7 | void main() { 8 | vec4 color = texture2D(text, vUv); 9 | if (color.r > 0.25 && color.b < 0.25) { 10 | gl_FragColor = texture2D(B, vUv); 11 | } else if (color.b > 0.25 && color.r < 0.25) { 12 | gl_FragColor = texture2D(A, vUv); 13 | } else { 14 | gl_FragColor = color; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/shaders/justTransition/uniforms.json: -------------------------------------------------------------------------------- 1 | { 2 | "A": { "type": "t", "value": null }, 3 | "B": { "type": "t", "value": null }, 4 | "text": { "type": "t", "value": null } 5 | } 6 | -------------------------------------------------------------------------------- /src/shaders/justTransition/vertex.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tDiffuse; 2 | 3 | varying vec2 vUv; 4 | 5 | void main() { 6 | vUv = uv; 7 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 8 | } 9 | -------------------------------------------------------------------------------- /src/shaders/linycuba/fragment.glsl: -------------------------------------------------------------------------------- 1 | uniform float frame; 2 | uniform sampler2D tDiffuse; 3 | uniform float lineAmount; 4 | uniform float lightAmount; 5 | 6 | varying vec2 vUv; 7 | varying vec4 globalPosition; 8 | 9 | varying vec3 vNormal; 10 | 11 | void main() { 12 | vec2 uv = vUv; 13 | vec3 white = vec3(1.); 14 | vec3 pink = vec3(255., 73., 130.) / 255.; 15 | vec3 green = vec3(119., 225., 93.) / 255.; 16 | vec3 gray = vec3(55., 60., 63.) / 255.; 17 | vec4 color = vec4(white * lightAmount, 1.); 18 | vec3 lineColor = pink; 19 | vec3 directionalLight = normalize(vec3(1.)); 20 | if(frame >= 10267.) { 21 | color.rgb = mix(white, green, pow((frame - 10267.) / (10329. - 10267.), .25)); 22 | } 23 | if(frame >= 10329. - 0.1) { 24 | float light = 0.5 + dot(vNormal, directionalLight) * 0.5; 25 | color.rgb = pink * light; 26 | lineColor = gray * light; 27 | } 28 | 29 | float lineWidth = 0.1 * lineAmount; 30 | 31 | if(uv.x < lineWidth) { 32 | color = vec4(lineColor, 1.); 33 | } 34 | 35 | if(uv.x > 1. - lineWidth) { 36 | color = vec4(lineColor, 1.); 37 | } 38 | 39 | if(uv.y > 1. - lineWidth) { 40 | color = vec4(lineColor, 1.); 41 | } 42 | 43 | if(uv.y < lineWidth) { 44 | color = vec4(lineColor, 1.); 45 | } 46 | 47 | 48 | gl_FragColor = color; 49 | } 50 | -------------------------------------------------------------------------------- /src/shaders/linycuba/uniforms.json: -------------------------------------------------------------------------------- 1 | { 2 | "tDiffuse": { "type": "t", "value": null }, 3 | "frame": { "type": "f", "value": 0.0 }, 4 | "lineAmount": { "type": "f", "value": 0.0 }, 5 | "lightAmount": { "type": "f", "value": 0.0 } 6 | } 7 | -------------------------------------------------------------------------------- /src/shaders/linycuba/vertex.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tDiffuse; 2 | uniform float frame; 3 | 4 | varying vec2 vUv; 5 | varying vec4 globalPosition; 6 | varying vec3 vNormal; 7 | 8 | void main() { 9 | vUv = uv; 10 | vNormal = normalMatrix * normal; 11 | globalPosition = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 12 | gl_Position = globalPosition; 13 | } 14 | -------------------------------------------------------------------------------- /src/shaders/logotransitionquadpass/fragment.glsl: -------------------------------------------------------------------------------- 1 | uniform float frame; 2 | uniform float yOffset; 3 | uniform sampler2D logo; 4 | uniform sampler2D scene; 5 | 6 | varying vec2 vUv; 7 | 8 | void main() { 9 | 10 | vec2 uv = vUv; 11 | uv.y = mod(uv.y + yOffset, 1.); 12 | vec4 sceneColor = texture2D(scene, uv); 13 | vec4 logoColor = texture2D(logo, uv); 14 | 15 | float t = (frame - 4601.) / (4632. - 4601.); 16 | float darkener = 1. - mix(0., 1., clamp(t, 0., 1.)) * 0.5; 17 | 18 | vec3 color = mix(sceneColor.rgb * darkener, logoColor.rgb, logoColor.a); 19 | 20 | gl_FragColor = vec4(color, 1.); 21 | } 22 | -------------------------------------------------------------------------------- /src/shaders/logotransitionquadpass/uniforms.json: -------------------------------------------------------------------------------- 1 | { 2 | "logo": { "type": "t", "value": null }, 3 | "scene": { "type": "t", "value": null }, 4 | "frame": { "type": "f", "value": 0.0 }, 5 | "yOffset": { "type": "f", "value": 0.0 } 6 | } 7 | -------------------------------------------------------------------------------- /src/shaders/logotransitionquadpass/vertex.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tDiffuse; 2 | 3 | varying vec2 vUv; 4 | 5 | void main() { 6 | vUv = uv; 7 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 8 | } 9 | -------------------------------------------------------------------------------- /src/shaders/lulle/fragment.glsl: -------------------------------------------------------------------------------- 1 | uniform float frame; 2 | uniform float BEAN; 3 | uniform float BEAT; 4 | uniform float numOfBalls; 5 | uniform sampler2D tDiffuse; 6 | uniform vec3 cameraDirection; 7 | uniform vec3 myCameraPosition; 8 | 9 | #define PI 3.1415926535897932384626433832795 10 | 11 | varying vec2 vUv; 12 | 13 | const int MAX_STEPS = 16; 14 | const float EPS = 0.001; 15 | const float END = 100.0; 16 | const float START = 0.0; 17 | 18 | const vec3 PINK = vec3(255., 73., 130.)/255.; 19 | const vec3 GREY = vec3(55., 60., 63.)/255.; 20 | const vec3 GREEN = vec3(119., 225., 130.)/255.; 21 | const vec3 WHITE = vec3(255., 255., 255.)/255.; 22 | 23 | vec2 smin(vec2 a, vec2 b, float k) { 24 | float h = clamp(0.5 + 0.5 * (b.x - a.x) / k, 0.0, 1.0); 25 | float material = mix(a.y, b.y, h); 26 | return vec2(mix(b.x, a.x, h) - k * h * (1.0 - h), material); 27 | } 28 | 29 | vec2 minmin(vec2 d1, vec2 d2) { 30 | float material = d1.y; 31 | if (d1.x > d2.x) { 32 | material = d2.y; 33 | } 34 | return vec2(smin(d1, d2, 1.).x, material); 35 | } 36 | 37 | float displace(vec3 p, float d1) { 38 | float d2 = 0.05*(1.-sin(20.*p.x))*(1.-cos(20.*p.y))*cos(20.*p.z-frame/60.); 39 | return d1+d2; 40 | } 41 | 42 | float rand(vec2 co){ 43 | return fract(sin(dot(co.xy, vec2(12.9898,78.233))) * 43758.5453); 44 | } 45 | 46 | float sphere(vec3 p, float s) { 47 | return length(p)-s; 48 | } 49 | 50 | vec2 sdf(in vec3 p) { 51 | float startBEAN = 1824. + 24.; 52 | float repeatSize = 15.; 53 | float repeatSizeY = repeatSize * .75; 54 | float offset = 0.; 55 | if (BEAN >= 2064. && BEAN < 2184.) { 56 | offset = mod(BEAN - startBEAN, 24.); 57 | } 58 | 59 | p.x += repeatSize / 2. * step(repeatSizeY, mod(p.y + 5., repeatSizeY * 2.)); 60 | p.x = mod(p.x + repeatSize / 2., repeatSize) - repeatSize / 2.; 61 | p.y = mod(p.y + repeatSizeY / 2., repeatSizeY) - repeatSizeY / 2.; 62 | 63 | if(frame < 4820.) { 64 | return vec2(999999., 1.); 65 | } 66 | 67 | float centerSize = 0.5 + cos(mod(BEAN - startBEAN, 48.) / 48. * PI) / 4.; 68 | vec2 s = vec2(sphere(p, centerSize * 1.5), 1.); 69 | 70 | for (float i = 0.; i < 24.; i++) { 71 | float circleIndex = floor(i / 8.0); 72 | float size = 73 | 0.5 - circleIndex * 0.1 + 74 | cos(mod(-0.8 * (floor(i/8.) + 1.) + BEAN - startBEAN, 48.) / 48. * PI) / 4.; 75 | 76 | float radius = 1.5 + circleIndex; 77 | float angle = 2. * PI * i/8.; 78 | float visible = step(i+4., numOfBalls); 79 | float x = sin(angle + offset) * radius * visible; 80 | float y = cos(angle + offset) * radius * visible; 81 | vec2 a = vec2(sphere(p-vec3(x, y, 0.), size), 1.); 82 | s = minmin(s, a); 83 | } 84 | return s; 85 | } 86 | 87 | vec2 march(vec3 eye, vec3 dir, float s, float e) { 88 | float d = s; 89 | for (int i = 0; i < MAX_STEPS; i++) { 90 | vec2 res = sdf(eye + d * dir); 91 | if (res.x < EPS) { 92 | return vec2(d, res.y); 93 | } 94 | d += res.x; 95 | if (d >= e) { 96 | return vec2(e, .0); 97 | } 98 | } 99 | return vec2(e, .0); 100 | } 101 | 102 | vec3 rayDir(float fov, vec2 uv) { 103 | vec2 xy = uv * 2.0 - 1.0; 104 | xy.y = xy.y / (16.0 / 9.0); 105 | float z = 2.0 / tan(radians(fov / 2.0)); 106 | return normalize(vec3(xy, -z)); 107 | } 108 | 109 | vec3 estimateNormal(vec3 p) { 110 | return normalize(vec3( 111 | sdf(vec3(p.x + EPS, p.yz)).x - sdf(vec3(p.x - EPS, p.yz)).x, 112 | sdf(vec3(p.x, p.y + EPS, p.z)).x - sdf(vec3(p.x, p.y - EPS, p.z)).x, 113 | sdf(vec3(p.xy, p.z + EPS)).x - sdf(vec3(p.xy, p.z - EPS)).x 114 | )); 115 | } 116 | 117 | 118 | vec3 phongContribForLight(vec3 k_d, vec3 k_s, float alpha, vec3 p, vec3 eye, 119 | vec3 lightPos, vec3 lightIntensity) { 120 | vec3 N = estimateNormal(p); 121 | vec3 L = normalize(lightPos - p); 122 | vec3 V = normalize(eye - p); 123 | vec3 R = normalize(reflect(-L, N)); 124 | 125 | float dotLN = dot(L, N); 126 | float dotRV = dot(R, V); 127 | 128 | if (dotLN < 0.0) { 129 | return vec3(0.0, 0.0, 0.0); 130 | } 131 | 132 | if (dotRV < 0.0) { 133 | return lightIntensity * (k_d * dotLN); 134 | } 135 | return lightIntensity * (k_d * dotLN + k_s * pow(dotRV, alpha)); 136 | } 137 | 138 | vec3 phongIllumination(vec3 k_a, vec3 k_d, vec3 k_s, float alpha, vec3 p, vec3 eye) { 139 | 140 | vec3 pos = p; 141 | vec3 nor = estimateNormal(p); 142 | vec3 rd = eye; 143 | vec3 ref = reflect( rd, nor ); 144 | vec3 lig = normalize( vec3(-0.4, 0.7, -0.6) ); 145 | float amb = clamp( 0.5+0.5*nor.y, 0.0, 1.0 ); 146 | float dif = clamp( dot( nor, lig ), 0.0, 1.0 ); 147 | float bac = clamp( dot( nor, normalize(vec3(-lig.x,0.0,-lig.z))), 0.0, 1.0 )*clamp( 1.0-pos.y,0.0,1.0); 148 | float fre = pow( clamp(1.0+dot(nor,rd),0.0,1.0), 2.0 ); 149 | float spe = pow(clamp( dot( ref, lig ), 0.0, 1.0 ),16.0); 150 | 151 | vec3 lin = vec3(0.0); 152 | lin += 1.30*dif*vec3(1.00,0.80,0.55); 153 | lin += 2.00*spe*vec3(1.00,0.90,0.70)*dif; 154 | lin += 0.40*amb*vec3(0.40,0.60,1.00); 155 | lin += 0.50*bac*vec3(0.25,0.25,0.25); 156 | lin += 0.25*fre*vec3(1.00,1.00,1.00); 157 | vec3 color = k_a * lin; 158 | 159 | return color; 160 | } 161 | 162 | vec4 background(vec2 uv) { 163 | return texture2D(tDiffuse, mod(uv * vec2(16., 9.) / 16. * 2., 1.)); 164 | float intensity = 0.; 165 | intensity = (1. + floor(sin(uv.x * 100. + frame/100.) + sin(uv.y * 50.))); 166 | vec3 color = GREY; 167 | intensity = intensity * (1. + floor(1. + sin(mod(BEAN, 12.)/12.))); 168 | return vec4(color*(0.4 + 0.2 * intensity), 1.); 169 | } 170 | 171 | void main() { 172 | vec3 eye = myCameraPosition; 173 | if (BEAN > 2040.) { 174 | eye.z = min((BEAN - 2000.)/2., 95.); 175 | } 176 | if (frame > 5728.) { 177 | eye.z = mix(95., 1., clamp((frame - 5729.) / (5750. - 5728.), 0.0, 1.0)); 178 | } 179 | 180 | vec3 dir = rayDir(60.0, vUv); 181 | 182 | vec2 res = march(eye, dir, START, END); 183 | 184 | vec3 color = vec3(.0); 185 | if (res.x >= END-EPS) { 186 | color = background((vUv + vec2(-.5, frame / 800.)) * (1. + (frame - 4726.) / 1000.)).xyz; 187 | } else { 188 | vec3 p = eye + dir * res.x; 189 | color = vec3(0.75); 190 | color = phongIllumination(color, color, normalize(vec3(1.0, 1.0, 1.0)), 10.0, p, eye); 191 | } 192 | 193 | vec2 uv = (vUv - 0.5) * 2.; 194 | color *= 0.75 + (1. - abs(uv.x * uv.y)) * 0.25; 195 | 196 | gl_FragColor = vec4(color, 1.0); 197 | } 198 | -------------------------------------------------------------------------------- /src/shaders/lulle/uniforms.json: -------------------------------------------------------------------------------- 1 | { 2 | "tDiffuse": { "type": "t", "value": null }, 3 | "frame": { "type": "f", "value": 0.0 }, 4 | "myCameraPosition": { "type": "v3", "value": null }, 5 | "cameraDirection": { "type": "v3", "value": null }, 6 | "BEAT": { "type": "f", "value": 0.0 }, 7 | "BEAN": { "type": "f", "value": 0.0 }, 8 | "numOfBalls": { "type": "f", "value": 0.0 } 9 | } 10 | -------------------------------------------------------------------------------- /src/shaders/lulle/vertex.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tDiffuse; 2 | 3 | varying vec2 vUv; 4 | 5 | void main() { 6 | vUv = uv; 7 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 8 | } 9 | -------------------------------------------------------------------------------- /src/shaders/metatronoverlayer/fragment.glsl: -------------------------------------------------------------------------------- 1 | uniform float frame; 2 | uniform float translationOverX; 3 | uniform float translationUnderX; 4 | uniform sampler2D tDiffuse; 5 | uniform sampler2D overlay; 6 | 7 | varying vec2 vUv; 8 | 9 | void main() { 10 | vec4 overlaySample = texture2D(overlay, vUv + vec2(translationOverX, 0.)); 11 | vec4 tDiffuseSample = texture2D(tDiffuse, vUv + vec2(translationUnderX, 0.)); 12 | gl_FragColor = vec4(mix( 13 | tDiffuseSample.rgb, 14 | overlaySample.rgb, 15 | overlaySample.a), 1.); 16 | } 17 | -------------------------------------------------------------------------------- /src/shaders/metatronoverlayer/uniforms.json: -------------------------------------------------------------------------------- 1 | { 2 | "tDiffuse": { "type": "t", "value": null }, 3 | "overlay": { "type": "t", "value": null }, 4 | "frame": { "type": "f", "value": 0.0 }, 5 | "translationUnderX": { "type": "f", "value": 0.0 }, 6 | "translationOverX": { "type": "f", "value": 0.0 } 7 | } 8 | -------------------------------------------------------------------------------- /src/shaders/metatronoverlayer/vertex.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tDiffuse; 2 | 3 | varying vec2 vUv; 4 | 5 | void main() { 6 | vUv = uv; 7 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 8 | } 9 | -------------------------------------------------------------------------------- /src/shaders/pyramidfx/fragment.glsl: -------------------------------------------------------------------------------- 1 | uniform float frame; 2 | uniform float barSize; 3 | uniform sampler2D tDiffuse; 4 | 5 | varying vec2 vUv; 6 | 7 | float rand(vec2 co){ 8 | return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); 9 | } 10 | 11 | void main() { 12 | vec2 uv = vUv; 13 | 14 | 15 | vec3 original = texture2D(tDiffuse, uv).rgb; 16 | 17 | if(uv.y < barSize || uv.y > 1. - barSize) { 18 | //= vec4(vec3(55., 60., 63.) / 255. / 6., 1.); 19 | original = vec3(55., 60., 63.) / 255. / 16.; 20 | } 21 | 22 | vec2 fakeResolution = vec2(16., 9.) * 30.; 23 | vec2 pixelated = floor(uv * fakeResolution) / fakeResolution; 24 | vec2 sampler = vec2(pixelated.x + frame * 0.0001, pixelated.y + frame * 0.00001); 25 | vec3 epsilon = vec3(0.001, -0.001, 0.); 26 | float noise = ( 27 | rand(sampler + epsilon.xx) + 28 | rand(sampler + epsilon.xy) + 29 | rand(sampler + epsilon.xz) + 30 | 31 | rand(sampler + epsilon.zx) + 32 | rand(sampler + epsilon.zy) + 33 | 2. * rand(sampler + epsilon.zz) + 34 | 35 | rand(sampler + epsilon.yx) + 36 | rand(sampler + epsilon.yy) + 37 | rand(sampler + epsilon.yz)) / 10.; 38 | 39 | noise *= (1. - length((uv - 0.5) * vec2(16., 9.) / 9.)); 40 | noise += 0.1; 41 | 42 | float vignette = (1. - length((uv - 0.5) * vec2(16., 9.) / 20.)); 43 | 44 | float scanlines = 0.8 + max(0., abs(sin(uv.y * 3.14159265 * 2. * 576.))) * 0.2; 45 | 46 | vec3 color = (original + noise * 0.1) * vignette * scanlines; 47 | 48 | color = mix(color, pow(color, vec3(2.2)), vec3(0.2)); 49 | 50 | gl_FragColor = vec4(color * 1.5, 1.); 51 | } 52 | -------------------------------------------------------------------------------- /src/shaders/pyramidfx/uniforms.json: -------------------------------------------------------------------------------- 1 | { 2 | "tDiffuse": { "type": "t", "value": null }, 3 | "barSize": { "type": "f", "value": 0.0 }, 4 | "frame": { "type": "f", "value": 0.0 } 5 | } 6 | -------------------------------------------------------------------------------- /src/shaders/pyramidfx/vertex.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tDiffuse; 2 | 3 | varying vec2 vUv; 4 | 5 | void main() { 6 | vUv = uv; 7 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 8 | } 9 | -------------------------------------------------------------------------------- /src/shaders/slideTransition/fragment.glsl: -------------------------------------------------------------------------------- 1 | uniform float t; 2 | uniform sampler2D A; 3 | uniform sampler2D B; 4 | 5 | varying vec2 vUv; 6 | 7 | void main() { 8 | gl_FragColor = texture2D(A, vUv); 9 | if (t > 0. && t > vUv.x) { 10 | gl_FragColor = texture2D(B, vec2(vUv.x - 1. + t, vUv.y)); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/shaders/slideTransition/uniforms.json: -------------------------------------------------------------------------------- 1 | { 2 | "A": { "type": "t", "value": null }, 3 | "B": { "type": "t", "value": null }, 4 | "t": { "type": "f", "value": 0.0 } 5 | } 6 | -------------------------------------------------------------------------------- /src/shaders/slideTransition/vertex.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tDiffuse; 2 | 3 | varying vec2 vUv; 4 | 5 | void main() { 6 | vUv = uv; 7 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 8 | } 9 | -------------------------------------------------------------------------------- /src/shaders/tartan/fragment.glsl: -------------------------------------------------------------------------------- 1 | uniform float frame; 2 | uniform float t; 3 | 4 | varying vec2 vUv; 5 | 6 | #define M_PI 3.1415926535897932384626433832795 7 | 8 | vec2 rotate(vec2 point, float angle) { 9 | float s = sin(angle); 10 | float c = cos(angle); 11 | return vec2(point.x * c - point.y * s, 12 | point.x * s + point.y * c); 13 | } 14 | 15 | void main() { 16 | vec4 pink = vec4(255. / 255., 73. / 255., 130. / 255., 1.); 17 | vec4 green = vec4(119. / 255., 225. / 255., 93. / 255., 1.); 18 | 19 | float fadeIn = clamp(t / 2., 0., 1.); 20 | 21 | vec2 mod_uv = mod(vUv / 5. + 0. * vec2(frame / 8000., frame / 12000.), 0.05); 22 | vec4 color = mix(pink, vec4(1., 1., 1., 1.), fadeIn * .6 * step(mod_uv.x, .01)); 23 | color = mix(color, vec4(1., 1., 1., 1.), fadeIn * .6 * step(mod_uv.y, .01)); 24 | vec2 small_stripe_vUv = rotate(vUv / 2., M_PI / 4.) + 0. * vec2(frame / 8000., frame / 12000.); 25 | vec2 mod_uv2 = mod(small_stripe_vUv / 5., 0.05); 26 | color = mix(color, green, fadeIn * .5 * step(mod_uv2.x, .003)); 27 | color = mix(color, green, fadeIn * .5 * step(mod_uv2.y, .003)); 28 | 29 | color *= .9; 30 | 31 | gl_FragColor = vec4(color); 32 | } 33 | -------------------------------------------------------------------------------- /src/shaders/tartan/uniforms.json: -------------------------------------------------------------------------------- 1 | { 2 | "frame": { "type": "f", "value": 0.0 }, 3 | "t": { "type": "f", "value": 0.0 } 4 | } 5 | -------------------------------------------------------------------------------- /src/shaders/tartan/vertex.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tDiffuse; 2 | 3 | varying vec2 vUv; 4 | 5 | void main() { 6 | vUv = uv; 7 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 8 | } 9 | -------------------------------------------------------------------------------- /src/shaders/tartarstuff/fragment.glsl: -------------------------------------------------------------------------------- 1 | uniform float frame; 2 | uniform sampler2D tDiffuse; 3 | 4 | varying vec2 vUv; 5 | 6 | void main() { 7 | gl_FragColor = vec4(vUv, 0.5 + 0.5 * sin(frame / 60.0), 1.0); 8 | } 9 | -------------------------------------------------------------------------------- /src/shaders/tartarstuff/uniforms.json: -------------------------------------------------------------------------------- 1 | { 2 | "tDiffuse": { "type": "t", "value": null }, 3 | "frame": { "type": "f", "value": 0.0 } 4 | } 5 | -------------------------------------------------------------------------------- /src/shaders/tartarstuff/vertex.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tDiffuse; 2 | 3 | varying vec2 vUv; 4 | 5 | void main() { 6 | vUv = uv; 7 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 8 | } 9 | -------------------------------------------------------------------------------- /src/shaders/textout/fragment.glsl: -------------------------------------------------------------------------------- 1 | uniform float t; 2 | uniform sampler2D A; 3 | uniform sampler2D B; 4 | 5 | varying vec2 vUv; 6 | 7 | void main() { 8 | vec4 colorA = texture2D(A, vUv); 9 | vec4 colorB; 10 | if (t > 0.0) { 11 | colorB = texture2D(B, vUv); 12 | } else { 13 | colorB = vec4(55./255., 60./255., 63./255., 1.); 14 | } 15 | gl_FragColor = mix(colorB, vec4(colorA.rgb, 1.0), colorA.a); 16 | } 17 | -------------------------------------------------------------------------------- /src/shaders/textout/uniforms.json: -------------------------------------------------------------------------------- 1 | { 2 | "A": { "type": "t", "value": null }, 3 | "B": { "type": "t", "value": null }, 4 | "t": { "type": "f", "value": 0.0 } 5 | } 6 | -------------------------------------------------------------------------------- /src/shaders/textout/vertex.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tDiffuse; 2 | 3 | varying vec2 vUv; 4 | 5 | void main() { 6 | vUv = uv; 7 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 8 | } 9 | -------------------------------------------------------------------------------- /src/slideTransitionNode.js: -------------------------------------------------------------------------------- 1 | (function(global) { 2 | class slideTransitionNode extends NIN.ShaderNode { 3 | constructor(id, options) { 4 | options.inputs = { 5 | A: new NIN.TextureInput(), 6 | B: new NIN.TextureInput(), 7 | }; 8 | super(id, options); 9 | } 10 | 11 | warmup(renderer) { 12 | this.update(2729); 13 | this.render(renderer); 14 | } 15 | 16 | update(frame) { 17 | this.uniforms.t.value = lerp(0, 1, (frame - FRAME_FOR_BEAN(21 * 48 + 42)) / 11); 18 | this.uniforms.A.value = this.inputs.A.getValue(); 19 | this.uniforms.B.value = this.inputs.B.getValue(); 20 | 21 | if(frame < 2739){ //Force AtariRace bloom 22 | demo.nm.nodes.bloom.opacity = 0.5; 23 | } 24 | } 25 | } 26 | 27 | global.slideTransitionNode = slideTransitionNode; 28 | })(this); 29 | -------------------------------------------------------------------------------- /src/tartarstuffNode.js: -------------------------------------------------------------------------------- 1 | (function(global) { 2 | class tartarstuffNode extends NIN.ShaderNode { 3 | constructor(id, options) { 4 | super(id, options); 5 | } 6 | 7 | warmup(renderer) { 8 | this.update(10611); 9 | this.render(renderer); 10 | } 11 | 12 | update(frame) { 13 | this.uniforms.frame.value = frame * 4; 14 | this.uniforms.t.value = (frame - FRAME_FOR_BEAN(84 * 48 + 18)) / 60 * 10; 15 | } 16 | } 17 | 18 | global.tartarstuffNode = tartarstuffNode; 19 | })(this); 20 | -------------------------------------------------------------------------------- /src/textigrades.js: -------------------------------------------------------------------------------- 1 | (function (global) { 2 | class textigrades extends NIN.Node { 3 | constructor(id) { 4 | super(id, { 5 | outputs: { 6 | render: new NIN.TextureOutput() 7 | } 8 | }); 9 | 10 | this.canvas = document.createElement('canvas'); 11 | this.ctx = this.canvas.getContext('2d'); 12 | this.resize(); 13 | this.output = new THREE.VideoTexture(this.canvas); 14 | this.output.minFilter = THREE.LinearFilter; 15 | this.output.magFilter = THREE.LinearFilter; 16 | } 17 | 18 | warmup(renderer) { 19 | this.update(10000); 20 | this.render(renderer); 21 | } 22 | 23 | update(frame) { 24 | this.frame = frame; 25 | } 26 | 27 | render() { 28 | const frame = this.frame; 29 | this.ctx.clearRect( 30 | 0, 0, this.canvas.width, this.canvas.height); 31 | 32 | this.ctx.save(); 33 | this.ctx.scale(GU, GU); 34 | this.ctx.translate(8, 4.5); 35 | this.ctx.fillStyle = 'white'; 36 | this.ctx.font = 'bold 0.8pt schmalibre'; 37 | this.ctx.textAlign = 'left'; 38 | this.ctx.textBaseline = 'alphabetic'; 39 | 40 | const x = 0; 41 | const y = -0.18 + 0.51; 42 | if (BEAN >= 84 * 48 + 4) { 43 | //Show nothing 44 | } else if (BEAN >= 3960 + 48 + 12 + 10) { 45 | this.ctx.fillStyle = 'rgb(55, 60, 63)'; 46 | this.ctx.fillText('GERMANY', x + 0.1, y + 0.1); 47 | this.ctx.fillStyle = 'rgb(255, 73, 130)'; 48 | this.ctx.fillText('GERMANY', x, y); 49 | } else if (BEAN >= 3960 + 48 + 12 + 4) { 50 | this.ctx.fillStyle = 'rgb(55, 60, 63)'; 51 | this.ctx.fillText('GERMA', x + 0.1, y + 0.1); 52 | this.ctx.fillStyle = 'rgb(255, 73, 130)'; 53 | this.ctx.fillText('GERMA', x, y); 54 | } else if (BEAN >= 3960 + 48 + 12) { 55 | this.ctx.fillStyle = 'rgb(55, 60, 63)'; 56 | this.ctx.fillText('GER', x + 0.1, y + 0.1); 57 | this.ctx.fillStyle = 'rgb(255, 73, 130)'; 58 | this.ctx.fillText('GER', x, y); 59 | } else if (BEAN >= 3960 + 48 + 4) { 60 | this.ctx.font = 'bold 0.8pt schmalibre'; 61 | this.ctx.fillStyle = 'rgb(55, 60, 63)'; 62 | this.ctx.fillText('SAARBRÜCKEN', x + 0.1, y + 0.1); 63 | this.ctx.fillStyle = 'rgb(255, 73, 130)'; 64 | this.ctx.fillText('SAARBRÜCKEN', x, y); 65 | this.ctx.fillStyle = 'rgb(55, 60, 63)'; 66 | } else if (BEAN >= 3960 + 48) { 67 | this.ctx.font = 'bold 0.8pt schmalibre'; 68 | this.ctx.fillStyle = 'rgb(55, 60, 63)'; 69 | this.ctx.fillText('SAARBRÜCK', x + 0.1, y + 0.1); 70 | this.ctx.fillStyle = 'rgb(255, 73, 130)'; 71 | this.ctx.fillText('SAARBRÜCK', x, y); 72 | this.ctx.fillStyle = 'rgb(55, 60, 63)'; 73 | this.ctx.fillStyle = 'rgb(55, 60, 63)'; 74 | } else if (BEAN >= 3960 + 24 + 12 + 10) { 75 | this.ctx.font = 'bold 0.8pt schmalibre'; 76 | this.ctx.fillStyle = 'rgb(55, 60, 63)'; 77 | this.ctx.fillText('SAAR', x + 0.1, y + 0.1); 78 | this.ctx.fillStyle = 'rgb(255, 73, 130)'; 79 | this.ctx.fillText('SAAR', x, y); 80 | this.ctx.fillStyle = 'rgb(55, 60, 63)'; 81 | } else if (BEAN >= 3960 + 24 + 12 + 8) { 82 | this.ctx.font = 'bold 0.8pt schmalibre'; 83 | this.ctx.fillStyle = 'rgb(55, 60, 63)'; 84 | this.ctx.fillText('SAA', x + 0.1, y + 0.1); 85 | this.ctx.fillStyle = 'rgb(255, 73, 130)'; 86 | this.ctx.fillText('SAA', x, y); 87 | this.ctx.fillStyle = 'rgb(55, 60, 63)'; 88 | } else if (BEAN >= 3960 + 24 + 12 + 6) { 89 | this.ctx.font = 'bold 0.8pt schmalibre'; 90 | this.ctx.fillStyle = 'rgb(55, 60, 63)'; 91 | this.ctx.fillText('SA', x + 0.1, y + 0.1); 92 | this.ctx.fillStyle = 'rgb(255, 73, 130)'; 93 | this.ctx.fillText('SA', x, y); 94 | this.ctx.fillStyle = 'rgb(55, 60, 63)'; 95 | } else if (BEAN >= 3960 + 24 + 12 + 4) { 96 | this.ctx.font = 'bold 0.8pt schmalibre'; 97 | this.ctx.fillStyle = 'rgb(55, 60, 63)'; 98 | this.ctx.fillText('S', x + 0.1, y + 0.1); 99 | this.ctx.fillStyle = 'rgb(255, 73, 130)'; 100 | this.ctx.fillText('S', x, y); 101 | this.ctx.fillStyle = 'rgb(55, 60, 63)'; 102 | } else if (BEAN >= 3960 + 24 + 6 + 4) { 103 | this.ctx.font = 'bold 0.8pt schmalibre'; 104 | this.ctx.fillStyle = 'rgb(55, 60, 63)'; 105 | this.ctx.fillText('EASTER 2018', x + 0.1, y + 0.1); 106 | this.ctx.fillStyle = 'rgb(255, 73, 130)'; 107 | this.ctx.fillText('EASTER 2018', x, y); 108 | this.ctx.fillStyle = 'rgb(55, 60, 63)'; 109 | } else if (BEAN >= 3960 + 24 + 6) { 110 | this.ctx.fillStyle = 'rgb(55, 60, 63)'; 111 | this.ctx.fillText('EASTER 201', x + 0.1, y + 0.1); 112 | this.ctx.fillStyle = 'rgb(255, 73, 130)'; 113 | this.ctx.fillText('EASTER 201', x, y); 114 | this.ctx.fillStyle = 'rgb(55, 60, 63)'; 115 | } else if (BEAN >= 3960 + 24) { 116 | this.ctx.fillStyle = 'rgb(55, 60, 63)'; 117 | this.ctx.fillText('EASTER 20', x + 0.1, y + 0.1); 118 | this.ctx.fillStyle = 'rgb(255, 73, 130)'; 119 | this.ctx.fillText('EASTER 20', x, y); 120 | } else if (BEAN >= 3960 + 24 - 2) { 121 | this.ctx.fillStyle = 'rgb(55, 60, 63)'; 122 | this.ctx.fillText('EASTER', x + 0.1, y + 0.1); 123 | this.ctx.fillStyle = 'rgb(255, 73, 130)'; 124 | this.ctx.fillText('EASTER', x, y); 125 | } else if (BEAN >= 3960 + 24 - 6) { 126 | this.ctx.fillStyle = 'rgb(55, 60, 63)'; 127 | this.ctx.fillText('EAST', x + 0.1, y + 0.1); 128 | this.ctx.fillStyle = 'rgb(255, 73, 130)'; 129 | this.ctx.fillText('EAST', x, y); 130 | } else if (BEAN >= 3960 + 9) { 131 | this.ctx.fillStyle = 'rgb(55, 60, 63)'; 132 | this.ctx.fillText('E WERK', x + 0.1, y + 0.1); 133 | this.ctx.fillStyle = 'rgb(255, 73, 130)'; 134 | this.ctx.fillText('E WERK', x, y); 135 | } else if (BEAN >= 3960) { 136 | this.ctx.fillStyle = 'rgb(55, 60, 63)'; 137 | this.ctx.fillText('E', x + 0.1, y + 0.1); 138 | this.ctx.fillStyle = 'rgb(255, 73, 130)'; 139 | this.ctx.fillText('E', x, y); 140 | } else if (BEAN >= 3936) { 141 | this.ctx.textAlign = 'center'; 142 | this.ctx.font = 'bold 0.6pt schmalibre'; 143 | this.ctx.fillStyle = 'rgb(55, 60, 63)'; 144 | this.ctx.scale(3, 3); 145 | this.ctx.translate((Math.random() - 0.5) * 0.2, 146 | (Math.random() - 0.5) * 0.2); 147 | this.ctx.fillText('REVISION', 0, -0.25 + 0.51); 148 | } else if (BEAN >= 3912) { 149 | this.ctx.textAlign = 'center'; 150 | this.ctx.fillText('NO LIMIT', 0, -0.19 + 0.51); 151 | } else if (BEAN >= 3888) { 152 | const inT = lerp(0, 1, (frame - FRAME_FOR_BEAN(3888)) / ( 153 | FRAME_FOR_BEAN(3888 + 3) - FRAME_FOR_BEAN(3888))); 154 | const outT = lerp(0, 1, (frame - FRAME_FOR_BEAN(3912 - 3)) / (FRAME_FOR_BEAN(3912) - FRAME_FOR_BEAN(3912 - 3))); 155 | this.ctx.textAlign = 'left'; 156 | const word = 'NO FUSS'; 157 | this.ctx.fillText( 158 | word.slice(0, lerp(0, word.length, inT - outT)), 159 | -7, 160 | -.19 + 0.51); 161 | } else if (BEAN >= 3864) { 162 | const inT = lerp(0, 1, (frame - FRAME_FOR_BEAN(3864)) / ( 163 | FRAME_FOR_BEAN(3864 + 3) - FRAME_FOR_BEAN(3864))); 164 | const outT = lerp(0, 1, (frame - FRAME_FOR_BEAN(3888 - 3)) / (FRAME_FOR_BEAN(3888) - FRAME_FOR_BEAN(3888 - 3))); 165 | this.ctx.textAlign = 'left'; 166 | const word = 'NO THEME'; 167 | this.ctx.fillText( 168 | word.slice(0, lerp(0, word.length, inT - outT)), 169 | -7, 170 | -0.19 + 0.51); 171 | } 172 | 173 | this.ctx.restore(); 174 | 175 | this.output.needsUpdate = true; 176 | this.outputs.render.setValue(this.output); 177 | } 178 | 179 | resize() { 180 | this.canvas.width = 16 * GU; 181 | this.canvas.height = 9 * GU; 182 | } 183 | } 184 | 185 | global.textigrades = textigrades; 186 | })(this); 187 | -------------------------------------------------------------------------------- /src/textoutNode.js: -------------------------------------------------------------------------------- 1 | (function(global) { 2 | class textoutNode extends NIN.ShaderNode { 3 | constructor(id, options) { 4 | options.inputs = { 5 | A: new NIN.TextureInput(), 6 | B: new NIN.TextureInput(), 7 | }; 8 | super(id, options); 9 | 10 | this.throb = 0; 11 | } 12 | 13 | warmup(renderer) { 14 | this.update(2229); 15 | this.render(renderer); 16 | } 17 | 18 | update(frame) { 19 | 20 | this.inputs.A.enabled = BEAN < 24 * 12 * 4; 21 | this.inputs.B.enabled = BEAN >= 23 * 12 * 4; 22 | 23 | const t = lerp( 24 | 0, 25 | 2, 26 | (frame - FRAME_FOR_BEAN(23 * 12 * 4)) / (FRAME_FOR_BEAN(24 * 12 * 4) - FRAME_FOR_BEAN(23 * 12 * 4)) 27 | ); 28 | 29 | this.throb *= .95; 30 | if(BEAT) { 31 | switch(BEAN % 96) { 32 | case 0: 33 | case 9: 34 | case 24: 35 | case 24 + 9: 36 | case 24 + 18: 37 | case 48 + 12: 38 | case 48 + 24: 39 | this.throb = 1; 40 | } 41 | } 42 | 43 | this.uniforms.A.value = this.inputs.A.getValue(); 44 | this.uniforms.B.value = this.inputs.B.getValue(); 45 | } 46 | } 47 | 48 | global.textoutNode = textoutNode; 49 | })(this); 50 | -------------------------------------------------------------------------------- /src/trianglebg.js: -------------------------------------------------------------------------------- 1 | (function(global) { 2 | class trianglebg extends NIN.Node { 3 | constructor(id) { 4 | super(id, { 5 | outputs: { 6 | render: new NIN.TextureOutput() 7 | } 8 | }); 9 | 10 | this.canvas = document.createElement('canvas'); 11 | this.ctx = this.canvas.getContext('2d'); 12 | this.resize(); 13 | this.output = new THREE.VideoTexture(this.canvas); 14 | this.output.minFilter = THREE.LinearFilter; 15 | this.output.magFilter = THREE.LinearFilter; 16 | 17 | this.lines = []; 18 | const radius = 0.5; 19 | let totalLength = 0; 20 | for(let i = 0; i < 5; i++) { 21 | const angle = Math.PI * 2 * i / 3; 22 | const angleNext = Math.PI * 2 * (i + 1) / 3; 23 | const x = radius * Math.sin(angle); 24 | const y = radius * Math.cos(angle); 25 | const xNext = radius * Math.sin(angleNext); 26 | const yNext = radius * Math.cos(angleNext); 27 | const dx = xNext - x; 28 | const dy = yNext - y; 29 | const length = Math.sqrt(dx * dx + dy * dy); 30 | totalLength += length; 31 | this.lines.push({ 32 | from: {x, y}, 33 | to: {x: xNext, y: yNext}, 34 | length, 35 | }); 36 | } 37 | this.lines.totalLength = totalLength; 38 | } 39 | 40 | warmup(renderer) { 41 | this.update(4766); 42 | this.render(renderer); 43 | } 44 | 45 | update(frame) { 46 | this.frame = frame; 47 | } 48 | 49 | resize() { 50 | this.canvas.width = 8 * GU; 51 | this.canvas.height = 8 * GU; 52 | } 53 | 54 | drawTriangle(x, y, amount) { 55 | this.ctx.save(); 56 | this.ctx.translate(x, y); 57 | this.ctx.strokeStyle = 'rgb(255, 73, 130)'; 58 | this.ctx.lineWidth = 0.05; 59 | 60 | this.ctx.beginPath(); 61 | let lengthLeft = this.lines.totalLength * amount; 62 | for(let i = 0; i < this.lines.length; i++) { 63 | if(lengthLeft <= 0) { 64 | break; 65 | } 66 | const line = this.lines[i]; 67 | const t = lengthLeft / line.length; 68 | if(i == 0) { 69 | this.ctx.moveTo(line.from.x, line.from.y); 70 | } 71 | this.ctx.lineTo(lerp(line.from.x, line.to.x, t), 72 | lerp(line.from.y, line.to.y, t)); 73 | lengthLeft -= line.length; 74 | } 75 | 76 | this.ctx.stroke(); 77 | this.ctx.restore(); 78 | } 79 | 80 | render() { 81 | this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); 82 | 83 | this.ctx.save(); 84 | this.ctx.scale(GU / 2 * 8, GU / 2 * 8); 85 | this.ctx.translate(1, 1); 86 | 87 | this.ctx.fillStyle = 'rgb(25, 25, 25)'; 88 | this.ctx.fillRect(-1, -1, 2, 2); 89 | 90 | const amount = smoothstep(0, 1, (this.frame - FRAME_FOR_BEAN(1824)) / ( 91 | FRAME_FOR_BEAN(1824 + 48) - FRAME_FOR_BEAN(1824))); 92 | this.drawTriangle(0, 0, amount); 93 | var offset = easeOut(0, 0.35, (this.frame - FRAME_FOR_BEAN(1848 + 48)) / ( 94 | FRAME_FOR_BEAN(1848 + 48 + 6) - FRAME_FOR_BEAN(1848 + 48))); 95 | this.drawTriangle(0, offset, amount); 96 | offset = easeOut(0, 0.35, (this.frame - FRAME_FOR_BEAN(1848 + 48 + 48)) / ( 97 | FRAME_FOR_BEAN(1848 + 48 + 48 + 6) - FRAME_FOR_BEAN(1848 + 48 + 48))); 98 | this.drawTriangle(0, offset/2, amount); 99 | 100 | this.ctx.restore(); 101 | this.output.needsUpdate = true; 102 | this.outputs.render.setValue(this.output); 103 | } 104 | } 105 | 106 | global.trianglebg = trianglebg; 107 | })(this); 108 | --------------------------------------------------------------------------------