diff --git a/201410_-_Sine_City/README b/201410_-_Sine_City/README new file mode 100644 index 0000000..6c111eb --- /dev/null +++ b/201410_-_Sine_City/README @@ -0,0 +1,11 @@ +Source code for "Sine City" +A JavaScript 8K intro + +On Pouet: http://www.pouet.net/prod.php?which=64233 + +Notes: + * It is likely not to work on your end. + * Tested on Linux using Chromium and Firefox with a NVidia GPU + * Known to work on some Windows boxes w/ native GL enabled + * The "original" version is not the code that was shown at DemoJS, + I adjusted quite a few things in the final, packed version. diff --git a/201410_-_Sine_City/custom-jsexe-bootstrap b/201410_-_Sine_City/custom-jsexe-bootstrap new file mode 100644 index 0000000..ea3c9f2 --- /dev/null +++ b/201410_-_Sine_City/custom-jsexe-bootstrap @@ -0,0 +1,2 @@ +// in case I need it again +C=V.getContext('2d');for(C.drawImage(this,0,_='');$--;(A=C.getImageData($%X,$/X,1,1).data[0])&&(_+=String.fromCharCode(A)));(1,eval)(_) diff --git a/201410_-_Sine_City/music.js b/201410_-_Sine_City/music.js new file mode 100644 index 0000000..f51b6e7 --- /dev/null +++ b/201410_-_Sine_City/music.js @@ -0,0 +1,159 @@ +var song = { + songData: [ + { + i: [ 0, 198, 128, 0, 3, 192, 128, 1, 0, 0, 96, 128, 28, 0, 0, 0, 0, 2, 63, 61, 13, 16, 44, 8, 0, 0 ], + + p: [1,2,3,4,5,2,3,4,6,7,1,2,3,4,5,2,3,4,5,2,3,4,1,2,3,8,9], + + c: [ + {n: [115,,,,,,,,,,,,117,,,,,,,,,,,,113], + f: [12,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,96]}, + {n: [115,,,,,,,,,,,,,,,110], + f: [12,,,,,,,,,,,,,,,12,,,,,,,,,,,,,,,,,,,,,115,,,,,,,,,,,,,,,148]}, + {n: [115,,,,,,,,,,,,117,,,,,,,,,,,,118], + f: [12,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,96]}, + {n: [122,,,,,,,,,,,,,,,123,,,,,115], + f: [12,,,,,,,,,,,,,,,12,,,,,12,,,,,,,,,,,,,,,,115,,,,,,,,,,,,,,,8,,,,,128]}, + {n: [118,,,,,,,,,,,,117,,,,,,,,,,,,113], + f: [12,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,96]}, + {n: [115], + f: [12,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,255]}, + {n: [,,,,,,,,,,,,,,,,118,118,118], + f: [,,,,,,,,,,,,,,,,12,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,128]}, + {n: [122,,,,,,,,,,,,,,,123,,,,,115], + f: [12,,,,,,,,,,,,,,,12,,,,,13,12,,,,,,,,,,,,,,,115,,,,,,,,,,,,,,,8,,,,,95,61]}, + {n: [], + f: []} + ] + }, + { + i: [ 0, 255, 116, 1, 0, 255, 101, 0, 0, 15, 1, 4, 45, 0, 13, 6, 1, 2, 62, 27, 60, 48, 0, 0, 44, 2 ], + + p: [,1,,2,,1,,2,,3,4,4,5,4,5,4,5,4,5,4,5,4,5,4,3,6], + + c: [ + {n: [,,,,,139,,,139,139,,,,,,139,,,,,,,,139,,,139,139,,,,,139,139,139], + f: []}, + {n: [,,139,139,,,,,139,139,,,,,139,139,,,,,,,,,,139,139,139,,,,,139,139,139], + f: []}, + {n: [,,,139,,,,,139,139,,,,,,139,,,,,139,139,,,,,,139,,,,139,139,139], + f: []}, + {n: [139,,,,139,,139,,,139,,,139,,,,139,,139,,,139,,,139,,,,139,,139,,,139], + f: []}, + {n: [139,,,139,139,,139,,,139,,,139,,,139,139,,139,,,139,,,139,,,139,139,,139,,,139], + f: []}, + {n: [139,,,139,139,,139,,,139,,,139,,,139,139,,139,,,139,139], + f: []} + ] + }, + { + i: [ 0, 0, 140, 0, 0, 0, 140, 0, 0, 128, 4, 10, 34, 0, 187, 5, 0, 1, 239, 135, 34, 19, 108, 8, 8, 4 ], + + p: [,,1,,1,,3,,1,3,2,2,2,2,2,3,2,3,2,3,2,3,2,3,1], + + c: [ + {n: [,,,,,,,,,,127,,,,,,,,,,,,127,,,,,,,,,,,,127], + f: []}, + {n: [,,,139,,,,,,139,139,,,,,139,,,,,,139,139,,,,,139,,,,,139,,139], + f: []}, + {n: [,,127,,,,,,,,127,,,,127,,,,,,,,127,,,,127,,,,,,,,127], + f: []} + ] + }, + { + i: [ 1, 192, 128, 0, 3, 201, 128, 0, 0, 93, 5, 6, 58, 3, 195, 6, 1, 3, 35, 63, 14, 17, 11, 10, 61, 6 ], + + p: [,,,,1,2,3,4,5,6,7,5,8,9,10,11,8,9,10,11,12,13,14,15,16], + + c: [ + {n: [,,,,,,,,147,146,145,,,,,,,,,,145,147,146,,,,,,,,,,149,148,147], + f: []}, + {n: [,,,,,,151,151,151,,,,,,,146,142,138,,,,,,,,,,,,,,,147,150,147], + f: []}, + {n: [,,146,,,146,,,,,,,,,147,146,145,,,,,,,,,,146,145,142,,,142,,,142], + f: []}, + {n: [,,141,,,,,,,,,,,,141,140,139,,,146,,,146,,,127], + f: []}, + {n: [,139,,151,,,,,,,,,,151,,139,,,,,,,,,,139,,151], + f: []}, + {n: [,139,,151,150,149,,,,,,,,139,,149,148,147,,,,,,,,139,,,146,,,145,,,144], + f: []}, + {n: [,139,,,139,142,,,142,144,146,,144,,,,146,147,,,147,146,141,,137,,,,142,141,,141,,137], + f: []}, + {n: [139,,127,,142,,,130,,,144,142,141,,129,,141,,,144,,,141,144,142,,,,149,,,146,,,151], + f: []}, + {n: [,149,,149,,146,144,142,,,141,,142,,,139,,,,151,147,,,,146,147,,144,146,,142,144,141,146], + f: []}, + {n: [,,,,,,,,147,146,145,,,,,141,144,147,146,,144,,137,,,144,146,142,144,,,142,144,141,146], + f: []}, + {n: [,146,,151,,146,,,,144,142,144,146,,,,142,,,,,139,,,,,151,146,139,144,139,142,141,142,151], + f: []}, + {n: [,,147,,,149,146,,,142,,142,141,,,144,,144,,,144,146,142,144,142,,,,151,150,149,,137,,149], + f: []}, + {n: [,151,,,147,151,,,146,151,,,,,144,151,,149,147,149,151,,146,,,144,143,142,,,139,,151,139], + f: []}, + {n: [,,134,,,134,,,134,,,146,144,,,141,144,,,146,147,146,,,144,,139,140,141,,,153,,,141], + f: []}, + {n: [,142,,151,,,142,143,144,,,,151,,,139,,,137,,149,,137,,,,125,,,141,142,141,,,146], + f: []}, + {n: [139,,127,139,,127,139,,127,139,127], + f: []} + ] + }, + { + i: [ 2, 160, 128, 1, 0, 160, 128, 0, 1, 60, 4, 7, 41, 0, 60, 4, 1, 3, 14, 0, 35, 32, 31, 12, 89, 1 ], + + p: [,,,,,,,,,,,,1,2,1,2,1,2,1,2,1,2,1,2,1,3], + + c: [ + {n: [,,139,,,,,,,,,,,,139,,,,,,,,,,,,139,,,,,139,139,,,139], + f: []}, + {n: [,,139,,,151,,,139,,,151,,,139,,,151,,,139,,,151,,,139,,,151,,,146,146,146,146], + f: []}, + {n: [,,139,,,151,,,139,,,151,,,139,,139,139,139,139,127], + f: []} + ] + }, + { + i: [ 2, 100, 128, 0, 3, 201, 128, 0, 0, 0, 0, 6, 29, 0, 195, 6, 1, 3, 28, 229, 119, 77, 147, 6, 61, 2 ], + + p: [,,,,,,,,,6,1,2,3,4,5,2,3,4,1,2,3,4,1,2,3,7], + + c: [ + {n: [115,115,115,115,115,115,115,115,115,115,115,115,117,117,117,117,117,117,117,117,117,117,117,117,113,113,113,113,113,113,113,113,113,113,113,113], + f: []}, + {n: [115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110], + f: []}, + {n: [115,115,115,115,115,115,115,115,115,115,115,115,117,117,117,117,117,117,117,117,117,117,117,117,118,118,118,118,118,118,118,118,118,118,118,118], + f: []}, + {n: [110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,111,111,111,111,111,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115], + f: []}, + {n: [118,118,118,118,118,118,118,118,118,118,118,118,117,117,117,117,117,117,117,117,117,117,117,117,113,113,113,113,113,113,113,113,113,113,113,113], + f: []}, + {n: [,,,,,,,,,,,,,,,,,,130,,130,,130,,130,,130,,130,118,130,118,130,118,130,118], + f: [,,,,,,,,,,,,,,,,,,26,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2]}, + {n: [110,122,,122,134,,110,122,,122,134,,110,122,,111,123,,111,123,115,127,139,127,115], + f: [,,,,,,,,,,,,,,,,,,,,26,25,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,8,147]} + ] + }, + { + i: [ 2, 100, 128, 0, 3, 201, 128, 0, 0, 0, 5, 6, 58, 0, 195, 6, 1, 2, 135, 0, 0, 32, 147, 6, 121, 6 ], + + p: [], + + c: [ + ] + }, + { + i: [ 2, 100, 128, 0, 3, 201, 128, 0, 0, 0, 5, 6, 58, 0, 195, 6, 1, 2, 135, 0, 0, 32, 147, 6, 121, 6 ], + + p: [], + + c: [ + ] + } + ], + rowLen: 5513, + patternLen: 36, + endPattern: 28 +}; diff --git a/201410_-_Sine_City/music.ogg b/201410_-_Sine_City/music.ogg new file mode 100644 index 0000000..0f4291e Binary files /dev/null and b/201410_-_Sine_City/music.ogg differ diff --git a/201410_-_Sine_City/player-small.js b/201410_-_Sine_City/player-small.js new file mode 100644 index 0000000..22c48d8 --- /dev/null +++ b/201410_-_Sine_City/player-small.js @@ -0,0 +1,336 @@ +/* -*- mode: javascript; tab-width: 4; indent-tabs-mode: nil; -*- +* +* Copyright (c) 2011-2013 Marcus Geelnard +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* +* 3. This notice may not be removed or altered from any source +* distribution. +* +*/ + +"use strict"; + +var CPlayer = function() { + + //-------------------------------------------------------------------------- + // Private methods + //-------------------------------------------------------------------------- + + // Oscillators + var osc_sin = function (value) { + return Math.sin(value * 6.283184); + }; + + var osc_saw = function (value) { + return 2 * (value % 1) - 1; + }; + + var osc_square = function (value) { + return (value % 1) < 0.5 ? 1 : -1; + }; + + var osc_tri = function (value) { + var v2 = (value % 1) * 4; + if(v2 < 2) return v2 - 1; + return 3 - v2; + }; + + var getnotefreq = function (n) { + // 174.61.. / 44100 = 0.003959503758 (F3) + return 0.003959503758 * Math.pow(2, (n - 128) / 12); + }; + + var createNote = function (instr, n) { + var osc1 = mOscillators[instr.i[0]], + o1vol = instr.i[1], + o1xenv = instr.i[3], + osc2 = mOscillators[instr.i[4]], + o2vol = instr.i[5], + o2xenv = instr.i[8], + noiseVol = instr.i[9], + attack = instr.i[10] * instr.i[10] * 4, + sustain = instr.i[11] * instr.i[11] * 4, + release = instr.i[12] * instr.i[12] * 4, + releaseInv = 1 / release; + + var noteBuf = new Int32Array(attack + sustain + release); + + // Calculate note frequencies for the oscillators + var o1t = getnotefreq(n + instr.i[2] - 128); + var o2t = getnotefreq(n + instr.i[6] - 128) * (1 + 0.0008 * instr.i[7]); + + // Re-trig oscillators + var c1 = 0, c2 = 0; + + // Local variables. + var j, e, t, rsample; + + // Generate one note (attack + sustain + release) + for (j = 0; j < attack + sustain + release; j++) { + // Envelope + e = 1; + if (j < attack) { + e = j / attack; + } else if (j >= attack + sustain) { + e -= (j - attack - sustain) * releaseInv; + } + + // Oscillator 1 + t = o1t; + if (o1xenv) { + t *= e * e; + } + c1 += t; + rsample = osc1(c1) * o1vol; + + // Oscillator 2 + t = o2t; + if (o2xenv) { + t *= e * e; + } + c2 += t; + rsample += osc2(c2) * o2vol; + + // Noise oscillator + if (noiseVol) { + rsample += (2 * Math.random() - 1) * noiseVol; + } + + // Add to (mono) channel buffer + noteBuf[j] = (80 * rsample * e) | 0; + } + + return noteBuf; + }; + + + //-------------------------------------------------------------------------- + // Private members + //-------------------------------------------------------------------------- + + // Array of oscillator functions + var mOscillators = [ + osc_sin, + osc_square, + osc_saw, + osc_tri + ]; + + // Private variables set up by init() + var mSong, mLastRow, mCurrentCol, mNumWords, mMixBuf; + + + //-------------------------------------------------------------------------- + // Initialization + //-------------------------------------------------------------------------- + + this.init = function (song) { + // Define the song + mSong = song; + + // Init iteration state variables + mLastRow = song.endPattern - 2; + mCurrentCol = 0; + + // Prepare song info + mNumWords = song.rowLen * song.patternLen * (mLastRow + 1) * 2; + + // Create work buffer (initially cleared) + mMixBuf = new Int32Array(mNumWords); + }; + + + //-------------------------------------------------------------------------- + // Public methods + //-------------------------------------------------------------------------- + + // Generate audio data for a single track + this.generate = function () { + // Local variables + var i, j, b, p, row, col, n, cp, + k, t, lfor, e, x, rsample, rowStartSample, f, da; + + // Put performance critical items in local variables + var chnBuf = new Int32Array(mNumWords), + instr = mSong.songData[mCurrentCol], + rowLen = mSong.rowLen, + patternLen = mSong.patternLen; + + // Clear effect state + var low = 0, band = 0, high; + var lsample, filterActive = false; + + // Clear note cache. + var noteCache = []; + + // Patterns + for (p = 0; p <= mLastRow; ++p) { + cp = instr.p[p]; + + // Pattern rows + for (row = 0; row < patternLen; ++row) { + // Execute effect command. + var cmdNo = cp ? instr.c[cp - 1].f[row] : 0; + if (cmdNo) { + instr.i[cmdNo - 1] = instr.c[cp - 1].f[row + patternLen] || 0; + + // Clear the note cache since the instrument has changed. + if (cmdNo < 14) { + noteCache = []; + } + } + + // Put performance critical instrument properties in local variables + var oscLFO = mOscillators[instr.i[13]], + lfoAmt = instr.i[14] / 512, + lfoFreq = Math.pow(2, instr.i[15] - 9) / rowLen, + fxLFO = instr.i[16], + fxFilter = instr.i[17], + fxFreq = instr.i[18] * 43.23529 * 3.141592 / 44100, + q = 1 - instr.i[19] / 255, + dist = instr.i[20] * 1e-5, + drive = instr.i[21] / 32, + panAmt = instr.i[22] / 512, + panFreq = 6.283184 * Math.pow(2, instr.i[23] - 9) / rowLen, + dlyAmt = instr.i[24] / 255, + dly = instr.i[25] * rowLen; + + // Calculate start sample number for this row in the pattern + rowStartSample = (p * patternLen + row) * rowLen; + + // Generate notes for this pattern row + for (col = 0; col < 4; ++col) { + n = cp ? instr.c[cp - 1].n[row + col * patternLen] : 0; + if (n) { + if (!noteCache[n]) { + noteCache[n] = createNote(instr, n); + } + + // Copy note from the note cache + var noteBuf = noteCache[n]; + for (j = 0, i = rowStartSample * 2; j < noteBuf.length; j++, i += 2) { + chnBuf[i] += noteBuf[j]; + } + } + } + + // Perform effects for this pattern row + for (j = 0; j < rowLen; j++) { + // Dry mono-sample + k = (rowStartSample + j) * 2; + rsample = chnBuf[k]; + + // We only do effects if we have some sound input + if (rsample || filterActive) { + // State variable filter + f = fxFreq; + if (fxLFO) { + f *= oscLFO(lfoFreq * k) * lfoAmt + 0.5; + } + f = 1.5 * Math.sin(f); + low += f * band; + high = q * (rsample - band) - low; + band += f * high; + rsample = fxFilter == 3 ? band : fxFilter == 1 ? high : low; + + // Distortion + if (dist) { + rsample *= dist; + rsample = rsample < 1 ? rsample > -1 ? osc_sin(rsample*.25) : -1 : 1; + rsample /= dist; + } + + // Drive + rsample *= drive; + + // Is the filter active (i.e. still audiable)? + filterActive = rsample * rsample > 1e-5; + + // Panning + t = Math.sin(panFreq * k) * panAmt + 0.5; + lsample = rsample * (1 - t); + rsample *= t; + } else { + lsample = 0; + } + + // Delay is always done, since it does not need sound input + if (k >= dly) { + // Left channel = left + right[-p] * t + lsample += chnBuf[k-dly+1] * dlyAmt; + + // Right channel = right + left[-p] * t + rsample += chnBuf[k-dly] * dlyAmt; + } + + // Store in stereo channel buffer (needed for the delay effect) + chnBuf[k] = lsample | 0; + chnBuf[k+1] = rsample | 0; + + // ...and add to stereo mix buffer + mMixBuf[k] += lsample | 0; + mMixBuf[k+1] += rsample | 0; + } + } + } + + // Next iteration. Return progress (1.0 == done!). + mCurrentCol++; + return mCurrentCol / 8; + }; + + // Create a WAVE formatted Uint8Array from the generated audio data + this.createWave = function() { + // Create WAVE header + var l1 = mNumWords * 2 - 8; + var l2 = l1 - 36; + var headerLen = 44; + var wave = new Uint8Array(headerLen + mNumWords * 2); + wave.set( + [82,73,70,70, + l1 & 255,(l1 >> 8) & 255,(l1 >> 16) & 255,(l1 >> 24) & 255, + 87,65,86,69,102,109,116,32,16,0,0,0,1,0,2,0, + 68,172,0,0,16,177,2,0,4,0,16,0,100,97,116,97, + l2 & 255,(l2 >> 8) & 255,(l2 >> 16) & 255,(l2 >> 24) & 255] + ); + + // Append actual wave data + for (var i = 0, idx = headerLen; i < mNumWords; ++i) { + // Note: We clamp here + var y = mMixBuf[i]; + y = y < -32767 ? -32767 : (y > 32767 ? 32767 : y); + wave[idx++] = y & 255; + wave[idx++] = (y >> 8) & 255; + } + + // Return the WAVE formatted typed array + return wave; + }; + + // Get n samples of wave data at time t [s]. Wave data in range [-2,2]. + this.getData = function(t, n) { + var i = 2 * Math.floor(t * 44100); + var d = new Array(n); + for (var j = 0; j < 2*n; j += 1) { + var k = i + j; + d[j] = t > 0 && k < mMixBuf.length ? mMixBuf[k] / 32768 : 0; + } + return d; + }; +}; + diff --git a/201410_-_Sine_City/sine-city-ori.html b/201410_-_Sine_City/sine-city-ori.html new file mode 100644 index 0000000..7b94824 --- /dev/null +++ b/201410_-_Sine_City/sine-city-ori.html @@ -0,0 +1,5 @@ +<body> +<script language="javascript" src="music.js"></script> +<script language="javascript" src="player-small.js"></script> +<script language="javascript" src="sine-city-ori.js"></script> + diff --git a/201410_-_Sine_City/sine-city-ori.js b/201410_-_Sine_City/sine-city-ori.js new file mode 100644 index 0000000..75c0928 --- /dev/null +++ b/201410_-_Sine_City/sine-city-ori.js @@ -0,0 +1,1665 @@ +var USE_SYNTH = 0; + +// Vector stuff +function vecOp(code) { + return eval('(function(o,a,b){for(var i=o.length;--i>=0;)' + code + ';return o})') +} +function vomNew(s) { + return new Float32Array(s) +} +var vecDot = function(a,b) { + var s = 0; + for ( var i in a ) { + s += a[i]*b[i]; + } + return s; +}; +var vecLen = function(a) { + return Math.sqrt( vecDot(a,a) ) +}; +var vecNorm = function(o,a) { + var l = vecLen(a); + return l ? vecScale(o,a,1/l) : vecCopy(o,a); +}; +var vecCross = function(o,a,b) { + return vecSet(o, + a[1]*b[2]-a[2]*b[1] , + a[2]*b[0]-a[0]*b[2] , + a[0]*b[1]-a[1]*b[0] + ); +}; +var vecs2Mat3 = function(o,a,b,c){ + for ( var i = 0 ; i < 3 ; i ++ ) { + o[i*3+0] = a[i]; + o[i*3+1] = b[i]; + o[i*3+2] = c[i]; + } +}; +var vecSet = vecOp('o[i]=arguments[i+1]') , + vecCopy = vecOp('o[i]=a[i]') , + vecAdd = vecOp('o[i]=a[i]+b[i]') , + vecSub = vecOp('o[i]=a[i]-b[i]') , + vecScale = vecOp('o[i]=a[i]*b'); + +var luma = [.299 , .587 , .114]; + + +// Shaders +var shaderBits = { + precision: 'precision highp float;' , + inPosition: 'attribute vec2 inPosition;' , + voTexCoords: 'varying vec2 voTexCoords;' , + raymarchVSMain: [ + "void main( )" , + "{" , + "gl_Position = vec4( inPosition , 0. , 1. );" , + "voTexCoords = inPosition;" , + "}" + ].join('') , + rmUtils: [ + "const vec3 LUMA = vec3( " , shaderVec(luma) , " );" , + + "struct Material" , + "{" , + "vec3 albedo;" , + "float metallic;" , + "float smoothness;" , + "float r0;" , + "};" , + + "float hash( float n )" , + "{" , + "return fract(sin(n)*43758.5453);" , + "}" , + + "float noise( vec3 x )" , + "{" , + "vec3 p = floor(x);" , + "vec3 f = fract(x);" , + + "f = f*f*(3.0-2.0*f);" , + "float n = p.x + p.y*57.0 + 113.0*p.z;" , + "return mix(mix(mix( hash(n+ 0.0), hash(n+ 1.0),f.x)," , + "mix( hash(n+ 57.0), hash(n+ 58.0),f.x),f.y)," , + " mix(mix( hash(n+113.0), hash(n+114.0),f.x)," , + "mix( hash(n+170.0), hash(n+171.0),f.x),f.y),f.z);" , + "}" , + + "float atan2( in float y , in float x )" , + "{" , + "return ( x == 0.0" , + "? ( y > 0.0 ? ( 3.14159 * .5 ) : ( -3.14159 * .5 ) )" , + ": atan( y , x ) );", + "}" , + + "vec2 solve(float a, float b, float c)" , + "{" , + "float d = b * b - 4. * a * c;" , + "if ( d < 0. ) {" , + "return vec2(-1.);" , + "}" , + "d=sqrt(d);" , + "vec2 s = -.5*vec2(b+d,b-d)/a;" , + "return vec2(min(s.x,s.y),max(s.x,s.y));" , + "}" , + + "float lx( vec2 v , float x )" , + "{" , + "vec2 s = pow(abs(v),vec2(x));" , + "return pow( s.x + s.y , 1. / x );" , + "}" , + + "mat2 rot( float angle )" , + "{" , + "vec2 cs = vec2( cos(angle),sin(angle));" , + "return mat2( -cs.x,cs.y,cs.y,cs.x );" , + "}" , + + "float schlick( vec3 hv , vec3 cd , float r0, float smooth )" , + "{" , + "float d = clamp((1. - dot( hv, -cd )), 0., 1.) , d2 = d * d;" , + "return r0 + (1. - r0) * d * d2 * d2 * smooth;" , + "}" , + + "float getSpecular(vec3 i, vec3 l, vec3 n, float smooth)" , + "{ " , + "float rDotL = max(dot(reflect(i, n), l), 0.0);" , + "float sp = exp2(4.0 + 6.0 * smooth);" , + "float si = (sp + 2.0) * 0.125;" , + "return pow(rDotL, sp) * si;" , + "}" , + + ].join('\n'), + beadCyl: [ + "float beadCyl( vec3 p )" , + "{" , + "vec2 q = mod( p.xy , vec2(15.) ) - vec2(7.5);" , + "return length(q) - .5 + .05 * sin(p.z*9.42477);" , + "}" + ].join('\n'), +}; + +var shaders = { + raymarchVS: [ 'v' , + 'inPosition' , 'voTexCoords' , 'raymarchVSMain' ] , +}; +var programs = { +}; + +function shaderFloat( v ) { + return '' + v + ( v == Math.floor(v) ? '.' : '' ); +} +function shaderVec( v ) { + return v.map(shaderFloat).join(','); +} + +function compileShader( def ) { + var type = def[0] == 'f' ? glCtx.FRAGMENT_SHADER : glCtx.VERTEX_SHADER; + var src = ''; + for ( var i = 1 ; i < def.length ; i ++ ) { + src += shaderBits[ def[ i ] ]; + } + + var shader = glCtx.createShader( type ); + glCtx.shaderSource( shader , src ); + glCtx.compileShader( shader ); + if (!glCtx.getShaderParameter(shader, glCtx.COMPILE_STATUS)) { + src = src.split( /\n/ ); + for ( var i in src ) { + var j = parseInt(i)+1; + src[i] = j + ": " + src[i]; + } + throw "SHADER ERROR\n" + glCtx.getShaderInfoLog(shader) + "\n" + src.join('\n'); + } + + + return shader; +} + +function compileShaders( ) { + for ( var name in shaders ) { + shaders[name] = compileShader( shaders[name] ); + } +} + +function buildProgram( name ) { + var p = glCtx.createProgram( ); + var d = programs[name]; + var ul = d.shift(); + while( d.length ) { + glCtx.attachShader( p , shaders[ d.shift() ] ); + } + glCtx.bindAttribLocation( p , 0 , "inPosition" ); + glCtx.linkProgram( p ); + var nul = {}; + while ( ul.length ) { + d = ul.shift(); + nul[d] = glCtx.getUniformLocation( p , 'u' + d ); + } + programs[name] = [p,nul]; +} + +function buildPrograms( ) { + compileShaders( ); + for ( var name in programs ) { + buildProgram(name); + } +} + + +// Raymarchers + +var materials = [ + { + albedo: [.05,.05,.05] , + metallic: .7 , + smoothness: .02 , + r0: .01 + } , { + albedo: [ .2,.2,.2 ] , + noise: [ .1,.1,.1] , + noiseScale: 5 , + metallic: .7 , + smoothness: .9 , + r0: .01 + } , { + albedo: [ 1,1,1 ] , + metallic: .5 , + smoothness: .4 , + r0: .02 + } , { + albedo: [ 3,0,0 ] , + noise: [.6,0,0], + noiseScale: 6 , + metallic: .3 , + smoothness: .1 , + r0: .6 + } , { + albedo: [ 0,2,0 ] , + noise: [0,.2,0], + noiseScale: 15 , + metallic: .9 , + smoothness: .5 , + r0: .4 + } , { + albedo: [ 3,1.5,0 ] , + noise: [.3,.6,0], + noiseScale: .3 , + metallic: .95 , + smoothness: .6 , + r0: .9 + } , { + albedo: [ .1,.1,.1 ] , + noise: [3,3,3] , + noiseScale: 3, + metallic: 0 , + smoothness: .04 , + r0: .002 + } , { + albedo: [ 0,1.5,2 ] , + metallic: .9 , + smoothness: .3 , + r0: .4 + } +]; + + +var raymarchers = { + tunnel: { + extraUniforms: {BallOffset:'float'} , + extraBits: [] , + + maxDistance: 100 , + epsilon: .025 , + epsilonMultiplier: 1 , + step: .7 , + depth: 64 , + + normalDelta: .0005 , + noiseScale: .5 , + reflectionDistance: .3 , + + fog: .4 , + fogDensity: .015 , + + aoSteps: 4 , + aoDelta: 2 , + aoWeight: .75 , + + materials: [0,1,2,3] , + + setCamera: function( ctx ) { + var z = ctx.time*30; + vecSet(ctx.camPos,0,0,z); + z += 5; + vecSet(ctx.lookAt,-Math.sin(z*.05),-.7*Math.cos(z*.033),z); + vecSet(ctx.up,0,1,0); + ctx.toNearPlane = 2; + } , + map: [ + "vec3 q = p + .1 * ( sin(p.zxy*.17+uTime*.5)+sin(p.yzx*.7+uTime*1.5) )*8.5*(1. + cos(sin(p.z * .1 ) + p.z * .3 ));" , + "float b = 14. - length( q.xy )," , + "ap = atan2(p.y,p.x),c,m,n=8.35-uBallOffset*1.35;" , + "q = vec3( 9.*(mod(ap+p.z*.02,.628)-.314) , length(p.xy)-9. , mod(p.z,12.56)-6.28);" , + "c = length(q.xy)-.25+.1*cos(p.z*8.+uTime*.1);" , + "c = min(c,length(q.yz)-.5);", + "q = vec3(n*(mod(ap+p.z*.02,1.256636)-.628318),q.y+9.-n,mod(p.z,62.8318)-31.4159);" , + "m = step(c,b)+1.;" , + "b=min(c,b);" , + "c=length(q) - 1.3;" , + "if(c<b){b=c;m=3.;}" , + "q.y+=n-9.;" , + "c = lx(q.yz,8.)-2.;" , + "if(c<b){b=c;m=0.;}" , + "return vec2(b,m);" + ].join('\n') , + lights: [ + { + attenuation: .25 , + vRadius: 0 , + update: function(ctx,lctx) { + vecSet(lctx.pos , 0 , -.5 , ctx.time*30-.5); + vecSet(lctx.colour,3,3,3); + lctx.distance = 30; + return true; + } + } , { + attenuation: .5 , + vRadius: .5 , + update: function(ctx,lctx) { + vecSet(lctx.pos , 4*Math.sin(ctx.time*.5)*Math.cos(ctx.time*.7) , + 3*Math.cos(ctx.time*1.5), + ctx.time*30+14+16*Math.sin(ctx.time*3.3)*Math.cos(ctx.time*.77) + ); + vecSet(lctx.colour,1,1,1); + lctx.distance = 15; + return true; + } + } + ] , + } , + fractals: { + extraUniforms: {BallSize:'float',TimeEffect:'float'} , + extraBits: [] , + + maxDistance: 6 , + epsilon: .00025 , + epsilonMultiplier: 1.08 , + step: .7 , + depth: 100 , + + normalDelta: .000008 , + noiseScale: 10 , + reflectionDistance: .03 , + + fog: 2.1 , + fogDensity: .2 , + + aoSteps: 6 , + aoDelta: .4 , + aoWeight: 5 , + + materials: [0,2,5] , + + setCamera: function( ctx ) { + var z = ctx.time*30; + vecSet(ctx.camPos,5*Math.sin(ctx.time*.1),10*Math.cos(ctx.time*.2),7.5); + vecSet(ctx.lookAt,0,0,ctx.camPos[2]-2); + vecSet(ctx.up,0,0,1); + ctx.toNearPlane = 3; + } , + map: [ + "const vec3 CSize=vec3(.58,.9,1.1);" , + "float scale=1.,k,m;" , + "vec3 fp=p;" , + "for(int i=0;i<7;i++){" , + "p=2.*clamp(p,-CSize,CSize)-p;" , + "k=max((1.3+uTimeEffect*.1*cos(uTime*.5))/dot(p,p),1.);" , + "p*=k;" , + "scale*=k;" , + "}" , + "k=length(p.xy);" , + "vec2 ds=vec2(k-3.,-k*p.z/length(p)-2.*log(1.+.01*d))/abs(scale);" , + "k=max(ds.x,ds.y);" , + "m=step(ds.y,ds.x);" , + // FIXME! + "vec3 ctr=uCamPos-vec3(.1,.3,-.4)*uCamMat;" , + "fp-=ctr;fp+=.25*sin(p*1.);" , + "ds.x = length(fp)-.1*uBallSize;" , + "if (ds.x < k ) { k = ds.x ; m = 2.; }" , + "return vec2(k,m);" + ].join('\n') , + lights: [ + { + attenuation: .05 , + update: function(ctx,lctx) { + vecCopy(lctx.pos,ctx.camPos); + lctx.pos[2]+=2; + vecSet(lctx.colour,1,1,1); + lctx.distance = 3; + return true; + } + } + ] , + } , + squares: { + extraUniforms: [] , + extraBits: ['beadCyl'] , + + maxDistance: 100 , + epsilon: .000025 , + epsilonMultiplier: 1 , + step: .75 , + depth: 80 , + + normalDelta: .00005 , + noiseScale: .5 , + reflectionDistance: .3 , + + fog: 3 , + fogDensity: .01 , + + aoSteps: 4 , + aoDelta: .75 , + aoWeight: 4.75 , + + materials: [6,0,4] , + + setCamera: function( ctx ) { + var z = ctx.time*30; + vecSet(ctx.camPos,Math.cos(ctx.time)*40.,0.,Math.sin(ctx.time*.5)*80.); + vecSet(ctx.lookAt,0,0,-100); + vecSet(ctx.up,0,1,0); + ctx.toNearPlane = 2.5; + } , + map: [ + "p.xy*=rot(d*.009 );" , + "vec3 q;" , + + "float y,m,x = beadCyl( p.xzy );" , + "x = min( x , beadCyl( p ) );" , + "x = min( x , beadCyl(p.yzx ) );" , + + "q = mod( p , vec3(15.) ) - vec3(7.5);" , + "y = max(length(max(abs(q) - vec3(2.5),vec3(0.))) - .25 , 3.5 - length(q) );" , + "m = step(y,x);" , + "x = min(x,y);" , + "y = length(q+.1*sin(q*5.5+uTime))-2.;" , + "if (y<x) {" , + "x = y;" , + "m=2.;" , + "}" , + "return vec2( x , m );" + ].join('\n') , + lights: [ + { + attenuation: .05 , + update: function(ctx,lctx) { + vecCopy(lctx.pos,ctx.camPos); + vecSet(lctx.colour,1,1,1); + lctx.distance = 30; + return true; + } + } + ] , + } , + balls: { + extraUniforms: {EffectTime:'float'} , + + maxDistance: 20 , + epsilon: .0005 , + epsilonMultiplier: 1.0 , + step: .6 , + depth: 128 , + + normalDelta: .0001 , + noiseScale: .5 , + reflectionDistance: .002 , + + fog: .01 , + fogDensity: .08 , + + aoSteps: 4 , + aoDelta: .5 , + aoWeight: 1.75 , + + materials: [2,7] , + + setCamera: function( ctx ) { + var z = ctx.time*30; + vecSet(ctx.camPos,Math.cos(ctx.time)*12,8,Math.sin(ctx.time)*12); + vecSet(ctx.lookAt,1,0,0); + vecSet(ctx.up,0,1,0); + ctx.toNearPlane = 2.5; + } , + + map: [ + "float t = uEffectTime;" , + "vec3 r = p;" , + "r.xz = mod(r.xz,8.)-4.;" , + "r.yz *= rot(t+.1*d);" , + "r.xy *= rot(t*.5+.2*d);" , + "r.y *= .9 + .1 * sin(t * 5.);" , + "float a = max( length(r)-3. , -min( length(r)-2.8 , " , + "max(mod(r.y,.8)-.4 , -mod(r.y+.4,.8)+.4)));" , + "float b = p.y+1.+sin(p.x*4.+t*2.)*sin(p.z+t)*.1;" , + "float h = clamp( .5+.5*(b-a)/1., .0, 1. );" , + "a = mix(b,a,h)-1.*h*(1.-h);" , + "r=p;" , + "r.xz = mod(r.xz,8.)-4.;" , + "r /= 1.25 + .25 * sin(t*5.);" , + "r.xy *= rot(t*5.);" , + "r.yz *= rot(t*2.5);" , + "b = max( length(r)-1. , .04-length(max(abs(mod(r,.5)-.25) - vec3(.15),vec3(0.))) );" , + "return vec2( min(a,b) , step(b,a) );" + ].join('\n') , + lights: [ + { + attenuation: .02 , + update: function(ctx,lctx) { + vecCopy(lctx.pos,ctx.camPos); + vecSet(lctx.colour,.6,.6,.6); + lctx.distance = 30; + return true; + } + },{ + attenuation: .05 , + vRadius: .5 , + update: function(ctx,lctx) { + vecSet(lctx.pos,Math.cos(ctx.time*2)*5,0,Math.sin(ctx.time*2)*5); + vecSet(lctx.colour,1,1,1); + lctx.distance = 4; + return true; + } + } , { + attenuation: .05 , + vRadius: .5 , + update: function(ctx,lctx) { + vecSet(lctx.pos,-Math.cos(ctx.time*2)*5,0,-Math.sin(ctx.time*2)*5); + vecSet(lctx.colour,1,1,1); + lctx.distance = 4; + return true; + } + } + ] , + } +}; + +var lightFunc = function(intensity,distance) { + return function(ctx,lctx) { + vecCopy(lctx.pos,ctx.camPos); + vecSet(lctx.colour,intensity,intensity,intensity); + lctx.distance = distance; + return true; + } +}; +var tun1CamCommon = function(ctx,dir) { + var z = ctx.time*6; + vecSet(ctx.camPos,-6,0,z); + vecSet(ctx.lookAt,1,0,z); + vecSet(ctx.up,0,1,0); + ctx.greyMix = 1; + ctx.extras[0] = '1f(p.BallOffset,0)'; + return ctx.stepTime / dir.time; +}; +var desyncFunc = function(desync) { + return function(ctx,tt) { + var z = ctx.stepTime / tt; + ctx.desync = -z * desync; + if ( desync > 0 ) { + ctx.desync += desync; + } + ctx.desync *= Math.random( ) * .25 + .75; + }; +}; +var balls1CamFunc = function(lax,laz,desync) { + var dsf = desyncFunc(desync); + return function(ctx) { + var z = ctx.time*3; + vecSet(ctx.camPos,0,4,z); + vecSet(ctx.lookAt,lax,0,z+laz); + vecSet(ctx.up,0,0,1); + ctx.fade = 0; + dsf(ctx,this.time); + }; +}; +var balls2CamCommon = function(ctx) { + var z = ctx.time*5; + vecSet(ctx.camPos,Math.cos(ctx.time)*12,8,Math.sin(ctx.time)*12+z); + vecSet(ctx.lookAt,1,0,z); + vecSet(ctx.up,0,1,0); + ctx.toNearPlane = 2.5; + z = ctx.time - direction[43].startTime; + ctx.extras[0] = '1f(p.EffectTime,'+z+')'; +}; +var balls2LightFunc = function(scale) { + return function(ctx,lctx) { + var z = ctx.time*30; + vecSet(lctx.pos,scale*Math.cos(ctx.time*2)*5,3,scale*Math.sin(ctx.time*2)*5+z); + vecSet(lctx.colour,1,1,1); + lctx.distance = 4; + return true; + }; +}; +var fract1CamCommon = function(ctx) { + var z = ctx.time; + vecSet(ctx.camPos,4,2.5+.025*z,6.7); + vecSet(ctx.lookAt,0,2.5-.05*z,6.7); + vecSet(ctx.up,0,0,1); + ctx.extras = [ '1f(p.BallSize,0)' , '1f(p.TimeEffect,0)' ]; + ctx.toNearPlane = 3; +}; +var fract1CamFunc = function(desync) { + var dsf = desyncFunc(desync); + return function(ctx){ + fract1CamCommon(ctx); + dsf(ctx,this.time); + }; +}; +var fract2CamCommon = function(ctx,bs) { + vecSet(ctx.camPos,5*Math.sin(ctx.time*.2),9*Math.cos(ctx.time*.41),7.8); + vecCopy(ctx.lookAt,ctx.camPos); + ctx.lookAt[0] = Math.cos(ctx.time*.2); + ctx.lookAt[1] = Math.sin(ctx.time*.33); + ctx.lookAt[2] -= 2; + vecSet(ctx.up,0,0,1); + ctx.toNearPlane = 3; + ctx.extras = [ '1f(p.BallSize,'+bs+')' , '1f(p.TimeEffect,1)' ]; +}; + +var drawText = function(str,x) { + twoDCtx.shadowBlur = c2height/5; + twoDCtx.fillText( str , x , c2height / 2 ); + twoDCtx.shadowBlur = 0; + twoDCtx.strokeText( str , x , c2height / 2 ); +}; +var titleText = function(str,shake,alpha,r,g,b) { + drawText( str , canvasWidth/15 ); + vecSet( context.text , 1 - c2rHeight + Math.random() * shake - shake * .5 , alpha , c2rHeight ); + vecSet( context.textColour , r , g , b ); +}; +var greetings = "Greetings to ... Mog, Sycop, Tim & Wullon ... Adinpsz ... Alcatraz ... ASD ... Bits'n'Bites ... Brain Control ... Cocoon ... Conspiracy ... Ctrl+Alt+Test ... Fairlight ... Farbrausch ... Kewlers ... LNX ... Loonies ... Mercury ... Popsy Team ... Razor 1911 ... RGBA ... 7th Cube ... Still ... TPOLM ... TRBL ... Umlaut Design ... X-Men ... Youth Uprising ... Everyone here at DemoJS 2014!"; +var greetingsText = function() { + var t = ( context.time - direction[34].startTime ) * canvasWidth * .5; + drawText( greetings , canvasWidth - t ); + vecSet( context.text , 1 - c2rHeight + Math.random() * .02 - .01 , 1 , c2rHeight ); + vecSet( context.textColour , 1 , 1 , 1 ); +}; + +var squaresCam = function(ctx) { + var t = ctx.time - direction[25].startTime; + var z = t*10 - 80; + vecSet(ctx.camPos,z,0,0); + vecSet(ctx.lookAt,z+Math.cos(t*.5) * 80,Math.sin(t*.25)*40,100); + vecSet(ctx.up,0,1,0); +}; + +var squaresCam2 = function(ctx,s) { + var t = ctx.time - direction[s].startTime; + var z = t*20 - 80; + vecSet(ctx.camPos,0,0,z); + vecSet(ctx.lookAt,Math.cos(t*.5) * 80,Math.sin(t*.25)*40,z+100); + vecSet(ctx.up,Math.sin(t),Math.cos(t),0); + ctx.desync = Math.random() * .025 - .0125; +}; + +var tunnelLight = function(ctx,lctx) { + vecAdd(lctx.pos,vecNorm(lctx.pos,vecScale(lctx.pos,ctx.lookAt,-1)),ctx.camPos); + lctx.pos[1] -= .5; + vecSet(lctx.colour,3,3,3); + lctx.distance = 30; + return true; +}; +var tunnelCam = function(ctx,mul) { + var z = ctx.time*30*ctx.tunMul; + vecSet(ctx.camPos,1.1*Math.cos(z*.1),Math.sin(z*.02),z); + z += 5; + vecSet(ctx.lookAt,-Math.sin(z*.05),-.7*Math.cos(z*.033),z); + vecSet(ctx.up,0,1,0); + ctx.toNearPlane = 2; +}; +var tunnelLightBall = function(ctx,lctx) { + vecSet(lctx.pos , 4*Math.sin(ctx.time*.5)*Math.cos(ctx.time*.7) , + 3*Math.cos(ctx.time*1.5), + ctx.time*30*ctx.tunMul+14+16*Math.sin(ctx.time*3.3)*Math.cos(ctx.time*.77) + ); + vecSet(lctx.colour,1,1,1); + lctx.distance = 15; + return true; +}; + +var direction = [ + { + // Music rows + rows: 36 , + // Raymarcher id + rm: 'tunnel' , + setGlobals: function( ctx ) { + var z = tun1CamCommon(ctx,this); + z *= z*z; + ctx.fade = 1 - z; + ctx.toNearPlane = 5; + } , + lights: [ + lightFunc(3,20) + ] , + updateText: null + } , { + rows: 18 , + rm: 'tunnel' , + setGlobals: function( ctx ) { + var z = tun1CamCommon(ctx,this); + ctx.toNearPlane = 5 - 2.25 * z; + ctx.fade = 0; + } , + lights: [ + lightFunc(3,20) + ] , + updateText: null + } , { + rows: 36 , + rm: 'tunnel' , + setGlobals: function( ctx ) { + var z = tun1CamCommon(ctx,this); + ctx.toNearPlane = 2.75 - 2.25 * z; + ctx.fade = z; + } , + lights: [ + lightFunc(3,20) + ] , + updateText: null + } , { + rows: 18 , + rm: 'balls' , + setGlobals: function( ctx ) { + var z = ctx.time*3; + vecSet(ctx.camPos,0,4,z); + vecSet(ctx.lookAt,4,0,z); + vecSet(ctx.up,0,0,1); + z = ctx.stepTime / this.time; + z *= z*z; + ctx.fade = 1 - z; + ctx.toNearPlane = 2.5; + } , + lights: [ + lightFunc(.75,8) + ] , + updateText: null + } , { + rows: 22 , + rm: 'balls' , + setGlobals: balls1CamFunc(4,0,0) , + lights: [ + lightFunc(1,8) + ] , + updateText: null + } , { + rows: 22 , + rm: 'balls' , + setGlobals: balls1CamFunc(2,-2,0) , + lights: [ + lightFunc(1,8) + ] , + updateText: null + } , { + rows: 3 , + rm: 'balls' , + setGlobals: balls1CamFunc( 6 , 0 , -.5 ) , + lights: [ + lightFunc(.5,4) + ] , + updateText: null + } , { + rows: 9 , + rm: 'balls' , + setGlobals: balls1CamFunc( 6 , 0 , .5 ) , + lights: [ + lightFunc(.5,4) + ] , + updateText: null + } , { + rows: 3 , + rm: 'balls' , + setGlobals: balls1CamFunc( 2 , 2 , -.2 ) , + lights: [ + lightFunc(1,8) + ] , + updateText: null + } , { + rows: 9 , + rm: 'balls' , + setGlobals: balls1CamFunc( 2 , 2 , .2 ) , + lights: [ + lightFunc(1,8) + ] , + updateText: null + } , { + rows: 3 , + rm: 'balls' , + setGlobals: balls1CamFunc( 2 , 5 , -.7 ) , + lights: [ + lightFunc(1,2) + ] , + updateText: null + } , { + rows: 7 , + rm: 'balls' , + setGlobals: balls1CamFunc( 2 , 2 , .7 ) , + lights: [ + lightFunc(1,2) + ] , + updateText: null + } , { + rows: 9 , + rm: 'balls' , + setGlobals: function(ctx) { + var z = ctx.time*3; + ctx.fade = ctx.stepTime / this.time; + vecSet(ctx.camPos,0,4+ctx.fade*2,z); + vecSet(ctx.lookAt,2,0,z+2); + vecSet(ctx.up,0,0,1); + ctx.fadeColour = 1; + } , + lights: [ + lightFunc(1,2) + ] , + updateText: null + } , { + rows: 21 , + rm: 'fractals' , + setGlobals: function( ctx ) { + fract1CamCommon(ctx); + ctx.fadeColour = 1; + var z = ctx.stepTime / this.time; + ctx.fade = 1 - z*z*z; + } , lights : [ + fractLight = function(ctx,lctx) { + vecCopy(lctx.pos,ctx.camPos); + lctx.pos[2]+=2; + vecSet(lctx.colour,1,1,1); + lctx.distance = 3; + return true; + } + ], + updateText: null + } , { + rows: 14 , + rm: 'fractals' , + setGlobals: fract1CamFunc(0) , + lights : [ + fractLight + ], + updateText: null + } , { + rows: 3 , + rm: 'fractals' , + setGlobals: fract1CamFunc(-.4) , + lights : [ fractLight ], + updateText: null + } , { + rows: 9 , + rm: 'fractals' , + setGlobals: fract1CamFunc(.4) , + lights : [ fractLight ], + updateText: null + } , { + rows: 3 , + rm: 'fractals' , + setGlobals: fract1CamFunc(-.2) , + lights : [ fractLight ], + updateText: null + } , { + rows: 9 , + rm: 'fractals' , + setGlobals: fract1CamFunc(.2) , + lights : [ fractLight ], + updateText: null + } , { + rows: 12 , + rm: 'fractals' , + setGlobals: function(ctx) { + fract1CamCommon(ctx); + ctx.desync = -( 6 * ctx.stepTime / this.time ) % 1; + ctx.desync *= Math.random( ) * .25 + .75; + } , + lights : [ fractLight ], + updateText: null + } , { + rows: 22 , + rm: 'fractals' , + setGlobals: function(ctx) { + fract1CamCommon(ctx); + ctx.fadeColour = .4; + ctx.fade = ctx.stepTime / this.time; + ctx.toNearPlane = 3 - 2.5*Math.max(1,2*ctx.fade); + ctx.desync = ( 30 * ctx.fade ) % 1; + ctx.desync *= Math.random( ) * .15 + .85; + } , + lights : [ fractLight ], + updateText: null + } , { + rows: 3 , + rm: 'fractals' , + setGlobals: neutral = function(ctx) { + fract1CamCommon(ctx); + ctx.fadeColour = .4; + ctx.fade = 1; + ctx.desync = 0; + } , + lights : [ fractLight ], + updateText: null + } , { + rows: 12 , + rm: 'fractals' , + setGlobals: neutral , + lights : [ fractLight ], + updateText: function() { + titleText( "TheT(ourist)" , .08 , 1 , 1 , 1 , 1 ); + } + } , { + rows: 12 , + rm: 'fractals' , + setGlobals: neutral , + lights : [ fractLight ], + updateText: function() { + titleText( "TheT(ourist)" , .08 , 1 - context.stepTime / this.time , 1 , 1 , 1 ); + } + } , { + rows: 12 , + rm: 'fractals' , + setGlobals: neutral , + lights : [ fractLight ], + updateText: function() { + titleText( "presents" , .08 , 1 - context.stepTime / this.time , 1 , 1 , 1 ); + } + } , { + rows: 20 , + rm: 'squares' , + setGlobals: function(ctx) { + squaresCam(ctx); + ctx.toNearPlane = 2.5; + ctx.fade = 1 - ctx.stepTime / this.time; + } , + lights : [ lightFunc(1,30) ], + updateText: function() { + titleText( "Sine City" , .04 , context.stepTime / this.time , 1 , 1 , 1 ); + } + } , { + rows: 52 , + rm: 'squares' , + setGlobals: function(ctx) { + squaresCam(ctx); + ctx.fade = 0; + } , + lights : [ lightFunc(1,30) ], + updateText: function() { + titleText( "Sine City" , .04 , 1 , 1 , 1 , 1 ); + } + } , { + rows: 12 , + rm: 'squares' , + setGlobals: function(ctx){ + squaresCam(ctx); + var z = context.stepTime / this.time; + ctx.fadeColour = 1; + ctx.fade = Math.max(0,1-z*2); + } , + lights : [ lightFunc(1,30) ], + updateText: function() { + var z = context.stepTime / this.time; + titleText( "Sine City" , .04 , 1 , 1 - z , 1 - z * .5 , 1 - z ); + } + } , { + rows: 12 , + rm: 'squares' , + setGlobals: function(ctx) { + squaresCam(ctx); + var z = context.stepTime / this.time; + ctx.desync = ( 1 - z ) * .7 + Math.random() * .025 - .0125; + ctx.greyMix = 1 - .5 * z; + } , + lights : [ lightFunc(1,30) ], + updateText: function() { + titleText( "Sine City" , .04 , 1 , 0 , .5 , 0 ); + } + } , { + rows: 9 , + rm: 'squares' , + setGlobals: function(ctx) { + squaresCam2(ctx,29); + var z = context.stepTime / this.time; + ctx.fade = Math.max(0,1-z*1.5); + ctx.desync += ( z - 1 ) * .3; + ctx.greyMix = .5 - .5 * z; + } , + lights : [ lightFunc(1,30) ], + updateText: function() { + titleText( "Sine City" , .04 , 1 - context.stepTime / this.time , 0 , .5 , 0 ); + } + } , { + rows: 69 , + rm: 'squares' , + setGlobals: function(ctx) { + squaresCam2(ctx,29); + ctx.greyMix = 0; + } , + lights : [ lightFunc(1,30) ], + updateText: null + } , { + rows: 11 , + rm: 'squares' , + setGlobals: function(ctx) { + squaresCam2(ctx,29); + ctx.fadeColour = .2; + ctx.fade = context.stepTime / this.time; + } , + lights : [ lightFunc(1,30) ], + updateText: null + } , { + rows: 11 , + rm: 'tunnel' , + setGlobals: function(ctx) { + ctx.tunMul = 1; + tunnelCam(ctx); + ctx.fade = 1 - context.stepTime / this.time; + } , + lights : [ tunnelLight ], + updateText: null + } , { + rows: 17 , + rm: 'tunnel' , + setGlobals: function(ctx) { + tunnelCam(ctx); + ctx.fade = 0; + ctx.desync = (1.2 - 1.2 * context.stepTime / this.time) * (.98 + .04*Math.random()); + } , + lights : [ tunnelLight ], + updateText: null + } , { + rows: 18 , + rm: 'tunnel' , + setGlobals: function(ctx) { + tunnelCam(ctx); + ctx.desync = 0; + ctx.extras[0] = '1f(p.BallOffset,'+(context.stepTime / this.time) + ')'; + } , + lights : [ tunnelLight ], + updateText: greetingsText + } , { + rows: 36 , + rm: 'tunnel' , + setGlobals: function(ctx) { + tunnelCam(ctx); + ctx.fade = 1 - Math.min(4*context.stepTime / this.time,1); + ctx.extras[0] = '1f(p.BallOffset,1)'; + } , + lights : tunLights = [ tunnelLight , tunnelLightBall ], + updateText: greetingsText + } , { + rows: 33 , + rm: 'tunnel' , + setGlobals: function(ctx) { + tunnelCam(ctx); + ctx.fadeColour = .7; + ctx.fade = context.stepTime / this.time; + ctx.extras[0] = '1f(p.BallOffset,1)'; + ctx.desync = -((4*ctx.fade)%1)*(.95+Math.random()*.1); + } , + lights : tunLights , + updateText: greetingsText + } , { + rows: 9 , + rm: 'fractals' , + setGlobals: function(ctx) { + fract2CamCommon(ctx,0); + ctx.fadeColour = 1; + ctx.fade = context.stepTime / this.time; + } , + lights : [ fractLight ], + updateText: greetingsText + } , { + rows: 20 , + rm: 'fractals' , + setGlobals: function(ctx) { + fract2CamCommon(ctx,context.stepTime / this.time); + ctx.fade = 0; + } , + lights : [ fractLight ], + updateText: greetingsText + } , { + rows: 31 , + rm: 'fractals' , + setGlobals: function(ctx) { + fract2CamCommon(ctx,1); + ctx.fade = Math.min(0,1-5*context.stepTime / this.time); + } , + lights : [ fractLight ], + updateText: greetingsText + } , { + rows: 5 , + rm: 'fractals' , + setGlobals: function(ctx) { + fract2CamCommon(ctx,1); + ctx.fade = 1-context.stepTime / this.time; + } , + lights : [ fractLight ], + updateText: greetingsText + } , { + rows: 18 , + rm: 'fractals' , + setGlobals: function(ctx) { + fract2CamCommon(ctx,1); + ctx.fade = Math.min(0,1-5*context.stepTime / this.time); + ctx.desync = Math.max(0,1.6*context.stepTime / this.time - .8 )*(.95+Math.random()*.1); + } , + lights : [ fractLight ], + updateText: greetingsText + } , { + rows: 12 , + rm: 'fractals' , + setGlobals: function(ctx) { + fract2CamCommon(ctx,1); + ctx.fadeColour = .1; + ctx.fade = context.stepTime / this.time; + ctx.desync = .8*(1-ctx.fade)*(.9+Math.random()*.2); + } , + lights : [ fractLight ], + updateText: greetingsText + } , { + rows: 22 , + rm: 'balls' , + setGlobals: function(ctx) { + balls2CamCommon(ctx); + ctx.fade = 1-context.stepTime / this.time; + ctx.desync = 0; + } , + lights : ballsLights = [ lightFunc(.6,30) , balls2LightFunc(1),balls2LightFunc(-1) ], + updateText: greetingsText + } , { + rows: 59 , + rm: 'balls' , + setGlobals: function(ctx) { + balls2CamCommon(ctx); + ctx.fadeColour = .8; + ctx.fade = Math.max(0,1-(12*context.stepTime / this.time)%4); + } , + lights : ballsLights, + updateText: greetingsText + } , { + rows: 8 , + rm: 'balls' , + setGlobals: function(ctx) { + balls2CamCommon(ctx); + ctx.fadeColour = .1; + ctx.fade = context.stepTime / this.time; + ctx.desync = .1-Math.random()*.2; + } , + lights : ballsLights, + updateText: null + } , { + rows: 7 , + rm: 'tunnel' , + setGlobals: function(ctx) { + ctx.tunMul = 2; + tunnelCam(ctx); + ctx.fade = 1-context.stepTime / this.time; + ctx.desync = .1-Math.random()*.2; + } , + lights : tunLights , + updateText: null + } , { + rows: 22 , + rm: 'tunnel' , + setGlobals: function(ctx) { + tunnelCam(ctx); + ctx.desync = .1-Math.random()*.2; + } , + lights : tunLights , + updateText: null + } , { + rows: 10 , + rm: 'tunnel' , + setGlobals: function(ctx) { + tunnelCam(ctx); + ctx.desync = context.stepTime*4+.1-Math.random()*.2; + ctx.fadeColour = 1; + ctx.fade = context.stepTime / this.time; + } , + lights : tunLights , + updateText: null + } , { + rows: 10 , + rm: 'squares' , + setGlobals: function(ctx) { + squaresCam2(ctx,49); + ctx.desync = (context.time-direction[48].startTime)*4+.1-Math.random()*.2; + ctx.fade = 1-context.stepTime / this.time; + } , + lights : [ lightFunc(1,30) ] , + updateText: null + } , { + rows: 40 , + rm: 'squares' , + setGlobals: function(ctx) { + squaresCam2(ctx,49); + ctx.desync = -(context.time-direction[48].startTime)*6; + } , + lights : [ lightFunc(1,30) ] , + updateText: null + } , { + rows: 40 , + rm: 'squares' , + setGlobals: function(ctx) { + squaresCam2(ctx,49); + ctx.desync = (context.time-direction[48].startTime)*8; + ctx.fadeColour = 0; + ctx.fade = context.stepTime / this.time; + } , + lights : [ lightFunc(1,30) ] , + updateText: null + } , { + rows: 68 , + rm: 'squares' , + setGlobals: function(ctx) { + squaresCam2(ctx,49); + ctx.fade = 1 + } , + lights : [ lightFunc(1,30) ] , + updateText: null + } +]; +var t = 0; +var BPM = 120; +for ( var i in direction ) { + direction[ i ].startTime = t; + t += ( direction[i].time = direction[ i ].rows * 60 / ( BPM * 4 ) ); + direction[ i ].endTime = t; +} +rows = t * BPM * 4 / 60; +console.log( "endTime: " + t + " (rows: " + rows + "; patterns: " + Math.floor(rows/36) + " + " + (rows - 36*Math.floor(rows/36)) + " extra row(s))" ); +console.log( "len : " + direction.length ); +t = 0; + +function getMaterialsCode(indices,noiseScale) +{ + var code = 'Material getMaterial( vec3 pos , float index ) {\n' + + 'Material m;'; + + for ( var i in indices ) { + if ( i > 0 ) { + code += 'else '; + } + var m = materials[ indices[i] ]; + code += 'if ( index == ' + shaderFloat( i ) + ' ) {\n' + + 'm.albedo = '; + if ( m.noiseScale ) { + code += 'mix( vec3(' + shaderVec( m.albedo ) + ') , vec3(' + + shaderVec( m.noise ) + ') , noise( pos * ' + + shaderFloat( noiseScale * m.noiseScale ) + ') )'; + } else { + code += 'vec3(' + shaderVec( m.albedo ) + ')'; + } + code += ';\nm.metallic=' + shaderFloat( m.metallic ) + ';\nm.smoothness=' + + shaderFloat( m.smoothness ) + ';\nm.r0=' + shaderFloat( m.r0 ) + ';\n}'; + } + + return code + 'return m;\n}\n'; +} + +function createRaymarcherCode( def , nLights ) { + var uniforms = [ 'CamMat' , 'CamPos' , 'Time' , 'Desync' , 'GreyMix' , 'Fade' , 'FadeColour' , 'TextParams' , 'TextColour' , 'Texture' ]; + var code = shaderBits['precision'] + + shaderBits['voTexCoords'] + + [ 'uniform mat3 uCamMat;' , + 'uniform vec3 uCamPos;' , + 'uniform float uTime;' , + 'uniform float uGreyMix;' , + 'uniform float uFade;' , + 'uniform float uFadeColour;' , + 'uniform vec3 uTextParams;' , + 'uniform vec3 uTextColour;' , + 'uniform sampler2D uTexture;' , + 'uniform float uDesync;' + ].join('\n'); + for ( var i in def.lights ) { + code += 'uniform vec3 uLightPos' + i + ', uLightColor' + i + ";\nuniform float uLightDistance" + i + ";\n"; + uniforms.splice( uniforms.length , 0 , 'LightPos' + i , 'LightColor' + i , 'LightDistance' + i ); + } + for ( var i in def.extraUniforms ) { + code += 'uniform ' + def.extraUniforms[i] + " u" + i + ";\n"; + uniforms.push(i); + } + for ( var i in def.extraBits ) { + code += shaderBits[def.extraBits[i]]; + } + code += shaderBits['rmUtils']; + code += 'vec2 cMap( vec3 p , float d ) {' + def.map + + '}' + getMaterialsCode(def.materials,def.noiseScale) + + [ + "vec3 getNormal( vec3 hp , float d )" , + "{" , + "vec2 e = vec2(1.,-1.)*" , shaderFloat(def.normalDelta) , ";" , + "vec4 f = vec4(" , + "cMap(hp+e.xyy,d).x," , + "cMap(hp+e.yyx,d).x," , + "cMap(hp+e.yxy,d).x," , + "cMap(hp+e.xxx,d).x" , + ");" , + "return normalize(f.x * e.xyy + f.y * e.yyx + f.z * e.yxy + f.w * e.xxx);" , + "}" , + + "float ambientOcclusion(vec3 p, vec3 n, vec3 cp){" , + "const int steps = ", def.aoSteps , ";" , + "const float delta = ", shaderFloat( def.aoDelta ) , ";" , + + "float a = 0.0;" , + "float weight = " , shaderFloat( def.aoWeight ) , ";" , + "float m;" , + "for(int i=1; i<=steps; i++) {" , + "float d = (float(i) / float(steps)) * delta;" , + "vec3 op = p + n * d;" , + "a += weight*(d - cMap(op,distance(op,cp)).x);" , + "weight *= 0.5;" , + "}" , + "return max(0.1 , 1.0 - clamp( pow(a , 1. ) , 0.0, 1.0) );" , + "}" , + + + "vec2 march( vec3 pos , vec3 dir , int nSteps)" , + "{" , + "float cd = 0. , e = " , shaderFloat( def.epsilon ) , ';' , + "vec2 m;" , + + "for ( int i = 0 ; i < " , def.depth , " ; i++ ) {" , + "m = cMap( pos + dir * cd , cd );" , + "if ( m.x < e || i > nSteps || cd >" , shaderFloat( def.maxDistance ) , " ) {" , + "break;" , + "}" , + "cd += m.x * " , shaderFloat( def.step ) , ";" , + "e *= " , shaderFloat( def.epsilonMultiplier ) , ";" , + "}" , + + "return vec2(cd,m.y);" , + "}" , + + "void main( ) " , + "{" , + "vec3 tc = vec3(voTexCoords,1.);" , + "tc.y += mod(uDesync,1.)*2.2;" , + "if ( tc.y > 1. ) {" , + "if ( tc.y < 1.2 ) discard;" , + "tc.y -= 2.2;" , + "}" , + "tc.x *= 1.6;" , + "vec3 dir = normalize( tc * uCamMat ) ," , + "pos = uCamPos , outColor = vec3( 0. ) , " , + "cMul = vec3( 1. ) , ld , l;" , + + "float ll;" , + "for ( int j = 0 ; j < 2 ; j ++ ) {" , + "vec3 col, nDir = dir , nPos = pos, ncMul = vec3(0.);" , + "vec2 vl,r = march( pos , dir , " , def.depth , " / ( j + 1 ) );" , + "if ( r.x < " , shaderFloat( def.maxDistance ) , " ) {" , + "vec3 hp = pos + dir * r.x , n=getNormal( hp , r.x ),hDir;" , + "nDir = reflect(dir,n);" , + "hDir = normalize( nDir + dir );" , + "float fog = " , shaderFloat( def.fogDensity ) , " * r.x;" , + "fog *= fog*fog*1.442695;" , + "fog = clamp( exp(-fog) , 0., 1. );" , + "Material m = getMaterial( hp , r.y );" , + "float occlusion = ambientOcclusion( hp , n , pos ) , " , + "fresnel = schlick( hDir , dir , m.r0 , m.smoothness * .9 + .1 );" , + "vec3 sCol = mix(vec3(1.),m.albedo/dot(LUMA,m.albedo),m.metallic) ," , + "dc , sc;" , + "col = vec3(0.);" , + ].join('\n'); + + for ( var l in def.lights ) { + var ld = def.lights[l]; + code += [ + "ld = uLightPos" + l + " - hp;" , + "ll = length(ld);" , + "ld /= ll;" , + "ll = max( 1. , ll - uLightDistance" + l + ") * " , shaderFloat( ld.attenuation ) , ";" , + "ll = 1. / max( 1. , ll * ll );" , + "l = ll * max(dot(ld,n),0.) * uLightColor" + l + ";" , + "dc = (1. - m.metallic) * m.albedo * occlusion;" , + "sc = sCol * getSpecular( dir , ld , n , m.smoothness );" , + "col += mix( dc , sc , fresnel ) * l;" + ].join('\n'); + code += ";"; + } + code += [ + "ncMul = cMul * fog * normalize(sCol) * m.r0 * (m.smoothness * .9 + .1) * fresnel;" , + "col = mix( vec3(" , shaderFloat(def.fog) , ") , col , fog );" , + "nPos += normalize(nDir) * " , shaderFloat(def.reflectionDistance) , ";" , + "} else {" , + "col=vec3(" , shaderFloat(def.fog) , ');' , + "}" , + ].join('\n'); + + for ( var l in def.lights ) { + var ld = def.lights[l]; + var r = ld.vRadius; + if ( r ) { + code += [ + "ld = pos - uLightPos" + l + ";" , + "vl = solve(dot(dir,dir),2.*dot(ld,dir),dot(ld,ld)-" + shaderFloat(r*r) + ");" , + "if ( vl.x > 0. && vl.y < r.x ) {" , + "float fog = " , shaderFloat( def.fogDensity ) , " * vl.x;" , + "fog *= fog*fog*1.442695;" , + "fog = clamp( exp(-fog) , 0., 1. );" , + "col += fog * uLightDistance" + l + " * uLightColor" + l + " * pow( (vl.y-vl.x) / " + shaderFloat(r*2) + " , 64. );" , + "}" + ].join( "\n" ); + } + } + + code += [ + "outColor += col * cMul;" , + "if ( all(lessThan(ncMul, vec3(.01))) ) {" , + "break;" , + "}" , + "cMul = ncMul;" , + "pos = nPos;" , + "dir = normalize(nDir);" , + "}" , + + "vec3 cMix = ( outColor.r == outColor.g && outColor.b == outColor.g ) ? outColor : vec3( dot( outColor , LUMA ) );" , + "outColor = mix( mix( outColor , cMix , uGreyMix ) , vec3(uFadeColour) , smoothstep( .05 , .95 , uFade ) );" , + + "cMix.xy = vec2(voTexCoords.x,tc.y) * .5 + .5;" , + "cMix.y = ( 1. - cMix.y - uTextParams.x ) / uTextParams.z;" , + "vec4 tcol = texture2D( uTexture , cMix.xy );" , + "outColor = mix(outColor , tcol.rgb * uTextColour , tcol.a * uTextParams.y );" , + + "outColor = max( vec3( 0. ) , outColor - vec3( .004 ) );" , + "outColor = ( outColor * ( 6.2 * outColor + .5 ) ) / ( outColor * ( 6.2 * outColor + vec3( 1.7 ) ) + vec3( .06 ) );" , + + "float g = smoothstep(.98,1.,noise(tc*8.-uTime*40.));" , + "outColor *= .95 + .05 * cos(uTime*41.);" , + "outColor += vec3(g);" , + "g = 1.-(smoothstep(.98,1.,noise(tc*8.+uTime*20.))+smoothstep(.95,1.,noise(tc*1.5+uTime*10.)));" , + + "float v = g*smoothstep(1.042+.008*cos(uTime*40.),.8,lx(voTexCoords,8.));" , + "g = (tc.x + 1. ) * (tc.y + 1. ) * (uTime * 10.0);" , + "v *= 1.-(mod((mod(g, 13.0) + 1.0) * (mod(g, 47.0) + 1.0), 0.01)) * 8.;" , + + "gl_FragColor = vec4(v*outColor,1.);" , + "}" , + ].join('\n'); + return [ code , uniforms ]; +} + +function buildRaymarchers( ) +{ + var ml = 1; + for ( var n in raymarchers ) { + var rm = raymarchers[n]; + var nl = rm.lights.length; + ml=nl>ml?nl:ml; + for ( var i=1;i<=nl;i++) { + var sn = 'rmfs_' + n + '_' + i; + var sd = createRaymarcherCode(rm,i); + shaderBits[sn] = sd[0]; + shaders[sn] = ['f',sn]; + programs['rm_' + n + '_' + i] = [ sd[1] , 'raymarchVS' , sn ]; + } + } + var context = { + camPos: vomNew(3), + lookAt: vomNew(3), + up: vomNew(3), + toNearPlane: 0 , + time: 0 , + desync: 0 , + greyMix: 0 , + fade: 0 , + fadeColour: 0 , + text: vomNew(3) , + textColour: vomNew(3) , + lights: [] + }; + for ( var i = 0;i<ml;i++ ) { + context.lights.push({ + pos: vomNew(3), + colour: vomNew(3) , + distance: 0 + }); + } + return context; +} + +var cmU=vomNew(3), + cmV=vomNew(3), + cmW=vomNew(3), + cd=vomNew(3), + cu=vomNew(3), + cm=vomNew(9); +function prepareRaymarcher( ds ) +{ + var rm = raymarchers[ds.rm], ctx = context; + ctx.extras = []; + ds.setGlobals( ctx ); + vecNorm(cmW,vecSub(cmW,ctx.lookAt,ctx.camPos)); + vecNorm(cmU,vecCross(cmU,ctx.up,cmW)); + vecNorm(cmV,vecCross(cmV,cmW,cmU)); + vecScale(cmW,cmW,ctx.toNearPlane); + vecs2Mat3(cm,cmU,cmV,cmW); + + var active = []; + for ( var i in ds.lights ) { + if ( ds.lights[i] && ds.lights[ i ](ctx,ctx.lights[ i ]) ) { + active.push( ctx.lights[ i ] ); + } + } + + var p = programs[ 'rm_' + ds.rm + '_' + active.length ]; + glCtx.useProgram( p[ 0 ] ); + glCtx.enableVertexAttribArray( 0 ); + glCtx.vertexAttribPointer( 0 , 2 , glCtx.FLOAT , false , 8 , 0 ); + p = p[1]; + glCtx.uniform1f( p.GreyMix , ctx.greyMix ); + glCtx.uniform1f( p.Fade , ctx.fade ); + glCtx.uniform1f( p.FadeColour , ctx.fadeColour ); + glCtx.uniform1f( p.Desync , ctx.desync ); + glCtx.uniform1f( p.Time , ctx.time ); + glCtx.uniform3fv( p.CamPos , ctx.camPos ); + glCtx.uniform3fv( p.TextParams , ctx.text ); + glCtx.uniform3fv( p.TextColour , ctx.textColour ); + glCtx.uniform1i( p.Texture , 0 ); + glCtx.uniformMatrix3fv( p.CamMat , false , cm ); + for ( var e in ctx.extras ) { + eval( 'glCtx.uniform' + ctx.extras[e] ); + } + for ( var i in active ) { + glCtx.uniform1f( p[ 'LightDistance' + i ] , active[ i ].distance ); + glCtx.uniform3fv( p[ 'LightPos' + i ] , active[ i ].pos ); + glCtx.uniform3fv( p[ 'LightColor' + i ] , active[ i ].colour ); + } + glCtx.drawArrays( 4 , 0 , 3 ); +} + + +// Main + +function resize() { + var vw=window.innerWidth,vh=window.innerHeight; + var cw=Math.floor(vh*1.6),ch=Math.floor(vw*.625); + if(cw>vw){ + C1.width=canvasWidth=vw; + C1.height=canvasHeight=ch; + }else{ + C1.width=canvasWidth=cw; + C1.height=canvasHeight=vh; + } + C2.style.width=C2.width=canvasWidth; + c2height=C2.style.height=C2.height=Math.max(canvasHeight/8,100); + c2rHeight=c2height/canvasHeight; + twoDCtx.shadowColor = "#ccc"; + twoDCtx.font = "normal small-caps bold " + Math.floor(c2height/2) + "px monospace"; + twoDCtx.fillStyle = "#111"; + twoDCtx.strokeStyle = "#ddd"; + C1.style.left=Math.floor((vw-canvasWidth)*.5); + C1.style.top=Math.floor((vh-canvasHeight)*.5); + glCtx.viewport(0,0,canvasWidth,canvasHeight); +} + +// FIXME: re-enable! document.body.style.cursor = 'none'; +document.body.style.background = 'black'; +document.body.innerHTML = '<canvas id=C1 style=position:fixed></canvas><canvas id=C2 style=display:none>'; +glCtx=C1.getContext('webgl'); +twoDCtx = C2.getContext('2d'); +(window.onresize=resize)(); +var context = buildRaymarchers( ); +buildPrograms(); +vtxBuffer = glCtx.createBuffer( ); +glCtx.bindBuffer( glCtx.ARRAY_BUFFER , glCtx.createBuffer( ) ); +glCtx.bufferData( glCtx.ARRAY_BUFFER , vomNew([1,4,1,-1,-4,-1]) , glCtx.STATIC_DRAW ); +glCtx.clearColor(0,0,0,1); + +textTexture = glCtx.createTexture( ); +glCtx.bindTexture( glCtx.TEXTURE_2D , textTexture ); +glCtx.texParameteri( glCtx.TEXTURE_2D , glCtx.TEXTURE_WRAP_S, glCtx.CLAMP_TO_EDGE ); +glCtx.texParameteri( glCtx.TEXTURE_2D , glCtx.TEXTURE_WRAP_T, glCtx.CLAMP_TO_EDGE ); +glCtx.texParameteri( glCtx.TEXTURE_2D , glCtx.TEXTURE_MIN_FILTER, glCtx.NEAREST ); +glCtx.texParameteri( glCtx.TEXTURE_2D , glCtx.TEXTURE_MAG_FILTER, glCtx.NEAREST ); +glCtx.texImage2D( glCtx.TEXTURE_2D , 0 , glCtx.RGBA , glCtx.RGBA , glCtx.UNSIGNED_BYTE , C2 ); + +timeStart = previousFrame = 0; +FRAME_TIME = 100/3; + +paused = 0; +document.body.onkeypress = function(e) { + if ( e.keyCode == 32 ) { + var now = Date.now(); + if ( paused ) { + timeStart += now - paused; + paused = 0; + requestAnimationFrame(draw); + A.play( ); + } else { + paused = now; + A.pause( ); + } + } +}; + +mainfunc = function(){ +requestAnimationFrame(draw=function(time){ + if ( ! paused ) { + requestAnimationFrame(draw); + } + if ( timeStart == 0 ) { + A.play( ); + timeStart = time; + previousFrame = timeStart - FRAME_TIME; + } + var delta = time - previousFrame, demoTime = .001*(time - timeStart); + if ( delta < FRAME_TIME ) { + return; + } + previousFrame = time - ( delta % FRAME_TIME ); + + var ds = direction[t]; + while ( ds && ds.endTime < demoTime ) { + ds=direction[++t]; + } + if ( ! ds ) { + A.pause( ); + return; + } + context.time = demoTime; + context.stepTime = demoTime - ds.startTime; + if ( ds.updateText ) { + twoDCtx.clearRect( 0 , 0 , canvasWidth , 100 ); + ds.updateText(); + glCtx.texImage2D( glCtx.TEXTURE_2D , 0 , glCtx.RGBA , glCtx.RGBA , glCtx.UNSIGNED_BYTE , C2 ); + } else { + vecSet(context.text,0,0,100/canvasHeight); + } + prepareRaymarcher( ds ); +}) +} + +if ( USE_SYNTH ) { + synth = new CPlayer(); + synth.init(song); + synthGen = setInterval(function(){ + if ( synth.generate() == 1 ) { + clearInterval(synthGen); + var s = '' , a = synth.createWave(); + for(var i=0;i<a.length;i++) + s+= String.fromCharCode(a[i]); + A = document.createElement("audio"); + A.src= 'data:audio/wav;base64,' + btoa(s); + A.oncanplaythrough=mainfunc; + } + + }, 0); +} else { + A = document.createElement("audio"); + A.oncanplaythrough=mainfunc; + A.src= 'music.ogg'; +} + diff --git a/201410_-_Sine_City/sine-city-packing-1-shaders.html b/201410_-_Sine_City/sine-city-packing-1-shaders.html new file mode 100644 index 0000000..743a66d --- /dev/null +++ b/201410_-_Sine_City/sine-city-packing-1-shaders.html @@ -0,0 +1,5 @@ +<body> +<script language="javascript" src="music.js"></script> +<script language="javascript" src="player-small.js"></script> +<script language="javascript" src="sine-city-packing-1-shaders.js"></script> + diff --git a/201410_-_Sine_City/sine-city-packing-1-shaders.js b/201410_-_Sine_City/sine-city-packing-1-shaders.js new file mode 100644 index 0000000..00e3ab0 --- /dev/null +++ b/201410_-_Sine_City/sine-city-packing-1-shaders.js @@ -0,0 +1,1405 @@ +var USE_SYNTH = 0; + +// Vector stuff +function vecOp(code) { + return eval('(function(o,a,b){for(var i=o.length;--i>=0;)' + code + ';return o})') +} +function vomNew(s) { + return new Float32Array(s) +} +var vecDot = function(a,b) { + var s = 0; + for ( var i in a ) { + s += a[i]*b[i]; + } + return s; +}; +var vecLen = function(a) { + return Math.sqrt( vecDot(a,a) ) +}; +var vecNorm = function(o,a) { + var l = vecLen(a); + return l ? vecScale(o,a,1/l) : vecCopy(o,a); +}; +var vecCross = function(o,a,b) { + return vecSet(o, + a[1]*b[2]-a[2]*b[1] , + a[2]*b[0]-a[0]*b[2] , + a[0]*b[1]-a[1]*b[0] + ); +}; +var vecs2Mat3 = function(o,a,b,c){ + for ( var i = 0 ; i < 3 ; i ++ ) { + o[i*3+0] = a[i]; + o[i*3+1] = b[i]; + o[i*3+2] = c[i]; + } +}; +var vecSet = vecOp('o[i]=arguments[i+1]') , + vecCopy = vecOp('o[i]=a[i]') , + vecAdd = vecOp('o[i]=a[i]+b[i]') , + vecSub = vecOp('o[i]=a[i]-b[i]') , + vecScale = vecOp('o[i]=a[i]*b'); + + +// Shaders +var shaderHeader = 'precision highp float;varying !2 zx;'; + + +function shaderFloat( v ) { + return '' + v + ( v == Math.floor(v) ? '.' : '' ); +} +function shaderVec( v ) { + return v.map(shaderFloat).join(','); +} + + +// Raymarchers + +var materials = [ + { + albedo: [.05,.05,.05] , + metallic: .7 , + smoothness: .02 , + r0: .01 + } , { + albedo: [ .2,.2,.2 ] , + noise: [ .1,.1,.1] , + noiseScale: 5 , + metallic: .7 , + smoothness: .9 , + r0: .01 + } , { + albedo: [ 1,1,1 ] , + metallic: .5 , + smoothness: .4 , + r0: .02 + } , { + albedo: [ 3,0,0 ] , + noise: [.6,0,0], + noiseScale: 6 , + metallic: .3 , + smoothness: .1 , + r0: .6 + } , { + albedo: [ 0,2,0 ] , + noise: [0,.2,0], + noiseScale: 15 , + metallic: .9 , + smoothness: .5 , + r0: .4 + } , { + albedo: [ 3,1.5,0 ] , + noise: [.3,.6,0], + noiseScale: .3 , + metallic: .95 , + smoothness: .6 , + r0: .9 + } , { + albedo: [ .1,.1,.1 ] , + noise: [3,3,3] , + noiseScale: 3, + metallic: 0 , + smoothness: .04 , + r0: .002 + } , { + albedo: [ 0,1.5,2 ] , + metallic: .9 , + smoothness: .3 , + r0: .4 + } +]; + + +var raymarchers = { + tunnel: { + maxDistance: 100 , + epsilon: .025 , + epsilonMultiplier: 1 , + step: .7 , + depth: 64 , + + normalDelta: .0005 , + noiseScale: .5 , + reflectionDistance: .3 , + + fog: .4 , + fogDensity: .015 , + + aoSteps: 4 , + aoDelta: 2 , + aoWeight: .75 , + + materials: [0,1,2,3] , + + map: [ + "y=x+.1*(sin(x.zxy*.17+u4[0]*.5)+sin(x.yzx*.7+u4[0]*1.5))*8.5*(1.+cos(sin(x.z*.1)+x.z*.3)),", + + "z=14.-length(y.xy),", + "w=x.x==.0?1.570795*(x.y>.0?1.:-1.):atan(x.y,x.x),", + "q=8.35-u4[8]*1.35,", + + "y=!3(9.*(mod(w+x.z*.02,.628)-.314),length(x.xy)-9.,mod(x.z,12.56)-6.28),", + "u=min(length(y.xy)-.25+.1*cos(x.z*8.+u4[0]*.1),length(y.yz)-.5),", + "y=!3(q*(mod(w+x.z*.02,1.256636)-.628318),y.y+9.-q,mod(x.z,62.8318)-31.4159)," , + "o=step(u,z)+1.,", + "z=min(u,z),", + "u=length(y)-1.3;", + "if(u<z)z=u,o=3.;" , + "y.y+=q-9.," , + "u=yyx(y.yz,8.)-2.;" , + "if(u<z)z=u,o=.0;" , + "return !2(z,o);" + ].join('\n') , + lights: [ + { + attenuation: .25 , + vRadius: 0 + } , { + attenuation: .5 , + vRadius: .5 + } + ] , + } , + fractals: { + maxDistance: 6 , + epsilon: .00025 , + epsilonMultiplier: 1.08 , + step: .7 , + depth: 100 , + + normalDelta: .000008 , + noiseScale: 10 , + reflectionDistance: .03 , + + fog: 2.1 , + fogDensity: .2 , + + aoSteps: 6 , + aoDelta: .4 , + aoWeight: 5.1 , + + materials: [0,2,5] , + + map: [ + "z=1.," , + "y=x;" , + "for(int i=0;i<7;i++)" , + "x=2.*clamp(x,-!3(.58,.9,1.1),!3(.58,.9,1.1))-x," , + "w=max((1.3+u4[9]*.1*cos(u4[0]*.5))/dot(x,x),1.)," , + "x*=w," , + "z*=w;" , + "w=length(x.xy),", + "e=!2(w-3.,-w*x.z/length(x)-2.*log(1.+.01*a))/abs(z),", + "w=max(e.x,e.y),", + "o=step(e.y,e.x),", + "y+=!3(.1,.3,-.4)*u0-u2+.25*sin(x*1.),", + "e.x=length(y)-.1*u4[8];", + "if(e.x<w)w=e.x,o=2.;" , + "return !2(w,o);" + ].join('\n') , + lights: [ + { + attenuation: .05 + } + ] , + } , + squares: { + maxDistance: 100 , + epsilon: .000025 , + epsilonMultiplier: 1 , + step: .75 , + depth: 80 , + + normalDelta: .00005 , + noiseScale: .5 , + reflectionDistance: .3 , + + fog: 3 , + fogDensity: .01 , + + aoSteps: 4 , + aoDelta: .75 , + aoWeight: 4.75 , + + materials: [6,0,4] , + + map: [ + "x.xy*=t(a*.009),", + + "w=min(min(yz(x.xzy),yz(x)),yz(x.yzx)),", + + "y=mod(x,!3(15.))-!3(7.5),", + "o=step(z=max(length(max(abs(y)-!3(2.5),!3(.0)))-.25,3.5-length(y)),w),", + "w=min(w,z),", + "z=length(y+.1*sin(y*5.5+u4[0]))-2.;", + "if(z<w)", + "w=z,", + "o=2.;", + "return !2(w,o);" + ].join('\n') , + lights: [ + { + attenuation: .05 + } + ] , + } , + balls: { + maxDistance: 20 , + epsilon: .0005 , + epsilonMultiplier: 1 , + step: .6 , + depth: 128 , + + normalDelta: .0001 , + noiseScale: .5 , + reflectionDistance: .002 , + + fog: .01 , + fogDensity: .08 , + + aoSteps: 4 , + aoDelta: .5 , + aoWeight: 1.75 , + + materials: [2,7] , + + map: [ + "y=x,", + "y.xz=mod(x.xz,8.)-4.,", + "y.yz*=t(u4[8]+.1*a),", + "y.xy*=t(u4[8]*.5+.2*a),", + "y.y*=.9+.1*sin(u4[8]*5.),", + "w=max(length(y)-3.,-min(length(y)-2.8,", + "max(mod(y.y,.8)-.4,-mod(y.y+.4,.8)+.4))),", + "z=x.y+1.+sin(x.x*4.+u4[8]*2.)*sin(x.z+u4[8])*.1,", + "o=clamp(.5+.5*(z-w)/1.,.0,1.),", + "w=mix(z,w,o)-1.*o*(1.-o),", + "y=x,", + "y.xz=mod(y.xz,8.)-4.,", + "y/=1.25+.25*sin(u4[8]*5.),", + "y.xy*=t(u4[8]*5.),", + "y.yz*=t(u4[8]*2.5),", + "z=max(length(y)-1.,.04-length(max(abs(mod(y,.5)-.25)-!3(.15),!3(.0))));", + "return !2(min(w,z),step(z,w));" + ].join('\n') , + lights: [ + { + attenuation: .02 + },{ + attenuation: .05 , + vRadius: .5 + } , { + attenuation: .05 , + vRadius: .5 + } + ] , + } +}; + +var lightFunc = function(intensity,distance) { + return function(ctx,lctx) { + vecCopy(lctx.pos,ctx.camPos); + vecSet(lctx.colour,intensity,intensity,intensity); + lctx.distance = distance; + return true; + } +}; +var tun1CamCommon = function(ctx,dir) { + var z = demoTime*6; + vecSet(ctx.camPos,-6,0,z); + vecSet(ctx.lookAt,1,0,z); + vecSet(ctx.up,0,1,0); + ctx.misc[1] = 1; + ctx.misc[8] = 0; + return ctx.stepTime / dir.time; +}; +var desyncFunc = function(desync) { + return function(ctx,tt) { + var z = ctx.stepTime / tt; + ctx.misc[4] = -z * desync; + if ( desync > 0 ) { + ctx.misc[4] += desync; + } + ctx.misc[4] *= Math.random( ) * .25 + .75; + }; +}; +var balls1CamFunc = function(lax,laz,desync) { + var dsf = desyncFunc(desync); + return function(ctx) { + var z = demoTime*3; + vecSet(ctx.camPos,0,4,z); + vecSet(ctx.lookAt,lax,0,z+laz); + vecSet(ctx.up,0,0,1); + ctx.misc[8]= ctx.misc[2] = 0; + dsf(ctx,this.time); + }; +}; +var balls2CamCommon = function(ctx) { + var z = demoTime*5; + vecSet(ctx.camPos,Math.cos(demoTime)*12,8,Math.sin(demoTime)*12+z); + vecSet(ctx.lookAt,1,0,z); + vecSet(ctx.up,0,1,0); + ctx.toNearPlane = 2.5; + z = demoTime - direction[43].startTime; + ctx.misc[8]=z; +}; +var balls2LightFunc = function(scale) { + return function(ctx,lctx) { + var z = demoTime*30; + vecSet(lctx.pos,scale*Math.cos(demoTime*2)*5,3,scale*Math.sin(demoTime*2)*5+z); + vecSet(lctx.colour,1,1,1); + lctx.distance = 4; + return true; + }; +}; +var fract1CamCommon = function(ctx) { + var z = demoTime; + vecSet(ctx.camPos,4,2.5+.025*z,6.7); + vecSet(ctx.lookAt,0,2.5-.05*z,6.7); + vecSet(ctx.up,0,0,1); + ctx.misc[8] = ctx.misc[9] = 0; + ctx.toNearPlane = 3; +}; +var fract1CamFunc = function(desync) { + var dsf = desyncFunc(desync); + return function(ctx){ + fract1CamCommon(ctx); + dsf(ctx,this.time); + }; +}; +var fract2CamCommon = function(ctx,bs) { + vecSet(ctx.camPos,5*Math.sin(demoTime*.2),9*Math.cos(demoTime*.41),7.8); + vecCopy(ctx.lookAt,ctx.camPos); + ctx.lookAt[0] = Math.cos(demoTime*.2); + ctx.lookAt[1] = Math.sin(demoTime*.33); + ctx.lookAt[2] -= 2; + vecSet(ctx.up,0,0,1); + ctx.toNearPlane = 3; + ctx.misc[8] = bs; + ctx.misc[9] = 1; +}; + +var drawText = function(str,x) { + twoDCtx.shadowBlur = c2height/5; + twoDCtx.fillText( str , x , c2height / 2 ); + twoDCtx.shadowBlur = 0; + twoDCtx.strokeText( str , x , c2height / 2 ); +}; +var titleText = function(str,shake,alpha,r,g,b) { + drawText( str , canvasWidth/15 ); + context.misc[5] = 1 - c2rHeight + Math.random() * shake - shake * .5; + context.misc[6] = alpha; + vecSet( context.textColour , r , g , b ); +}; +var greetings = "Greetings to ... Mog, Sycop, Tim & Wullon ... Adinpsz ... Alcatraz ... ASD ... Bits'n'Bites ... Brain Control ... Cocoon ... Conspiracy ... Ctrl+Alt+Test ... Fairlight ... Farbrausch ... Kewlers ... LNX ... Loonies ... Mercury ... Popsy Team ... Razor 1911 ... RGBA ... 7th Cube ... Still ... TPOLM ... TRBL ... Umlaut Design ... X-Men ... Youth Uprising ... Everyone here at DemoJS 2014!"; +var greetingsText = function() { + var t = ( demoTime - direction[34].startTime ) * canvasWidth * .5; + drawText( greetings , canvasWidth - t ); + context.misc[5] = 1 - c2rHeight + Math.random() * .02 - .01; + context.misc[6] = 1; + vecSet( context.textColour , 1 , 1 , 1 ); +}; + +var squaresCam = function(ctx) { + var t = demoTime - direction[25].startTime; + var z = t*10 - 80; + vecSet(ctx.camPos,z,0,0); + vecSet(ctx.lookAt,z+Math.cos(t*.5) * 80,Math.sin(t*.25)*40,100); + vecSet(ctx.up,0,1,0); +}; + +var squaresCam2 = function(ctx,s) { + var t = demoTime - direction[s].startTime; + var z = t*20 - 80; + vecSet(ctx.camPos,0,0,z); + vecSet(ctx.lookAt,Math.cos(t*.5) * 80,Math.sin(t*.25)*40,z+100); + vecSet(ctx.up,Math.sin(t),Math.cos(t),0); + ctx.misc[4] = Math.random() * .025 - .0125; +}; + +var tunnelLight = function(ctx,lctx) { + vecAdd(lctx.pos,vecNorm(lctx.pos,vecScale(lctx.pos,ctx.lookAt,-1)),ctx.camPos); + lctx.pos[1] -= .5; + vecSet(lctx.colour,3,3,3); + lctx.distance = 30; + return true; +}; +var tunnelCam = function(ctx,mul) { + var z = demoTime*30*ctx.tunMul; + vecSet(ctx.camPos,1.1*Math.cos(z*.1),Math.sin(z*.02),z); + z += 5; + vecSet(ctx.lookAt,-Math.sin(z*.05),-.7*Math.cos(z*.033),z); + vecSet(ctx.up,0,1,0); + ctx.toNearPlane = 2; +}; +var tunnelLightBall = function(ctx,lctx) { + vecSet(lctx.pos , 4*Math.sin(demoTime*.5)*Math.cos(demoTime*.7) , + 3*Math.cos(demoTime*1.5), + demoTime*30*ctx.tunMul+14+16*Math.sin(demoTime*3.3)*Math.cos(demoTime*.77) + ); + vecSet(lctx.colour,1,1,1); + lctx.distance = 15; + return true; +}; + +var direction = [ + { + // Music rows + rows: 36 , + // Raymarcher id + rm: 'tunnel' , + setGlobals: function( ctx ) { + var z = tun1CamCommon(ctx,this); + z *= z*z; + ctx.misc[2] = 1 - z; + ctx.toNearPlane = 5; + } , + lights: [ + lightFunc(3,20) + ] , + updateText: null + } , { + rows: 18 , + rm: 'tunnel' , + setGlobals: function( ctx ) { + var z = tun1CamCommon(ctx,this); + ctx.toNearPlane = 5 - 2.25 * z; + ctx.misc[2] = 0; + } , + lights: [ + lightFunc(3,20) + ] , + updateText: null + } , { + rows: 36 , + rm: 'tunnel' , + setGlobals: function( ctx ) { + var z = tun1CamCommon(ctx,this); + ctx.toNearPlane = 2.75 - 2.25 * z; + ctx.misc[2] = z; + } , + lights: [ + lightFunc(3,20) + ] , + updateText: null + } , { + rows: 18 , + rm: 'balls' , + setGlobals: function( ctx ) { + var z = demoTime*3; + vecSet(ctx.camPos,0,4,z); + vecSet(ctx.lookAt,4,0,z); + vecSet(ctx.up,0,0,1); + z = ctx.stepTime / this.time; + z *= z*z; + ctx.misc[2] = 1 - z; + ctx.toNearPlane = 2.5; + } , + lights: [ + lightFunc(.75,8) + ] , + updateText: null + } , { + rows: 22 , + rm: 'balls' , + setGlobals: balls1CamFunc(4,0,0) , + lights: [ + lightFunc(1,8) + ] , + updateText: null + } , { + rows: 22 , + rm: 'balls' , + setGlobals: balls1CamFunc(2,-2,0) , + lights: [ + lightFunc(1,8) + ] , + updateText: null + } , { + rows: 3 , + rm: 'balls' , + setGlobals: balls1CamFunc( 6 , 0 , -.5 ) , + lights: [ + lightFunc(.5,4) + ] , + updateText: null + } , { + rows: 9 , + rm: 'balls' , + setGlobals: balls1CamFunc( 6 , 0 , .5 ) , + lights: [ + lightFunc(.5,4) + ] , + updateText: null + } , { + rows: 3 , + rm: 'balls' , + setGlobals: balls1CamFunc( 2 , 2 , -.2 ) , + lights: [ + lightFunc(1,8) + ] , + updateText: null + } , { + rows: 9 , + rm: 'balls' , + setGlobals: balls1CamFunc( 2 , 2 , .2 ) , + lights: [ + lightFunc(1,8) + ] , + updateText: null + } , { + rows: 3 , + rm: 'balls' , + setGlobals: balls1CamFunc( 2 , 5 , -.7 ) , + lights: [ + lightFunc(1,2) + ] , + updateText: null + } , { + rows: 7 , + rm: 'balls' , + setGlobals: balls1CamFunc( 2 , 2 , .7 ) , + lights: [ + lightFunc(1,2) + ] , + updateText: null + } , { + rows: 9 , + rm: 'balls' , + setGlobals: function(ctx) { + var z = demoTime*3; + ctx.misc[2] = ctx.stepTime / this.time; + vecSet(ctx.camPos,0,4+ctx.misc[2]*2,z); + vecSet(ctx.lookAt,2,0,z+2); + vecSet(ctx.up,0,0,1); + ctx.misc[3] = 1; + } , + lights: [ + lightFunc(1,2) + ] , + updateText: null + } , { + rows: 21 , + rm: 'fractals' , + setGlobals: function( ctx ) { + fract1CamCommon(ctx); + ctx.misc[3] = 1; + var z = ctx.stepTime / this.time; + ctx.misc[2] = 1 - z*z*z; + } , lights : [ + fractLight = function(ctx,lctx) { + vecCopy(lctx.pos,ctx.camPos); + lctx.pos[2]+=2; + vecSet(lctx.colour,1,1,1); + lctx.distance = 3; + return true; + } + ], + updateText: null + } , { + rows: 14 , + rm: 'fractals' , + setGlobals: fract1CamFunc(0) , + lights : [ + fractLight + ], + updateText: null + } , { + rows: 3 , + rm: 'fractals' , + setGlobals: fract1CamFunc(-.4) , + lights : [ fractLight ], + updateText: null + } , { + rows: 9 , + rm: 'fractals' , + setGlobals: fract1CamFunc(.4) , + lights : [ fractLight ], + updateText: null + } , { + rows: 3 , + rm: 'fractals' , + setGlobals: fract1CamFunc(-.2) , + lights : [ fractLight ], + updateText: null + } , { + rows: 9 , + rm: 'fractals' , + setGlobals: fract1CamFunc(.2) , + lights : [ fractLight ], + updateText: null + } , { + rows: 12 , + rm: 'fractals' , + setGlobals: function(ctx) { + fract1CamCommon(ctx); + ctx.misc[4] = -( 6 * ctx.stepTime / this.time ) % 1; + ctx.misc[4] *= Math.random( ) * .25 + .75; + } , + lights : [ fractLight ], + updateText: null + } , { + rows: 22 , + rm: 'fractals' , + setGlobals: function(ctx) { + fract1CamCommon(ctx); + ctx.misc[3] = .4; + ctx.misc[2] = ctx.stepTime / this.time; + ctx.toNearPlane = 3 - 2.5*Math.max(1,2*ctx.misc[2]); + ctx.misc[4] = ( 30 * ctx.misc[2] ) % 1; + ctx.misc[4] *= Math.random( ) * .15 + .85; + } , + lights : [ fractLight ], + updateText: null + } , { + rows: 3 , + rm: 'fractals' , + setGlobals: neutral = function(ctx) { + fract1CamCommon(ctx); + ctx.misc[3] = .4; + ctx.misc[2] = 1; + ctx.misc[4] = 0; + } , + lights : [ fractLight ], + updateText: null + } , { + rows: 12 , + rm: 'fractals' , + setGlobals: neutral , + lights : [ fractLight ], + updateText: function() { + titleText( "TheT(ourist)" , .08 , 1 , 1 , 1 , 1 ); + } + } , { + rows: 12 , + rm: 'fractals' , + setGlobals: neutral , + lights : [ fractLight ], + updateText: function() { + titleText( "TheT(ourist)" , .08 , 1 - context.stepTime / this.time , 1 , 1 , 1 ); + } + } , { + rows: 12 , + rm: 'fractals' , + setGlobals: neutral , + lights : [ fractLight ], + updateText: function() { + titleText( "presents" , .08 , 1 - context.stepTime / this.time , 1 , 1 , 1 ); + } + } , { + rows: 20 , + rm: 'squares' , + setGlobals: function(ctx) { + squaresCam(ctx); + ctx.toNearPlane = 2.5; + ctx.misc[2] = 1 - ctx.stepTime / this.time; + } , + lights : [ lightFunc(1,30) ], + updateText: function() { + titleText( "Sine City" , .04 , context.stepTime / this.time , 1 , 1 , 1 ); + } + } , { + rows: 52 , + rm: 'squares' , + setGlobals: function(ctx) { + squaresCam(ctx); + ctx.misc[2] = 0; + } , + lights : [ lightFunc(1,30) ], + updateText: function() { + titleText( "Sine City" , .04 , 1 , 1 , 1 , 1 ); + } + } , { + rows: 12 , + rm: 'squares' , + setGlobals: function(ctx){ + squaresCam(ctx); + var z = context.stepTime / this.time; + ctx.misc[3] = 1; + ctx.misc[2] = Math.max(0,1-z*2); + } , + lights : [ lightFunc(1,30) ], + updateText: function() { + var z = context.stepTime / this.time; + titleText( "Sine City" , .04 , 1 , 1 - z , 1 - z * .5 , 1 - z ); + } + } , { + rows: 12 , + rm: 'squares' , + setGlobals: function(ctx) { + squaresCam(ctx); + var z = context.stepTime / this.time; + ctx.misc[4] = ( 1 - z ) * .7 + Math.random() * .025 - .0125; + ctx.misc[1] = 1 - .5 * z; + } , + lights : [ lightFunc(1,30) ], + updateText: function() { + titleText( "Sine City" , .04 , 1 , 0 , .5 , 0 ); + } + } , { + rows: 9 , + rm: 'squares' , + setGlobals: function(ctx) { + squaresCam2(ctx,29); + var z = context.stepTime / this.time; + ctx.misc[2] = Math.max(0,1-z*1.5); + ctx.misc[4] += ( z - 1 ) * .3; + ctx.misc[1] = .5 - .5 * z; + } , + lights : [ lightFunc(1,30) ], + updateText: function() { + titleText( "Sine City" , .04 , 1 - context.stepTime / this.time , 0 , .5 , 0 ); + } + } , { + rows: 69 , + rm: 'squares' , + setGlobals: function(ctx) { + squaresCam2(ctx,29); + ctx.misc[1] = 0; + } , + lights : [ lightFunc(1,30) ], + updateText: null + } , { + rows: 11 , + rm: 'squares' , + setGlobals: function(ctx) { + squaresCam2(ctx,29); + ctx.misc[3] = .2; + ctx.misc[2] = context.stepTime / this.time; + } , + lights : [ lightFunc(1,30) ], + updateText: null + } , { + rows: 11 , + rm: 'tunnel' , + setGlobals: function(ctx) { + ctx.tunMul = 1; + tunnelCam(ctx); + ctx.misc[2] = 1 - context.stepTime / this.time; + } , + lights : [ tunnelLight ], + updateText: null + } , { + rows: 17 , + rm: 'tunnel' , + setGlobals: function(ctx) { + tunnelCam(ctx); + ctx.misc[2] = 0; + ctx.misc[4] = (1.2 - 1.2 * context.stepTime / this.time) * (.98 + .04*Math.random()); + } , + lights : [ tunnelLight ], + updateText: null + } , { + rows: 18 , + rm: 'tunnel' , + setGlobals: function(ctx) { + tunnelCam(ctx); + ctx.misc[4] = 0; + ctx.misc[8] = context.stepTime / this.time; + } , + lights : [ tunnelLight ], + updateText: greetingsText + } , { + rows: 36 , + rm: 'tunnel' , + setGlobals: function(ctx) { + tunnelCam(ctx); + ctx.misc[2] = 1 - Math.min(4*context.stepTime / this.time,1); + ctx.misc[8] = 1; + } , + lights : tunLights = [ tunnelLight , tunnelLightBall ], + updateText: greetingsText + } , { + rows: 33 , + rm: 'tunnel' , + setGlobals: function(ctx) { + tunnelCam(ctx); + ctx.misc[2] = context.stepTime / this.time; + ctx.misc[3] = .7; + ctx.misc[4] = -((4*ctx.misc[2])%1)*(.95+Math.random()*.1); + } , + lights : tunLights , + updateText: greetingsText + } , { + rows: 9 , + rm: 'fractals' , + setGlobals: function(ctx) { + fract2CamCommon(ctx,0); + ctx.misc[2] = context.stepTime / this.time; + ctx.misc[3] = 1; + } , + lights : [ fractLight ], + updateText: greetingsText + } , { + rows: 20 , + rm: 'fractals' , + setGlobals: function(ctx) { + fract2CamCommon(ctx,context.stepTime / this.time); + ctx.misc[2] = 0; + } , + lights : [ fractLight ], + updateText: greetingsText + } , { + rows: 31 , + rm: 'fractals' , + setGlobals: function(ctx) { + fract2CamCommon(ctx,1); + ctx.misc[2] = Math.min(0,1-5*context.stepTime / this.time); + } , + lights : [ fractLight ], + updateText: greetingsText + } , { + rows: 5 , + rm: 'fractals' , + setGlobals: function(ctx) { + fract2CamCommon(ctx,1); + ctx.misc[2] = 1-context.stepTime / this.time; + } , + lights : [ fractLight ], + updateText: greetingsText + } , { + rows: 18 , + rm: 'fractals' , + setGlobals: function(ctx) { + fract2CamCommon(ctx,1); + ctx.misc[2] = Math.min(0,1-5*context.stepTime / this.time); + ctx.misc[4] = Math.max(0,1.6*context.stepTime / this.time - .8 )*(.95+Math.random()*.1); + } , + lights : [ fractLight ], + updateText: greetingsText + } , { + rows: 12 , + rm: 'fractals' , + setGlobals: function(ctx) { + fract2CamCommon(ctx,1); + ctx.misc[3] = .1; + ctx.misc[2] = context.stepTime / this.time; + ctx.misc[4] = .8*(1-ctx.misc[2])*(.9+Math.random()*.2); + } , + lights : [ fractLight ], + updateText: greetingsText + } , { + rows: 22 , + rm: 'balls' , + setGlobals: function(ctx) { + balls2CamCommon(ctx); + ctx.misc[2] = 1-context.stepTime / this.time; + ctx.misc[4] = 0; + } , + lights : ballsLights = [ lightFunc(.6,30) , balls2LightFunc(1),balls2LightFunc(-1) ], + updateText: greetingsText + } , { + rows: 59 , + rm: 'balls' , + setGlobals: function(ctx) { + balls2CamCommon(ctx); + ctx.misc[3] = .8; + ctx.misc[2] = Math.max(0,1-(12*context.stepTime / this.time)%4); + } , + lights : ballsLights, + updateText: greetingsText + } , { + rows: 8 , + rm: 'balls' , + setGlobals: function(ctx) { + balls2CamCommon(ctx); + ctx.misc[3] = .1; + ctx.misc[2] = context.stepTime / this.time; + ctx.misc[4] = .1-Math.random()*.2; + } , + lights : ballsLights, + updateText: null + } , { + rows: 7 , + rm: 'tunnel' , + setGlobals: function(ctx) { + ctx.tunMul = 2; + tunnelCam(ctx); + ctx.misc[2] = 1-context.stepTime / this.time; + ctx.misc[4] = .1-Math.random()*.2; + } , + lights : tunLights , + updateText: null + } , { + rows: 22 , + rm: 'tunnel' , + setGlobals: function(ctx) { + tunnelCam(ctx); + ctx.misc[4] = .1-Math.random()*.2; + } , + lights : tunLights , + updateText: null + } , { + rows: 10 , + rm: 'tunnel' , + setGlobals: function(ctx) { + tunnelCam(ctx); + ctx.misc[4] = context.stepTime*4+.1-Math.random()*.2; + ctx.misc[3] = 1; + ctx.misc[2] = context.stepTime / this.time; + } , + lights : tunLights , + updateText: null + } , { + rows: 10 , + rm: 'squares' , + setGlobals: function(ctx) { + squaresCam2(ctx,49); + ctx.misc[4] = (demoTime-direction[48].startTime)*4+.1-Math.random()*.2; + ctx.misc[2] = 1-context.stepTime / this.time; + } , + lights : [ lightFunc(1,30) ] , + updateText: null + } , { + rows: 40 , + rm: 'squares' , + setGlobals: function(ctx) { + squaresCam2(ctx,49); + ctx.misc[4] = -(demoTime-direction[48].startTime)*6; + } , + lights : [ lightFunc(1,30) ] , + updateText: null + } , { + rows: 40 , + rm: 'squares' , + setGlobals: function(ctx) { + squaresCam2(ctx,49); + ctx.misc[4] = (demoTime-direction[48].startTime)*8; + ctx.misc[3] = 0; + ctx.misc[2] = context.stepTime / this.time; + } , + lights : [ lightFunc(1,30) ] , + updateText: null + } , { + rows: 68 , + rm: 'squares' , + setGlobals: function(ctx) { + squaresCam2(ctx,49); + ctx.misc[2] = 1 + } , + lights : [ lightFunc(1,30) ] , + updateText: null + } +]; +var t = 0; +var BPM = 120; +for ( var i in direction ) { + direction[ i ].startTime = t; + t += ( direction[i].time = direction[ i ].rows * 60 / ( BPM * 4 ) ); + direction[ i ].endTime = t; +} +rows = t * BPM * 4 / 60; +t = 0; + +function createRaymarcherCode( def , nLights ) { + var w = 'uniform '; + var code = shaderHeader + + [ w+'mat3 u0;' , + w+'sampler2D u1;' , + w+'!3 u2,u3;' , + w+'float u4[10];' + ].join('\n'); + var u = 5; + for ( var i in def.lights ) { + code += w+'!3 u' + u++ + ', u' + u++ + ';'+w+'float u' + u++ + ';'; + } + code += [ + "const !2 c=!2(1.,-1.)*"+def.normalDelta+";" , + "float p,z,w,u,o,zy,q,x,a,zz;" , + "!2 e,h;" , + "!3 l=!3(zx,1.),m,r,s=u2,yx=!3(1.),n=!3(.0),b,v,xxx,xy,d,xx,xz,y;" , + "!4 f;" , + + "float g(float x)" , + "{" , + "return fract(sin(x)*43758.5453);" , + "}" , + + "float yy(!3 x)" , + "{" , + "m=floor(x),y=fract(x)," , + "y*=y*(3.-2.*y)," , + "z=m.x+m.y*57.+m.z*113.;" , + "return mix(mix(mix(g(z),g(z+1.),y.x)," , + "mix(g(z+57.),g(z+58.),y.x),y.y)," , + "mix(mix(g(z+113.),g(z+114.),y.x)," , + "mix(g(z+170.),g(z+171.),y.x),y.y),y.z);" , + "}" , + + "float yyx(!2 x,float a)" , + "{" , + "e=pow(abs(x),!2(a));" , + "return pow(e.x+e.y,1./a);" , + "}" , + + "mat2 t(float x)" , + "{" , + "e=!2(cos(x),sin(x));" , + "return mat2(-e.x,e.y,e.y,e.x);" , + "}" , + + "float yz(!3 x)" , + "{" , + "return length(mod(x.xy,!2(15.))-!2(7.5))-.5+.05*sin(x.z*9.42477);" , + "}" , + + "!2 k(!3 x,float a) {" + ].join("\n"); + code += def.map + '}'; + code += [ + "void main()" , + "{" , + "l.y+=mod(u4[4],1.)*2.2;" , + "if(l.y>1.){" , + "if(l.y < 1.2)discard;" , + "l.y-=2.2;" , + "}" , + "l.x*=1.6," , + "r=normalize(l*u0);" , + + "for(int j=0;j<2;j++){" , + "v=r,xxx=s,xy=!3(.0)," , + "x=.0,a=" + def.epsilon + ';' , + "for(int i=0;i<" + def.depth + ";i++){" , + "h=k(s+r*x,x);" , + "if(h.x< a||i>" + def.depth + "/(j+1)||x>" + def.maxDistance + ".)break;" , + "x+=h.x*" + def.step + ",a*=" + shaderFloat( def.epsilonMultiplier ) + ";" , + "}" , + "h.x=x;", + + "if(x<"+ def.maxDistance+ ".){" , + "d=s+r*x," , + "f=!4(" , + "k(d+c.xyy,x).x," , + "k(d+c.yyx,x).x," , + "k(d+c.yxy,x).x," , + "k(d+c.xxx,x).x" , + ")," , + "xx=normalize(f.x*c.xyy+f.y*c.yyx+f.z*c.yxy+f.w*c.xxx)," , + "a=.0," , + "p=" + def.aoWeight + ";" , + "for(int i=1;i<="+def.aoSteps+";i++)" , + "x=(float(i)/"+def.aoSteps+".)*"+ shaderFloat( def.aoDelta ) + "," , + "m=d+xx*x," , + "a+=p*(x-k(m,distance(m,s)).x)," , + "p*=.5;" , + "q=max(.1,1.-clamp(pow(a,1.),.0,1.));" , + ].join('\n'); + + for ( var i in def.materials ) { + if ( i > 0 ) { + code += 'else '; + } + var m = materials[ def.materials[i] ]; + code += 'if(h.y==' + i + '.)' + + 'xz='; + if ( m.noiseScale ) { + code += 'mix(!3(' + shaderVec( m.albedo ) + '),!3(' + + shaderVec( m.noise ) + '),yy(d*' + + shaderFloat( def.noiseScale * m.noiseScale ) + '))'; + } else { + code += '!3(' + shaderVec( m.albedo ) + ')'; + } + code += ',w=' + shaderFloat( m.metallic ) + ',u=' + m.smoothness + ',o=' + m.r0 + ';'; + } + + code += [ + "v=reflect(r,xx)," , + "z="+def.fogDensity+"*h.x," , + "z=clamp(exp(-z*z*z*1.442695),.0,1.)," , + "x=clamp((1.+dot(normalize(v+r),r)),.0,1.),a=x*x," , + "zz=o+(1.-o)*x*a*a*(u*.9+.1)," , + "y=mix(!3(1.),xz/dot(!3(.299,.587,.114),xz),w)," , + "m=!3(.0)," , + "zy=exp2(4.+6.*u)," , + ].join('\n'); + + u = 5; + for ( var l in def.lights ) { + var b = def.lights[l]; + code += [ + "p=length(b=u" + u + "-d)," , + "b/=p," , + "p=max(1.,p-u" + (u+2) + ")*" + b.attenuation + "," , + "p=1./max(1.,p*p)," , + "m+=mix((1.-w)*xz*q,y*pow(max(dot(reflect(r,xx),b),.0),zy)*(zy+2.)/8.,zz)*p*max(dot(b,xx),.0)*u" + (u+1) + "," + ].join('\n'); + u+=3; + } + code += [ + "xy=yx*z*normalize(y)*o*(u*.9+.1)*zz," , + "m=mix(!3(" + shaderFloat(def.fog) + "),m,z)," , + "xxx+=normalize(v)*" + def.reflectionDistance + ";" , + "}else" , + "m=!3(" + shaderFloat(def.fog) + ');' + ].join('\n'); + + u=5; + for ( var l in def.lights ) { + var b = def.lights[l]; + var h = b.vRadius; + if ( h ) { + code += [ + "b=s-u" + u + "," , + "p=dot(r,r),a=2.*dot(b,r)," , + "x=a*a-4.*p*(dot(b,b)-" + (h*h) + ")," , + "e=x<.0?!2(-1.):(x=sqrt(x),-.5*!2(a+x,a-x)/p)," , + "e=!2(min(e.x,e.y),max(e.x,e.y));" , + "if(e.x>.0&&e.y<h.x)" , + "m+=u" + (u+2) + "*u" + (u+1) + "*pow((e.y-e.x)/" + shaderFloat(h*2) + ",64.);" + ].join( "\n" ); + } + u+=3; + } + + code += [ + "n+=m*yx;" , + "if(all(lessThan(xy,!3(.01))))break;" , + "yx=xy," , + "s=xxx," , + "r=normalize(v);" , + "}" , + + "h=!2(zx.x,l.y)*.5+.5," , + "h.y=(1.-h.y-u4[5])/u4[7]," , + "f=texture2D(u1,h)," , + "n=max(!3(.0),mix(mix(mix(n,(n.x==n.y&&n.x==n.z)?n:!3(dot(n,!3(.299,.587,.114))),u4[1]),!3(u4[3]),smoothstep(.05,.95,u4[2])),f.rgb*u3,f.a*u4[6])-!3(.004)),", + + "x=(l.x+1.)*(l.y+1.)*(u4[0]*10.),", + "gl_FragColor=!4((1.-(smoothstep(.98,1.,yy(l*8.+u4[0]*20.))+smoothstep(.95,1.,yy(l*1.5+u4[0]*10.))))*smoothstep(1.042+.008*cos(u4[0]*40.),.8,yyx(zx,8.))*(1.-(mod((mod(x,13.)+1.)*(mod(x,47.)+1.),.01))*8.)*((.95+.05*cos(u4[0]*41.))*(n*(6.2*n+.5))/(n*(6.2*n+!3(1.7))+!3(.06))+!3(smoothstep(.98,1.,yy(l*8.-u4[0]*40.)))),1.);", + "}" , + ].join('\n'); + return [ code , 5+def.lights.length*3 ]; +} + +function buildRaymarchers( ) +{ + var ml = 1; + var sn = 1; + for ( var n in raymarchers ) { + var rm = raymarchers[n]; + var nl = rm.lights.length; + ml=nl>ml?nl:ml; + for ( var i=1;i<=nl;i++) { + var sd = createRaymarcherCode(rm,i); + shaders[sn] = [glCtx.FRAGMENT_SHADER,sd[0]]; + programs[n + '_' + i] = [ sd[1] , 0 , sn++ ]; + } + } + var context = { + camPos: vomNew(3), + lookAt: vomNew(3), + up: vomNew(3), + toNearPlane: 0 , + misc: vomNew(10) , + textColour: vomNew(3) , + lights: [] + }; + for ( var i = 0;i<ml;i++ ) { + context.lights.push({ + pos: vomNew(3), + colour: vomNew(3) , + distance: 0 + }); + } + return context; +} + +var cmU=vomNew(3), + cmV=vomNew(3), + cmW=vomNew(3), + cd=vomNew(3), + cu=vomNew(3), + cm=vomNew(9); +function prepareRaymarcher( ds ) +{ + var rm = raymarchers[ds.rm], ctx = context; + ds.setGlobals( ctx ); + vecNorm(cmW,vecSub(cmW,ctx.lookAt,ctx.camPos)); + vecNorm(cmU,vecCross(cmU,ctx.up,cmW)); + vecNorm(cmV,vecCross(cmV,cmW,cmU)); + vecScale(cmW,cmW,ctx.toNearPlane); + vecs2Mat3(cm,cmU,cmV,cmW); + + var active = []; + for ( var i in ds.lights ) { + if ( ds.lights[i] && ds.lights[ i ](ctx,ctx.lights[ i ]) ) { + active.push( ctx.lights[ i ] ); + } + } + + var p = programs[ds.rm + '_' + active.length ]; + glCtx.useProgram( p[ 0 ] ); + glCtx.enableVertexAttribArray( 0 ); + glCtx.vertexAttribPointer( 0 , 2 , glCtx.FLOAT , false , 8 , 0 ); + p = p[1]; + + var u = 0; + glCtx.uniformMatrix3fv( p[u++] , false , cm ); + glCtx.uniform1i( p[u++] , 0 ); + glCtx.uniform3fv( p[u++] , ctx.camPos ); + glCtx.uniform3fv( p[u++] , ctx.textColour ); + glCtx.uniform1fv( p[u++] , ctx.misc ); + for ( var i in active ) { + glCtx.uniform3fv( p[u++] , active[ i ].pos ); + glCtx.uniform3fv( p[u++] , active[ i ].colour ); + glCtx.uniform1f( p[u++] , active[ i ].distance ); + } + glCtx.drawArrays( 4 , 0 , 3 ); +} + + +// Main + +function resize() { + var vw=window.innerWidth,vh=window.innerHeight; + var cw=Math.floor(vh*1.6),ch=Math.floor(vw*.625); + if(cw>vw){ + C1.width=canvasWidth=vw; + C1.height=canvasHeight=ch; + }else{ + C1.width=canvasWidth=cw; + C1.height=canvasHeight=vh; + } + C2.style.width=C2.width=canvasWidth; + c2height=C2.style.height=C2.height=Math.max(canvasHeight/8,100); + c2rHeight=c2height/canvasHeight; + twoDCtx.shadowColor = "#ccc"; + twoDCtx.font = "normal small-caps bold " + Math.floor(c2height/2) + "px monospace"; + twoDCtx.fillStyle = "#111"; + twoDCtx.strokeStyle = "#ddd"; + C1.style.left=Math.floor((vw-canvasWidth)*.5); + C1.style.top=Math.floor((vh-canvasHeight)*.5); + glCtx.viewport(0,0,canvasWidth,canvasHeight); +} + +// FIXME: re-enable! document.body.style.cursor = 'none'; +document.body.style.background = 'black'; +document.body.innerHTML = '<canvas id=C1 style=position:fixed></canvas><canvas id=C2 style=display:none>'; +glCtx=C1.getContext('webgl'); +twoDCtx = C2.getContext('2d'); +(window.onresize=resize)(); +var shaders = [ + [ glCtx.VERTEX_SHADER , shaderHeader + "attribute !2 i;void main(){gl_Position=!4(i,.0,1.),zx=i;}" + ] +]; +var programs = {}; +var context = buildRaymarchers( ); +for ( var i in shaders ) { + var def = shaders[i]; + glCtx.shaderSource( i= shaders[i] = glCtx.createShader( def[0] ) , def[1].replace(/!/g,'vec') ); + glCtx.compileShader( i ); + if (!glCtx.getShaderParameter(i, glCtx.COMPILE_STATUS)) { + def[1] = def[1].split( /\n/ ); + for ( var k in def[1] ) { + var j = parseInt(k)+1; + def[1][k] = j + ": " + def[1][k]; + } + throw "SHADER ERROR\n" + glCtx.getShaderInfoLog(i) + "\n" + def[1].join('\n'); + } +} +for ( var name in programs ) { + var p = glCtx.createProgram( ); + var d = programs[name]; + var ul = d.shift(); + while( d.length ) { + glCtx.attachShader( p , shaders[ d.shift() ] ); + } + glCtx.linkProgram( p ); + var nul = []; + while ( ul-- ) { + nul[ul] = glCtx.getUniformLocation( p , 'u' + ul ); + } + programs[name] = [p,nul]; +} +vtxBuffer = glCtx.createBuffer( ); +glCtx.bindBuffer( glCtx.ARRAY_BUFFER , glCtx.createBuffer( ) ); +glCtx.bufferData( glCtx.ARRAY_BUFFER , vomNew([1,4,1,-1,-4,-1]) , glCtx.STATIC_DRAW ); +glCtx.clearColor(0,0,0,1); + +textTexture = glCtx.createTexture( ); +glCtx.bindTexture( glCtx.TEXTURE_2D , textTexture ); +glCtx.texParameteri( glCtx.TEXTURE_2D , glCtx.TEXTURE_WRAP_S, glCtx.CLAMP_TO_EDGE ); +glCtx.texParameteri( glCtx.TEXTURE_2D , glCtx.TEXTURE_WRAP_T, glCtx.CLAMP_TO_EDGE ); +glCtx.texParameteri( glCtx.TEXTURE_2D , glCtx.TEXTURE_MIN_FILTER, glCtx.NEAREST ); +glCtx.texParameteri( glCtx.TEXTURE_2D , glCtx.TEXTURE_MAG_FILTER, glCtx.NEAREST ); +glCtx.texImage2D( glCtx.TEXTURE_2D , 0 , glCtx.RGBA , glCtx.RGBA , glCtx.UNSIGNED_BYTE , C2 ); + +timeStart = previousFrame = 0; +FRAME_TIME = 100/3; + +paused = 0; +document.body.onkeypress = function(e) { + if ( e.keyCode == 32 ) { + var now = Date.now(); + if ( paused ) { + timeStart += now - paused; + paused = 0; + requestAnimationFrame(draw); + A.play( ); + } else { + paused = now; + A.pause( ); + } + } +}; + +var demoTime; +mainfunc = function(){ +requestAnimationFrame(draw=function(time){ + if ( ! paused ) { + requestAnimationFrame(draw); + } + if ( timeStart == 0 ) { + A.play( ); + timeStart = time; + previousFrame = timeStart - FRAME_TIME; + } + var delta = time - previousFrame; + demoTime = .001*(time - timeStart); + if ( delta < FRAME_TIME ) { + return; + } + previousFrame = time - ( delta % FRAME_TIME ); + + var ds = direction[t]; + while ( ds && ds.endTime < demoTime ) { + ds=direction[++t]; + } + if ( ! ds ) { + A.pause( ); + return; + } + context.misc[0] = demoTime; + context.misc[7] = c2rHeight; + context.stepTime = demoTime - ds.startTime; + if ( ds.updateText ) { + twoDCtx.clearRect( 0 , 0 , canvasWidth , 100 ); + ds.updateText(); + glCtx.texImage2D( glCtx.TEXTURE_2D , 0 , glCtx.RGBA , glCtx.RGBA , glCtx.UNSIGNED_BYTE , C2 ); + } + prepareRaymarcher( ds ); +}) +} + +if ( USE_SYNTH ) { + synth = new CPlayer(); + synth.init(song); + synthGen = setInterval(function(){ + if ( synth.generate() == 1 ) { + clearInterval(synthGen); + var s = '' , a = synth.createWave(); + for(var i=0;i<a.length;i++) + s+= String.fromCharCode(a[i]); + A = document.createElement("audio"); + A.src= 'data:audio/wav;base64,' + btoa(s); + A.oncanplaythrough=mainfunc; + } + + }, 0); +} else { + A = document.createElement("audio"); + A.oncanplaythrough=mainfunc; + A.src= 'music.ogg'; +} diff --git a/201410_-_Sine_City/sine-city-packing-2-raymarchers.html b/201410_-_Sine_City/sine-city-packing-2-raymarchers.html new file mode 100644 index 0000000..1f73a54 --- /dev/null +++ b/201410_-_Sine_City/sine-city-packing-2-raymarchers.html @@ -0,0 +1,5 @@ +<body> +<script language="javascript" src="music.js"></script> +<script language="javascript" src="player-small.js"></script> +<script language="javascript" src="sine-city-packing-2-raymarchers.js"></script> + diff --git a/201410_-_Sine_City/sine-city-packing-2-raymarchers.js b/201410_-_Sine_City/sine-city-packing-2-raymarchers.js new file mode 100644 index 0000000..7496515 --- /dev/null +++ b/201410_-_Sine_City/sine-city-packing-2-raymarchers.js @@ -0,0 +1,1123 @@ +var USE_SYNTH = 1; + +// Vector stuff +function vecOp(code) { + return eval('(function(o,a,b){for(var i=o.length;--i>=0;)' + code + ';return o})') +} +function vomNew(s) { + return new Float32Array(s) +} +var vecDot = function(a,b) { + var s = 0; + for ( var i in a ) { + s += a[i]*b[i]; + } + return s; +}; +var vecLen = function(a) { + return Math.sqrt( vecDot(a,a) ) +}; +var vecNorm = function(o,a) { + var l = vecLen(a); + return l ? vecScale(o,a,1/l) : vecCopy(o,a); +}; +var vecCross = function(o,a,b) { + return vecSet(o, + a[1]*b[2]-a[2]*b[1] , + a[2]*b[0]-a[0]*b[2] , + a[0]*b[1]-a[1]*b[0] + ); +}; +var vecs2Mat3 = function(o,a,b,c){ + for ( var i = 0 ; i < 3 ; i ++ ) { + o[i*3+0] = a[i]; + o[i*3+1] = b[i]; + o[i*3+2] = c[i]; + } +}; +var vecSet = vecOp('o[i]=arguments[i+1]') , + vecCopy = vecOp('o[i]=a[i]') , + vecAdd = vecOp('o[i]=a[i]+b[i]') , + vecSub = vecOp('o[i]=a[i]-b[i]') , + vecScale = vecOp('o[i]=a[i]*b'); + + +// Shaders +var shaderHeader = 'precision highp float;varying !2 zx;'; + + +function shaderFloat( v ) { + return '' + v + ( v == Math.floor(v) ? '.' : '' ); +} +function shaderVec( v ) { + return v.map(shaderFloat).join(','); +} + + +// Raymarchers + +var materials = [[[.05],.7,.02,.01],[[.2],.7,.9,.01,5,[.1]],[[1],.5,.4,.02],[[3,0,0],.3,.1,.6,6,[.6,0,0]],[[0,2,0],.9,.5,.4,15,[0,.2,0]],[[3,1.5,0],.95,.6,.9,.3,[.3,.6,0]],[[.1],0,.04,.002,3,[3]],[[0,1.5,2],.9,.3,.4]]; +var raymarchers = [[100,.025,1,.7,64,.0005,.5,.3,.4,.015,4,2,.75,[0,1,2,3],'y=x+.1*(sin(x.zxy*.17+u4[0]*.5)+sin(x.yzx*.7+u4[0]*1.5))*8.5*(1.+cos(sin(x.z*.1)+x.z*.3)),z=14.-length(y.xy),w=x.x==.0?1.570795*(x.y>.0?1.:-1.):atan(x.y,x.x),q=8.35-u4[8]*1.35,y=!3(9.*(mod(w+x.z*.02,.628)-.314),length(x.xy)-9.,mod(x.z,12.56)-6.28),u=min(length(y.xy)-.25+.1*cos(x.z*8.+u4[0]*.1),length(y.yz)-.5),y=!3(q*(mod(w+x.z*.02,1.256636)-.628318),y.y+9.-q,mod(x.z,62.8318)-31.4159),o=step(u,z)+1.,z=min(u,z),u=length(y)-1.3;if(u<z)z=u,o=3.;y.y+=q-9.,u=yyx(y.yz,8.)-2.;if(u<z)z=u,o=.0;return !2(z,o);',[[.25,0],[.5,.5]]],[6,.00025,1.08,.7,100,.000008,10,.03,2.1,.2,6,.4,5.1,[0,2,5],'z=1.,y=x;for(int i=0;i<7;i++)x=2.*clamp(x,-!3(.58,.9,1.1),!3(.58,.9,1.1))-x,w=max((1.3+u4[9]*.1*cos(u4[0]*.5))/dot(x,x),1.),x*=w,z*=w;w=length(x.xy),e=!2(w-3.,-w*x.z/length(x)-2.*log(1.+.01*a))/abs(z),w=max(e.x,e.y),o=step(e.y,e.x),y+=!3(.1,.3,-.4)*u0-u2+.25*sin(x*1.),e.x=length(y)-.1*u4[8];if(e.x<w)w=e.x,o=2.;return !2(w,o);',[[.05]]],[100,.000025,1,.75,80,.00005,.5,.3,3,.01,4,.75,4.75,[6,0,4],'x.xy*=t(a*.009),w=min(min(yz(x.xzy),yz(x)),yz(x.yzx)),y=mod(x,!3(15.))-!3(7.5),o=step(z=max(length(max(abs(y)-!3(2.5),!3(.0)))-.25,3.5-length(y)),w),w=min(w,z),z=length(y+.1*sin(y*5.5+u4[0]))-2.;if(z<w)w=z,o=2.;return !2(w,o);',[[.05]]],[20,.0005,1,.6,128,.0001,.5,.002,.01,.08,4,.5,1.75,[2,7],'y=x,y.xz=mod(x.xz,8.)-4.,y.yz*=t(u4[8]+.1*a),y.xy*=t(u4[8]*.5+.2*a),y.y*=.9+.1*sin(u4[8]*5.),w=max(length(y)-3.,-min(length(y)-2.8,max(mod(y.y,.8)-.4,-mod(y.y+.4,.8)+.4))),z=x.y+1.+sin(x.x*4.+u4[8]*2.)*sin(x.z+u4[8])*.1,o=clamp(.5+.5*(z-w)/1.,.0,1.),w=mix(z,w,o)-1.*o*(1.-o),y=x,y.xz=mod(y.xz,8.)-4.,y/=1.25+.25*sin(u4[8]*5.),y.xy*=t(u4[8]*5.),y.yz*=t(u4[8]*2.5),z=max(length(y)-1.,.04-length(max(abs(mod(y,.5)-.25)-!3(.15),!3(.0))));return !2(min(w,z),step(z,w));',[[.02],[.05,.5],[.05,.5]]]]; + +var lightFunc = function(intensity,distance) { + return function(ctx,lctx) { + vecCopy(lctx[0],ctx.camPos); + vecSet(lctx[1],intensity,intensity,intensity); + lctx[2] = distance; + } +}; +var tun1CamCommon = function(ctx,dir) { + var z = demoTime*6; + vecSet(ctx.camPos,-6,0,z); + vecSet(ctx.lookAt,1,0,z); + vecSet(ctx.up,0,1,0); + ctx.misc[1] = 1; + ctx.misc[8] = 0; + return ctx.stepTime / dir.time; +}; +var desyncFunc = function(desync) { + return function(ctx,tt) { + var z = ctx.stepTime / tt; + ctx.misc[4] = -z * desync; + if ( desync > 0 ) { + ctx.misc[4] += desync; + } + ctx.misc[4] *= Math.random( ) * .25 + .75; + }; +}; +var balls1CamFunc = function(lax,laz,desync) { + var dsf = desyncFunc(desync); + return function(ctx) { + var z = demoTime*3; + vecSet(ctx.camPos,0,4,z); + vecSet(ctx.lookAt,lax,0,z+laz); + vecSet(ctx.up,0,0,1); + ctx.misc[8]= ctx.misc[2] = 0; + dsf(ctx,this.time); + }; +}; +var balls2CamCommon = function(ctx) { + var z = demoTime*5; + vecSet(ctx.camPos,Math.cos(demoTime)*12,8,Math.sin(demoTime)*12+z); + vecSet(ctx.lookAt,1,0,z); + vecSet(ctx.up,0,1,0); + ctx.toNearPlane = 2.5; + z = demoTime - direction[43].startTime; + ctx.misc[8]=z; +}; +var balls2LightFunc = function(scale) { + return function(ctx,lctx) { + var z = demoTime*30; + vecSet(lctx[0],scale*Math.cos(demoTime*2)*5,3,scale*Math.sin(demoTime*2)*5+z); + vecSet(lctx[1],1,1,1); + lctx[2] = 4; + }; +}; +var fract1CamCommon = function(ctx) { + var z = demoTime; + vecSet(ctx.camPos,4,2.5+.025*z,6.7); + vecSet(ctx.lookAt,0,2.5-.05*z,6.7); + vecSet(ctx.up,0,0,1); + ctx.misc[8] = ctx.misc[9] = 0; + ctx.toNearPlane = 3; +}; +var fract1CamFunc = function(desync) { + var dsf = desyncFunc(desync); + return function(ctx){ + fract1CamCommon(ctx); + dsf(ctx,this.time); + }; +}; +var fract2CamCommon = function(ctx,bs) { + vecSet(ctx.camPos,5*Math.sin(demoTime*.2),9*Math.cos(demoTime*.41),7.8); + vecCopy(ctx.lookAt,ctx.camPos); + ctx.lookAt[0] = Math.cos(demoTime*.2); + ctx.lookAt[1] = Math.sin(demoTime*.33); + ctx.lookAt[2] -= 2; + vecSet(ctx.up,0,0,1); + ctx.toNearPlane = 3; + ctx.misc[8] = bs; + ctx.misc[9] = 1; +}; + +var drawText = function(str,x) { + twoDCtx.shadowBlur = c2height/5; + twoDCtx.fillText( str , x , c2height / 2 ); + twoDCtx.shadowBlur = 0; + twoDCtx.strokeText( str , x , c2height / 2 ); +}; +var titleText = function(str,shake,alpha,r,g,b) { + drawText( str , canvasWidth/15 ); + context.misc[5] = 1 - c2rHeight + Math.random() * shake - shake * .5; + context.misc[6] = alpha; + vecSet( context.textColour , r , g , b ); +}; +var greetings = "Greetings to ... Mog, Sycop, Tim & Wullon ... Adinpsz ... Alcatraz ... ASD ... Bits'n'Bites ... Brain Control ... Cocoon ... Conspiracy ... Ctrl+Alt+Test ... Fairlight ... Farbrausch ... Kewlers ... LNX ... Loonies ... Mercury ... Popsy Team ... Razor 1911 ... RGBA ... 7th Cube ... Still ... TPOLM ... TRBL ... Umlaut Design ... X-Men ... Youth Uprising ... Everyone here at DemoJS 2014!"; +var greetingsText = function() { + var t = ( demoTime - direction[34].startTime ) * canvasWidth * .5; + drawText( greetings , canvasWidth - t ); + context.misc[5] = 1 - c2rHeight + Math.random() * .02 - .01; + context.misc[6] = 1; + vecSet( context.textColour , 1 , 1 , 1 ); +}; + +var squaresCam = function(ctx) { + var t = demoTime - direction[25].startTime; + var z = t*10 - 80; + vecSet(ctx.camPos,z,0,0); + vecSet(ctx.lookAt,z+Math.cos(t*.5) * 80,Math.sin(t*.25)*40,100); + vecSet(ctx.up,0,1,0); +}; + +var squaresCam2 = function(ctx,s) { + var t = demoTime - direction[s].startTime; + var z = t*20 - 80; + vecSet(ctx.camPos,0,0,z); + vecSet(ctx.lookAt,Math.cos(t*.5) * 80,Math.sin(t*.25)*40,z+100); + vecSet(ctx.up,Math.sin(t),Math.cos(t),0); + ctx.misc[4] = Math.random() * .025 - .0125; +}; + +var tunnelLight = function(ctx,lctx) { + vecAdd(lctx[0],vecNorm(lctx[0],vecScale(lctx[0],ctx.lookAt,-1)),ctx.camPos); + lctx[0][1] -= .5; + vecSet(lctx[1],3,3,3); + lctx[2] = 30; +}; +var tunnelCam = function(ctx,mul) { + var z = demoTime*30*ctx.tunMul; + vecSet(ctx.camPos,1.1*Math.cos(z*.1),Math.sin(z*.02),z); + z += 5; + vecSet(ctx.lookAt,-Math.sin(z*.05),-.7*Math.cos(z*.033),z); + vecSet(ctx.up,0,1,0); + ctx.toNearPlane = 2; +}; +var tunnelLightBall = function(ctx,lctx) { + vecSet(lctx[0] , 4*Math.sin(demoTime*.5)*Math.cos(demoTime*.7) , + 3*Math.cos(demoTime*1.5), + demoTime*30*ctx.tunMul+14+16*Math.sin(demoTime*3.3)*Math.cos(demoTime*.77) + ); + vecSet(lctx[1],1,1,1); + lctx[2] = 15; +}; + +var direction = [ + { + // Music rows + rows: 36 , + // Raymarcher id + rm: 0 , + setGlobals: function( ctx ) { + var z = tun1CamCommon(ctx,this); + z *= z*z; + ctx.misc[2] = 1 - z; + ctx.toNearPlane = 5; + } , + lights: [ + lightFunc(3,20) + ] , + updateText: null + } , { + rows: 18 , + rm: 0 , + setGlobals: function( ctx ) { + var z = tun1CamCommon(ctx,this); + ctx.toNearPlane = 5 - 2.25 * z; + ctx.misc[2] = 0; + } , + lights: [ + lightFunc(3,20) + ] , + updateText: null + } , { + rows: 36 , + rm: 0 , + setGlobals: function( ctx ) { + var z = tun1CamCommon(ctx,this); + ctx.toNearPlane = 2.75 - 2.25 * z; + ctx.misc[2] = z; + } , + lights: [ + lightFunc(3,20) + ] , + updateText: null + } , { + rows: 18 , + rm: 3 , + setGlobals: function( ctx ) { + var z = demoTime*3; + vecSet(ctx.camPos,0,4,z); + vecSet(ctx.lookAt,4,0,z); + vecSet(ctx.up,0,0,1); + z = ctx.stepTime / this.time; + z *= z*z; + ctx.misc[2] = 1 - z; + ctx.toNearPlane = 2.5; + } , + lights: [ + lightFunc(.75,8) + ] , + updateText: null + } , { + rows: 22 , + rm: 3 , + setGlobals: balls1CamFunc(4,0,0) , + lights: [ + lightFunc(1,8) + ] , + updateText: null + } , { + rows: 22 , + rm: 3 , + setGlobals: balls1CamFunc(2,-2,0) , + lights: [ + lightFunc(1,8) + ] , + updateText: null + } , { + rows: 3 , + rm: 3 , + setGlobals: balls1CamFunc( 6 , 0 , -.5 ) , + lights: [ + lightFunc(.5,4) + ] , + updateText: null + } , { + rows: 9 , + rm: 3 , + setGlobals: balls1CamFunc( 6 , 0 , .5 ) , + lights: [ + lightFunc(.5,4) + ] , + updateText: null + } , { + rows: 3 , + rm: 3 , + setGlobals: balls1CamFunc( 2 , 2 , -.2 ) , + lights: [ + lightFunc(1,8) + ] , + updateText: null + } , { + rows: 9 , + rm: 3 , + setGlobals: balls1CamFunc( 2 , 2 , .2 ) , + lights: [ + lightFunc(1,8) + ] , + updateText: null + } , { + rows: 3 , + rm: 3 , + setGlobals: balls1CamFunc( 2 , 5 , -.7 ) , + lights: [ + lightFunc(1,2) + ] , + updateText: null + } , { + rows: 7 , + rm: 3 , + setGlobals: balls1CamFunc( 2 , 2 , .7 ) , + lights: [ + lightFunc(1,2) + ] , + updateText: null + } , { + rows: 9 , + rm: 3 , + setGlobals: function(ctx) { + var z = demoTime*3; + ctx.misc[2] = ctx.stepTime / this.time; + vecSet(ctx.camPos,0,4+ctx.misc[2]*2,z); + vecSet(ctx.lookAt,2,0,z+2); + vecSet(ctx.up,0,0,1); + ctx.misc[3] = 1; + } , + lights: [ + lightFunc(1,2) + ] , + updateText: null + } , { + rows: 21 , + rm: 1 , + setGlobals: function( ctx ) { + fract1CamCommon(ctx); + ctx.misc[3] = 1; + var z = ctx.stepTime / this.time; + ctx.misc[2] = 1 - z*z*z; + } , lights : [ + fractLight = function(ctx,lctx) { + vecCopy(lctx[0],ctx.camPos); + lctx[0][2]+=2; + vecSet(lctx[1],1,1,1); + lctx[2] = 3; + } + ], + updateText: null + } , { + rows: 14 , + rm: 1 , + setGlobals: fract1CamFunc(0) , + lights : [ + fractLight + ], + updateText: null + } , { + rows: 3 , + rm: 1 , + setGlobals: fract1CamFunc(-.4) , + lights : [ fractLight ], + updateText: null + } , { + rows: 9 , + rm: 1 , + setGlobals: fract1CamFunc(.4) , + lights : [ fractLight ], + updateText: null + } , { + rows: 3 , + rm: 1 , + setGlobals: fract1CamFunc(-.2) , + lights : [ fractLight ], + updateText: null + } , { + rows: 9 , + rm: 1 , + setGlobals: fract1CamFunc(.2) , + lights : [ fractLight ], + updateText: null + } , { + rows: 12 , + rm: 1 , + setGlobals: function(ctx) { + fract1CamCommon(ctx); + ctx.misc[4] = -( 6 * ctx.stepTime / this.time ) % 1; + ctx.misc[4] *= Math.random( ) * .25 + .75; + } , + lights : [ fractLight ], + updateText: null + } , { + rows: 22 , + rm: 1 , + setGlobals: function(ctx) { + fract1CamCommon(ctx); + ctx.misc[3] = .4; + ctx.misc[2] = ctx.stepTime / this.time; + ctx.toNearPlane = 3 - 2.5*Math.max(1,2*ctx.misc[2]); + ctx.misc[4] = ( 30 * ctx.misc[2] ) % 1; + ctx.misc[4] *= Math.random( ) * .15 + .85; + } , + lights : [ fractLight ], + updateText: null + } , { + rows: 3 , + rm: 1 , + setGlobals: neutral = function(ctx) { + fract1CamCommon(ctx); + ctx.misc[3] = .4; + ctx.misc[2] = 1; + ctx.misc[4] = 0; + } , + lights : [ fractLight ], + updateText: null + } , { + rows: 12 , + rm: 1 , + setGlobals: neutral , + lights : [ fractLight ], + updateText: function() { + titleText( "TheT(ourist)" , .08 , 1 , 1 , 1 , 1 ); + } + } , { + rows: 12 , + rm: 1 , + setGlobals: neutral , + lights : [ fractLight ], + updateText: function() { + titleText( "TheT(ourist)" , .08 , 1 - context.stepTime / this.time , 1 , 1 , 1 ); + } + } , { + rows: 12 , + rm: 1 , + setGlobals: neutral , + lights : [ fractLight ], + updateText: function() { + titleText( "presents" , .08 , 1 - context.stepTime / this.time , 1 , 1 , 1 ); + } + } , { + rows: 20 , + rm: 2 , + setGlobals: function(ctx) { + squaresCam(ctx); + ctx.toNearPlane = 2.5; + ctx.misc[2] = 1 - ctx.stepTime / this.time; + } , + lights : [ lightFunc(1,30) ], + updateText: function() { + titleText( "Sine City" , .04 , context.stepTime / this.time , 1 , 1 , 1 ); + } + } , { + rows: 52 , + rm: 2 , + setGlobals: function(ctx) { + squaresCam(ctx); + ctx.misc[2] = 0; + } , + lights : [ lightFunc(1,30) ], + updateText: function() { + titleText( "Sine City" , .04 , 1 , 1 , 1 , 1 ); + } + } , { + rows: 12 , + rm: 2 , + setGlobals: function(ctx){ + squaresCam(ctx); + var z = context.stepTime / this.time; + ctx.misc[3] = 1; + ctx.misc[2] = Math.max(0,1-z*2); + } , + lights : [ lightFunc(1,30) ], + updateText: function() { + var z = context.stepTime / this.time; + titleText( "Sine City" , .04 , 1 , 1 - z , 1 - z * .5 , 1 - z ); + } + } , { + rows: 12 , + rm: 2 , + setGlobals: function(ctx) { + squaresCam(ctx); + var z = context.stepTime / this.time; + ctx.misc[4] = ( 1 - z ) * .7 + Math.random() * .025 - .0125; + ctx.misc[1] = 1 - .5 * z; + } , + lights : [ lightFunc(1,30) ], + updateText: function() { + titleText( "Sine City" , .04 , 1 , 0 , .5 , 0 ); + } + } , { + rows: 9 , + rm: 2 , + setGlobals: function(ctx) { + squaresCam2(ctx,29); + var z = context.stepTime / this.time; + ctx.misc[2] = Math.max(0,1-z*1.5); + ctx.misc[4] += ( z - 1 ) * .3; + ctx.misc[1] = .5 - .5 * z; + } , + lights : [ lightFunc(1,30) ], + updateText: function() { + titleText( "Sine City" , .04 , 1 - context.stepTime / this.time , 0 , .5 , 0 ); + } + } , { + rows: 69 , + rm: 2 , + setGlobals: function(ctx) { + squaresCam2(ctx,29); + ctx.misc[1] = 0; + } , + lights : [ lightFunc(1,30) ], + updateText: null + } , { + rows: 11 , + rm: 2 , + setGlobals: function(ctx) { + squaresCam2(ctx,29); + ctx.misc[3] = .2; + ctx.misc[2] = context.stepTime / this.time; + } , + lights : [ lightFunc(1,30) ], + updateText: null + } , { + rows: 11 , + rm: 0 , + setGlobals: function(ctx) { + ctx.tunMul = 1; + tunnelCam(ctx); + ctx.misc[2] = 1 - context.stepTime / this.time; + } , + lights : [ tunnelLight ], + updateText: null + } , { + rows: 17 , + rm: 0 , + setGlobals: function(ctx) { + tunnelCam(ctx); + ctx.misc[2] = 0; + ctx.misc[4] = (1.2 - 1.2 * context.stepTime / this.time) * (.98 + .04*Math.random()); + } , + lights : [ tunnelLight ], + updateText: null + } , { + rows: 18 , + rm: 0 , + setGlobals: function(ctx) { + tunnelCam(ctx); + ctx.misc[4] = 0; + ctx.misc[8] = context.stepTime / this.time; + } , + lights : [ tunnelLight ], + updateText: greetingsText + } , { + rows: 36 , + rm: 0 , + setGlobals: function(ctx) { + tunnelCam(ctx); + ctx.misc[2] = 1 - Math.min(4*context.stepTime / this.time,1); + ctx.misc[8] = 1; + } , + lights : tunLights = [ tunnelLight , tunnelLightBall ], + updateText: greetingsText + } , { + rows: 33 , + rm: 0 , + setGlobals: function(ctx) { + tunnelCam(ctx); + ctx.misc[2] = context.stepTime / this.time; + ctx.misc[3] = .7; + ctx.misc[4] = -((4*ctx.misc[2])%1)*(.95+Math.random()*.1); + } , + lights : tunLights , + updateText: greetingsText + } , { + rows: 9 , + rm: 1 , + setGlobals: function(ctx) { + fract2CamCommon(ctx,0); + ctx.misc[2] = context.stepTime / this.time; + ctx.misc[3] = 1; + } , + lights : [ fractLight ], + updateText: greetingsText + } , { + rows: 20 , + rm: 1 , + setGlobals: function(ctx) { + fract2CamCommon(ctx,context.stepTime / this.time); + ctx.misc[2] = 0; + } , + lights : [ fractLight ], + updateText: greetingsText + } , { + rows: 31 , + rm: 1 , + setGlobals: function(ctx) { + fract2CamCommon(ctx,1); + ctx.misc[2] = Math.min(0,1-5*context.stepTime / this.time); + } , + lights : [ fractLight ], + updateText: greetingsText + } , { + rows: 5 , + rm: 1 , + setGlobals: function(ctx) { + fract2CamCommon(ctx,1); + ctx.misc[2] = 1-context.stepTime / this.time; + } , + lights : [ fractLight ], + updateText: greetingsText + } , { + rows: 18 , + rm: 1 , + setGlobals: function(ctx) { + fract2CamCommon(ctx,1); + ctx.misc[2] = Math.min(0,1-5*context.stepTime / this.time); + ctx.misc[4] = Math.max(0,1.6*context.stepTime / this.time - .8 )*(.95+Math.random()*.1); + } , + lights : [ fractLight ], + updateText: greetingsText + } , { + rows: 12 , + rm: 1 , + setGlobals: function(ctx) { + fract2CamCommon(ctx,1); + ctx.misc[3] = .1; + ctx.misc[2] = context.stepTime / this.time; + ctx.misc[4] = .8*(1-ctx.misc[2])*(.9+Math.random()*.2); + } , + lights : [ fractLight ], + updateText: greetingsText + } , { + rows: 22 , + rm: 3 , + setGlobals: function(ctx) { + balls2CamCommon(ctx); + ctx.misc[2] = 1-context.stepTime / this.time; + ctx.misc[4] = 0; + } , + lights : ballsLights = [ lightFunc(.6,30) , balls2LightFunc(1),balls2LightFunc(-1) ], + updateText: greetingsText + } , { + rows: 59 , + rm: 3 , + setGlobals: function(ctx) { + balls2CamCommon(ctx); + ctx.misc[3] = .8; + ctx.misc[2] = Math.max(0,1-(12*context.stepTime / this.time)%4); + } , + lights : ballsLights, + updateText: greetingsText + } , { + rows: 8 , + rm: 3 , + setGlobals: function(ctx) { + balls2CamCommon(ctx); + ctx.misc[3] = .1; + ctx.misc[2] = context.stepTime / this.time; + ctx.misc[4] = .1-Math.random()*.2; + } , + lights : ballsLights, + updateText: null + } , { + rows: 7 , + rm: 0 , + setGlobals: function(ctx) { + ctx.tunMul = 2; + tunnelCam(ctx); + ctx.misc[2] = 1-context.stepTime / this.time; + ctx.misc[4] = .1-Math.random()*.2; + } , + lights : tunLights , + updateText: null + } , { + rows: 22 , + rm: 0 , + setGlobals: function(ctx) { + tunnelCam(ctx); + ctx.misc[4] = .1-Math.random()*.2; + } , + lights : tunLights , + updateText: null + } , { + rows: 10 , + rm: 0 , + setGlobals: function(ctx) { + tunnelCam(ctx); + ctx.misc[4] = context.stepTime*4+.1-Math.random()*.2; + ctx.misc[3] = 1; + ctx.misc[2] = context.stepTime / this.time; + } , + lights : tunLights , + updateText: null + } , { + rows: 10 , + rm: 2 , + setGlobals: function(ctx) { + squaresCam2(ctx,49); + ctx.misc[4] = (demoTime-direction[48].startTime)*4+.1-Math.random()*.2; + ctx.misc[2] = 1-context.stepTime / this.time; + } , + lights : [ lightFunc(1,30) ] , + updateText: null + } , { + rows: 40 , + rm: 2 , + setGlobals: function(ctx) { + squaresCam2(ctx,49); + ctx.misc[4] = -(demoTime-direction[48].startTime)*6; + } , + lights : [ lightFunc(1,30) ] , + updateText: null + } , { + rows: 40 , + rm: 2 , + setGlobals: function(ctx) { + squaresCam2(ctx,49); + ctx.misc[4] = (demoTime-direction[48].startTime)*8; + ctx.misc[3] = 0; + ctx.misc[2] = context.stepTime / this.time; + } , + lights : [ lightFunc(1,30) ] , + updateText: null + } , { + rows: 68 , + rm: 2 , + setGlobals: function(ctx) { + squaresCam2(ctx,49); + ctx.misc[2] = 1 + } , + lights : [ lightFunc(1,30) ] , + updateText: null + } +]; +var t = 0; +var BPM = 120; +for ( var i in direction ) { + direction[ i ].startTime = t; + t += ( direction[i].time = direction[ i ].rows * 60 / ( BPM * 4 ) ); + direction[ i ].endTime = t; +} +rows = t * BPM * 4 / 60; +t = 0; + +function createRaymarcherCode( def ) { + var w = 'uniform '; + var code = shaderHeader + + [ w+'mat3 u0;' , + w+'sampler2D u1;' , + w+'!3 u2,u3;' , + w+'float u4[10];' + ].join('\n'); + var u = 5; + for ( var i in def[15] ) { + code += w+'!3 u' + u++ + ', u' + u++ + ';'+w+'float u' + u++ + ';'; + } + code += [ + "const !2 c=!2(1.,-1.)*"+def[5]+";" , + "float p,z,w,u,o,zy,q,x,a,zz;" , + "!2 e,h;" , + "!3 l=!3(zx,1.),m,r,s=u2,yx=!3(1.),n=!3(.0),b,v,xxx,xy,d,xx,xz,y;" , + "!4 f;" , + + "float g(float x)" , + "{" , + "return fract(sin(x)*43758.5453);" , + "}" , + + "float yy(!3 x)" , + "{" , + "m=floor(x),y=fract(x)," , + "y*=y*(3.-2.*y)," , + "z=m.x+m.y*57.+m.z*113.;" , + "return mix(mix(mix(g(z),g(z+1.),y.x)," , + "mix(g(z+57.),g(z+58.),y.x),y.y)," , + "mix(mix(g(z+113.),g(z+114.),y.x)," , + "mix(g(z+170.),g(z+171.),y.x),y.y),y.z);" , + "}" , + + "float yyx(!2 x,float a)" , + "{" , + "e=pow(abs(x),!2(a));" , + "return pow(e.x+e.y,1./a);" , + "}" , + + "mat2 t(float x)" , + "{" , + "e=!2(cos(x),sin(x));" , + "return mat2(-e.x,e.y,e.y,e.x);" , + "}" , + + "float yz(!3 x)" , + "{" , + "return length(mod(x.xy,!2(15.))-!2(7.5))-.5+.05*sin(x.z*9.42477);" , + "}" , + + "!2 k(!3 x,float a) {" + ].join("\n"); + code += def[14] + '}'; + code += [ + "void main()" , + "{" , + "l.y+=mod(u4[4],1.)*2.2;" , + "if(l.y>1.){" , + "if(l.y < 1.2)discard;" , + "l.y-=2.2;" , + "}" , + "l.x*=1.6," , + "r=normalize(l*u0);" , + + "for(int j=0;j<2;j++){" , + "v=r,xxx=s,xy=!3(.0)," , + "x=.0,a=" + def[1] + ';' , + "for(int i=0;i<" + def[4] + ";i++){" , + "h=k(s+r*x,x);" , + "if(h.x< a||i>" + def[4] + "/(j+1)||x>" + def[0] + ".)break;" , + "x+=h.x*" + def[3] + ",a*=" + shaderFloat( def[2] ) + ";" , + "}" , + "h.x=x;", + + "if(x<"+ def[0]+ ".){" , + "d=s+r*x," , + "f=!4(" , + "k(d+c.xyy,x).x," , + "k(d+c.yyx,x).x," , + "k(d+c.yxy,x).x," , + "k(d+c.xxx,x).x" , + ")," , + "xx=normalize(f.x*c.xyy+f.y*c.yyx+f.z*c.yxy+f.w*c.xxx)," , + "a=.0," , + "p=" + def[12] + ";" , + "for(int i=1;i<="+def[10]+";i++)" , + "x=(float(i)/"+def[10]+".)*"+ shaderFloat( def[11] ) + "," , + "m=d+xx*x," , + "a+=p*(x-k(m,distance(m,s)).x)," , + "p*=.5;" , + "q=max(.1,1.-clamp(pow(a,1.),.0,1.));" , + ].join('\n'); + + for(var i in def[13]) + w=materials[def[13][i]],code+=(i>0?'else ':'')+'if(h.y==' + i + '.)xz='+(w[4]?('mix(!3('+shaderVec(w[0])+'),!3('+shaderVec(w[5])+'),yy(d*'+shaderFloat(def[6]*w[4])+'))'):('!3('+shaderVec(w[0])+')'))+',w='+shaderFloat(w[1])+',u='+w[2]+',o='+w[3]+';'; + + code += [ + "v=reflect(r,xx)," , + "z="+def[9]+"*h.x," , + "z=clamp(exp(-z*z*z*1.442695),.0,1.)," , + "x=clamp((1.+dot(normalize(v+r),r)),.0,1.),a=x*x," , + "zz=o+(1.-o)*x*a*a*(u*.9+.1)," , + "y=mix(!3(1.),xz/dot(!3(.299,.587,.114),xz),w)," , + "m=!3(.0)," , + "zy=exp2(4.+6.*u)," , + ].join('\n'); + + u = 5; + for ( var l in def[15] ) { + var b = def[15][l]; + code += [ + "p=length(b=u" + u + "-d)," , + "b/=p," , + "p=max(1.,p-u" + (u+2) + ")*" + b[0] + "," , + "p=1./max(1.,p*p)," , + "m+=mix((1.-w)*xz*q,y*pow(max(dot(reflect(r,xx),b),.0),zy)*(zy+2.)/8.,zz)*p*max(dot(b,xx),.0)*u" + (u+1) + "," + ].join('\n'); + u+=3; + } + code += [ + "xy=yx*z*normalize(y)*o*(u*.9+.1)*zz," , + "m=mix(!3(" + shaderFloat(def[8]) + "),m,z)," , + "xxx+=normalize(v)*" + def[7] + ";" , + "}else" , + "m=!3(" + shaderFloat(def[8]) + ');' + ].join('\n'); + + u=5; + for ( var l in def[15] ) { + var b = def[15][l]; + var h = b[1]; + if ( h ) { + code += [ + "b=s-u" + u + "," , + "p=dot(r,r),a=2.*dot(b,r)," , + "x=a*a-4.*p*(dot(b,b)-" + (h*h) + ")," , + "e=x<.0?!2(-1.):(x=sqrt(x),-.5*!2(a+x,a-x)/p)," , + "e=!2(min(e.x,e.y),max(e.x,e.y));" , + "if(e.x>.0&&e.y<h.x)" , + "m+=u" + (u+2) + "*u" + (u+1) + "*pow((e.y-e.x)/" + shaderFloat(h*2) + ",64.);" + ].join( "\n" ); + } + u+=3; + } + + code += [ + "n+=m*yx;" , + "if(all(lessThan(xy,!3(.01))))break;" , + "yx=xy," , + "s=xxx," , + "r=normalize(v);" , + "}" , + + "h=!2(zx.x,l.y)*.5+.5," , + "h.y=(1.-h.y-u4[5])/u4[7]," , + "f=texture2D(u1,h)," , + "n=max(!3(.0),mix(mix(mix(n,(n.x==n.y&&n.x==n.z)?n:!3(dot(n,!3(.299,.587,.114))),u4[1]),!3(u4[3]),smoothstep(.05,.95,u4[2])),f.rgb*u3,f.a*u4[6])-!3(.004)),", + + "x=(l.x+1.)*(l.y+1.)*(u4[0]*10.),", + "gl_FragColor=!4((1.-(smoothstep(.98,1.,yy(l*8.+u4[0]*20.))+smoothstep(.95,1.,yy(l*1.5+u4[0]*10.))))*smoothstep(1.042+.008*cos(u4[0]*40.),.8,yyx(zx,8.))*(1.-(mod((mod(x,13.)+1.)*(mod(x,47.)+1.),.01))*8.)*((.95+.05*cos(u4[0]*41.))*(n*(6.2*n+.5))/(n*(6.2*n+!3(1.7))+!3(.06))+!3(smoothstep(.98,1.,yy(l*8.-u4[0]*40.)))),1.);", + "}" , + ].join('\n'); + return code; +} + +var cmU=vomNew(3), + cmV=vomNew(3), + cmW=vomNew(3), + cd=vomNew(3), + cu=vomNew(3), + cm=vomNew(9); + + +// Main + +function resize() { + var vw=window.innerWidth,vh=window.innerHeight; + var cw=Math.floor(vh*1.6),ch=Math.floor(vw*.625); + if(cw>vw){ + C1.width=canvasWidth=vw; + C1.height=canvasHeight=ch; + }else{ + C1.width=canvasWidth=cw; + C1.height=canvasHeight=vh; + } + C2.style.width=C2.width=canvasWidth; + c2height=C2.style.height=C2.height=Math.max(canvasHeight/8,100); + c2rHeight=c2height/canvasHeight; + twoDCtx.shadowColor = "#ccc"; + twoDCtx.font = "normal small-caps bold " + Math.floor(c2height/2) + "px monospace"; + twoDCtx.fillStyle = "#111"; + twoDCtx.strokeStyle = "#ddd"; + C1.style.left=Math.floor((vw-canvasWidth)*.5); + C1.style.top=Math.floor((vh-canvasHeight)*.5); + glCtx.viewport(0,0,canvasWidth,canvasHeight); +} + +// FIXME: re-enable! document.body.style.cursor = 'none'; +document.body.style.background = 'black'; +document.body.innerHTML = '<canvas id=C1 style=position:fixed></canvas><canvas id=C2 style=display:none>'; +glCtx=C1.getContext('webgl'); +twoDCtx = C2.getContext('2d'); +(window.onresize=resize)(); +var shaders = [ + [ glCtx.VERTEX_SHADER , shaderHeader + "attribute !2 i;void main(){gl_Position=!4(i,.0,1.),zx=i;}" + ] +]; +var programs = {}; +var context = { + camPos: vomNew(3), + lookAt: vomNew(3), + up: vomNew(3), + toNearPlane: 0 , + misc: vomNew(10) , + textColour: vomNew(3) , + lights: [[vomNew(3),vomNew(3),0],[vomNew(3),vomNew(3),0],[vomNew(3),vomNew(3),0]] +}; +var sn = 1; +for ( var i in raymarchers ) { + var rm = raymarchers[i]; + shaders[sn] = [glCtx.FRAGMENT_SHADER,createRaymarcherCode(rm)]; + programs[i] = [ 5+rm[15].length*3 , 0 , sn++ ]; +} +for ( var i in shaders ) { + var def = shaders[i]; + glCtx.shaderSource( i= shaders[i] = glCtx.createShader( def[0] ) , def[1].replace(/!/g,'vec') ); + glCtx.compileShader( i ); + if (!glCtx.getShaderParameter(i, glCtx.COMPILE_STATUS)) { + def[1] = def[1].split( /\n/ ); + for ( var k in def[1] ) { + var j = parseInt(k)+1; + def[1][k] = j + ": " + def[1][k]; + } + throw "SHADER ERROR\n" + glCtx.getShaderInfoLog(i) + "\n" + def[1].join('\n'); + } +} +for ( var name in programs ) { + var p = glCtx.createProgram( ); + var d = programs[name]; + var ul = d.shift(); + while( d.length ) { + glCtx.attachShader( p , shaders[ d.shift() ] ); + } + glCtx.linkProgram( p ); + var nul = []; + while ( ul-- ) { + nul[ul] = glCtx.getUniformLocation( p , 'u' + ul ); + } + programs[name] = [p,nul]; +} +vtxBuffer = glCtx.createBuffer( ); +glCtx.bindBuffer( glCtx.ARRAY_BUFFER , glCtx.createBuffer( ) ); +glCtx.bufferData( glCtx.ARRAY_BUFFER , vomNew([1,4,1,-1,-4,-1]) , glCtx.STATIC_DRAW ); +glCtx.clearColor(0,0,0,1); + +textTexture = glCtx.createTexture( ); +glCtx.bindTexture( glCtx.TEXTURE_2D , textTexture ); +glCtx.texParameteri( glCtx.TEXTURE_2D , glCtx.TEXTURE_WRAP_S, glCtx.CLAMP_TO_EDGE ); +glCtx.texParameteri( glCtx.TEXTURE_2D , glCtx.TEXTURE_WRAP_T, glCtx.CLAMP_TO_EDGE ); +glCtx.texParameteri( glCtx.TEXTURE_2D , glCtx.TEXTURE_MIN_FILTER, glCtx.NEAREST ); +glCtx.texParameteri( glCtx.TEXTURE_2D , glCtx.TEXTURE_MAG_FILTER, glCtx.NEAREST ); +glCtx.texImage2D( glCtx.TEXTURE_2D , 0 , glCtx.RGBA , glCtx.RGBA , glCtx.UNSIGNED_BYTE , C2 ); + +timeStart = previousFrame = 0; +FRAME_TIME = 100/3; + +paused = 0; +document.body.onkeypress = function(e) { + if ( e.keyCode == 32 ) { + var now = Date.now(); + if ( paused ) { + timeStart += now - paused; + paused = 0; + requestAnimationFrame(draw); + A.play( ); + } else { + paused = now; + A.pause( ); + } + } +}; + +var demoTime; +mainfunc = function(){ +requestAnimationFrame(draw=function(time){ + if ( ! paused ) { + requestAnimationFrame(draw); + } + if ( timeStart == 0 ) { + A.play( ); + timeStart = time; + previousFrame = timeStart - FRAME_TIME; + } + var delta = time - previousFrame; + demoTime = .001*(time - timeStart); + if ( delta < FRAME_TIME ) { + return; + } + previousFrame = time - ( delta % FRAME_TIME ); + + var ds = direction[t]; + while ( ds && ds.endTime < demoTime ) { + ds=direction[++t]; + } + if ( ! ds ) { + A.pause( ); + return; + } + context.misc[0] = demoTime; + context.misc[7] = c2rHeight; + context.stepTime = demoTime - ds.startTime; + if ( ds.updateText ) { + twoDCtx.clearRect( 0 , 0 , canvasWidth , 100 ); + ds.updateText(); + glCtx.texImage2D( glCtx.TEXTURE_2D , 0 , glCtx.RGBA , glCtx.RGBA , glCtx.UNSIGNED_BYTE , C2 ); + } + + var rm = raymarchers[ds.rm], ctx = context; + ds.setGlobals( ctx ); + vecNorm(cmW,vecSub(cmW,ctx.lookAt,ctx.camPos)); + vecNorm(cmU,vecCross(cmU,ctx.up,cmW)); + vecNorm(cmV,vecCross(cmV,cmW,cmU)); + vecScale(cmW,cmW,ctx.toNearPlane); + vecs2Mat3(cm,cmU,cmV,cmW); + + for ( var i in ds.lights ) { + ds.lights[ i ](ctx,ctx.lights[ i ]); + } + + var p = programs[ds.rm]; + glCtx.useProgram( p[ 0 ] ); + glCtx.enableVertexAttribArray( 0 ); + glCtx.vertexAttribPointer( 0 , 2 , glCtx.FLOAT , false , 8 , 0 ); + p = p[1]; + + var u = 0; + glCtx.uniformMatrix3fv( p[u++] , false , cm ); + glCtx.uniform1i( p[u++] , 0 ); + glCtx.uniform3fv( p[u++] , ctx.camPos ); + glCtx.uniform3fv( p[u++] , ctx.textColour ); + glCtx.uniform1fv( p[u++] , ctx.misc ); + for ( var i in ds.lights ) { + glCtx.uniform3fv( p[u++] , context.lights[ i ][0] ); + glCtx.uniform3fv( p[u++] , context.lights[ i ][1] ); + glCtx.uniform1f( p[u++] , context.lights[ i ][2] ); + } + glCtx.drawArrays( 4 , 0 , 3 ); +}) +} + +if ( USE_SYNTH ) { + synth = new CPlayer(); + synth.init(song); + synthGen = setInterval(function(){ + if ( synth.generate() == 1 ) { + clearInterval(synthGen); + var s = '' , a = synth.createWave(); + for(var i=0;i<a.length;i++) + s+= String.fromCharCode(a[i]); + A = document.createElement("audio"); + A.src= 'data:audio/wav;base64,' + btoa(s); + A.oncanplaythrough=mainfunc; + } + + }, 0); +} else { + A = document.createElement("audio"); + A.oncanplaythrough=mainfunc; + A.src= 'music.ogg'; +} diff --git a/201410_-_Sine_City/sine-city-packing-3-direction.html b/201410_-_Sine_City/sine-city-packing-3-direction.html new file mode 100644 index 0000000..68667c7 --- /dev/null +++ b/201410_-_Sine_City/sine-city-packing-3-direction.html @@ -0,0 +1,5 @@ +<body> +<script language="javascript" src="music.js"></script> +<script language="javascript" src="player-small.js"></script> +<script language="javascript" src="sine-city-packing-3-direction.js"></script> + diff --git a/201410_-_Sine_City/sine-city-packing-3-direction.js b/201410_-_Sine_City/sine-city-packing-3-direction.js new file mode 100644 index 0000000..c20a09c --- /dev/null +++ b/201410_-_Sine_City/sine-city-packing-3-direction.js @@ -0,0 +1,1062 @@ +var USE_SYNTH = 1; + +// Vector stuff +function vecOp(code) { + return eval('(function(o,a,b){for(var i=o.length;--i>=0;)' + code + ';return o})') +} +function vomNew(s) { + return new Float32Array(s) +} +var vecNorm = function(o,a) { + var l = Math.sqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]); + return l ? vecScale(o,a,1/l) : vecCopy(o,a); +}; +var vecCross = function(o,a,b) { + return vecSet(o, + a[1]*b[2]-a[2]*b[1] , + a[2]*b[0]-a[0]*b[2] , + a[0]*b[1]-a[1]*b[0] + ); +}; +var vecs2Mat3 = function(o,a,b,c){ + for ( var i = 0 ; i < 3 ; i ++ ) { + o[i*3+0] = a[i]; + o[i*3+1] = b[i]; + o[i*3+2] = c[i]; + } +}; +var vecSet = vecOp('o[i]=arguments[i+1]') , + vecCopy = vecOp('o[i]=a[i]') , + vecSub = vecOp('o[i]=a[i]-b[i]') , + vecScale = vecOp('o[i]=a[i]*b'); + + +// Shaders +var shaderHeader = 'precision highp float;varying !2 zx;'; + + +function shaderFloat( v ) { + return '' + v + ( v == Math.floor(v) ? '.' : '' ); +} +function shaderVec( v ) { + return v.map(shaderFloat).join(','); +} + + +// Raymarchers + +var materials = [[[.05],.7,.02,.01],[[.2],.7,.9,.01,5,[.1]],[[1],.5,.4,.02],[[3,0,0],.3,.1,.6,6,[.6,0,0]],[[0,2,0],.9,.5,.4,15,[0,.2,0]],[[3,1.5,0],.95,.6,.9,.3,[.3,.6,0]],[[.1],0,.04,.002,3,[3]],[[0,1.5,2],.9,.3,.4]]; +var raymarchers = [[100,.025,1,.7,64,.0005,.5,.3,.4,.015,4,2,.75,[0,1,2,3],'y=x+.1*(sin(x.zxy*.17+u4[0]*.5)+sin(x.yzx*.7+u4[0]*1.5))*8.5*(1.+cos(sin(x.z*.1)+x.z*.3)),z=14.-length(y.xy),w=x.x==.0?1.570795*(x.y>.0?1.:-1.):atan(x.y,x.x),q=8.35-u4[8]*1.35,y=!3(9.*(mod(w+x.z*.02,.628)-.314),length(x.xy)-9.,mod(x.z,12.56)-6.28),u=min(length(y.xy)-.25+.1*cos(x.z*8.+u4[0]*.1),length(y.yz)-.5),y=!3(q*(mod(w+x.z*.02,1.256636)-.628318),y.y+9.-q,mod(x.z,62.8318)-31.4159),o=step(u,z)+1.,z=min(u,z),u=length(y)-1.3;if(u<z)z=u,o=3.;y.y+=q-9.,u=yyx(y.yz,8.)-2.;if(u<z)z=u,o=.0;return !2(z,o);',[[.25,0],[.5,.5]]],[6,.00025,1.08,.7,100,.000008,10,.03,2.1,.2,6,.4,5.1,[0,2,5],'z=1.,y=x;for(int i=0;i<7;i++)x=2.*clamp(x,-!3(.58,.9,1.1),!3(.58,.9,1.1))-x,w=max((1.3+u4[9]*.1*cos(u4[0]*.5))/dot(x,x),1.),x*=w,z*=w;w=length(x.xy),e=!2(w-3.,-w*x.z/length(x)-2.*log(1.+.01*a))/abs(z),w=max(e.x,e.y),o=step(e.y,e.x),y+=!3(.1,.3,-.4)*u0-u2+.25*sin(x*1.),e.x=length(y)-.1*u4[8];if(e.x<w)w=e.x,o=2.;return !2(w,o);',[[.05]]],[100,.000025,1,.75,80,.00005,.5,.3,3,.01,4,.75,4.75,[6,0,4],'x.xy*=t(a*.009),w=min(min(yz(x.xzy),yz(x)),yz(x.yzx)),y=mod(x,!3(15.))-!3(7.5),o=step(z=max(length(max(abs(y)-!3(2.5),!3(.0)))-.25,3.5-length(y)),w),w=min(w,z),z=length(y+.1*sin(y*5.5+u4[0]))-2.;if(z<w)w=z,o=2.;return !2(w,o);',[[.05]]],[20,.0005,1,.6,128,.0001,.5,.002,.01,.08,4,.5,1.75,[2,7],'y=x,y.xz=mod(x.xz,8.)-4.,y.yz*=t(u4[8]+.1*a),y.xy*=t(u4[8]*.5+.2*a),y.y*=.9+.1*sin(u4[8]*5.),w=max(length(y)-3.,-min(length(y)-2.8,max(mod(y.y,.8)-.4,-mod(y.y+.4,.8)+.4))),z=x.y+1.+sin(x.x*4.+u4[8]*2.)*sin(x.z+u4[8])*.1,o=clamp(.5+.5*(z-w)/1.,.0,1.),w=mix(z,w,o)-1.*o*(1.-o),y=x,y.xz=mod(y.xz,8.)-4.,y/=1.25+.25*sin(u4[8]*5.),y.xy*=t(u4[8]*5.),y.yz*=t(u4[8]*2.5),z=max(length(y)-1.,.04-length(max(abs(mod(y,.5)-.25)-!3(.15),!3(.0))));return !2(min(w,z),step(z,w));',[[.02],[.05,.5],[.05,.5]]]]; + +var tunMul=1; +var randAround = function(c,d) { return c - d + Math.random()*d*2 }; +var lightFunc = function(intensity,distance) { + return function(lctx) { + vecCopy(lctx[0],camPos); + lctx[1]=intensity; + lctx[2] = distance; + } +}; +var tun1CamCommon = function(dir) { + var z = demoTime*6; + vecSet(camPos,-6,0,z); + vecSet(lookAt,1,0,z); + vecSet(camUp,0,1,0); + misc[1] = 1; + misc[8] = 0; +}; +var desyncFunc = function(desync) { + return function(tt) { + var z = stepTime / direction[t][6]; + misc[4] = -z * desync; + if ( desync > 0 ) { + misc[4] += desync; + } + misc[4] *= randAround(.875,.125); + }; +}; +var balls1CamFunc = function(lax,laz,desync) { + var dsf = desyncFunc(desync); + return function() { + var z = demoTime*3; + vecSet(camPos,0,4,z); + vecSet(lookAt,lax,0,z+laz); + vecSet(camUp,0,0,1); + misc[8]= misc[2] = 0; + dsf(); + }; +}; +var balls2CamCommon = function() { + var z = demoTime*5; + vecSet(camPos,Math.cos(demoTime)*12,8,Math.sin(demoTime)*12+z); + vecSet(lookAt,1,0,z); + vecSet(camUp,0,1,0); + toNearPlane = 2.5; + z = demoTime - direction[43][5]; + misc[8]=z; +}; +var balls2LightFunc = function(scale) { + return function(lctx) { + var z = demoTime*30; + vecSet(lctx[0],scale*Math.cos(demoTime*2)*5,3,scale*Math.sin(demoTime*2)*5+z); + lctx[1] = 1; + lctx[2] = 4; + }; +}; +var fract1CamCommon = function() { + var z = demoTime; + vecSet(camPos,4,2.5+.025*z,6.7); + vecSet(lookAt,0,2.5-.05*z,6.7); + vecSet(camUp,0,0,1); + misc[8] = misc[9] = 0; + toNearPlane = 3; +}; +var fract1CamFunc = function(desync) { + var dsf = desyncFunc(desync); + return function(){ + fract1CamCommon(); + dsf(); + }; +}; +var fract2CamCommon = function(bs) { + vecSet(camPos,5*Math.sin(demoTime*.2),9*Math.cos(demoTime*.41),7.8); + vecCopy(lookAt,camPos); + lookAt[0] = Math.cos(demoTime*.2); + lookAt[1] = Math.sin(demoTime*.33); + lookAt[2] -= 2; + vecSet(camUp,0,0,1); + toNearPlane = 3; + misc[8] = bs; + misc[9] = 1; +}; + +var drawText = function(str,x) { + twoDCtx.shadowBlur = c2height/5; + twoDCtx.fillText( str , x , c2height / 2 ); + twoDCtx.shadowBlur = 0; + twoDCtx.strokeText( str , x , c2height / 2 ); +}; +var titleText = function(str,shake,alpha,r,g,b) { + drawText( str , canvasWidth/15 ); + misc[5] = 1 - c2rHeight + randAround(0,shake); + misc[6] = alpha; + vecSet( textColour , r , g , b ); +}; +var greetingsText = function() { + var t = ( demoTime - direction[34][5] ) * canvasWidth * .5; + drawText( "Greetings to ... Mog, Sycop, Tim & Wullon ... Adinpsz ... Alcatraz ... ASD ... Bits'n'Bites ... Brain Control ... Cocoon ... Conspiracy ... Ctrl+Alt+Test ... Fairlight ... Farbrausch ... Kewlers ... LNX ... Loonies ... Mercury ... Popsy Team ... Razor 1911 ... RGBA ... 7th Cube ... Still ... TPOLM ... TRBL ... Umlaut Design ... X-Men ... Youth Uprising ... Everyone here at DemoJS 2014!" , canvasWidth - t ); + misc[5] = 1 - c2rHeight + randAround(.01,.01); + misc[6] = 1; + vecSet( textColour , 1 , 1 , 1 ); +}; + +var squaresCam = function() { + var t = demoTime - direction[25][5]; + var z = t*10 - 80; + vecSet(camPos,z,0,0); + vecSet(lookAt,z+Math.cos(t*.5) * 80,Math.sin(t*.25)*40,100); + vecSet(camUp,0,1,0); +}; + +var squaresCam2 = function(s) { + var t = demoTime - direction[s][5]; + var z = t*20 - 80; + vecSet(camPos,0,0,z); + vecSet(lookAt,Math.cos(t*.5) * 80,Math.sin(t*.25)*40,z+100); + vecSet(camUp,Math.sin(t),Math.cos(t),0); + misc[4] = randAround(.0125,.0125); +}; + +var tunnelLight = function(lctx) { + vecSub(lctx[0],camPos,vecNorm(lctx[0],lookAt)); + lctx[0][1] -= .5; + lctx[1] = 3; + lctx[2] = 30; +}; +var tunnelCam = function(mul) { + var z = demoTime*30*tunMul; + vecSet(camPos,1.1*Math.cos(z*.1),Math.sin(z*.02),z); + z += 5; + vecSet(lookAt,-Math.sin(z*.05),-.7*Math.cos(z*.033),z); + vecSet(camUp,0,1,0); + toNearPlane = 2; +}; +var tunnelLightBall = function(lctx) { + vecSet(lctx[0] , 4*Math.sin(demoTime*.5)*Math.cos(demoTime*.7) , + 3*Math.cos(demoTime*1.5), + demoTime*30*tunMul+14+16*Math.sin(demoTime*3.3)*Math.cos(demoTime*.77) + ); + lctx[1] = 1; + lctx[2] = 15; +}; + +// direction 0<->rows / 1<->rm / 2<->setGlobals / 3<->lights / 4<->updateText / 5<->startTime / 6<->time / 7<->endTime +var direction = [ + [ + // Music rows + 36 , + // Raymarcher id + 0 , + function( ) { + tun1CamCommon(); + misc[2] = 1 - rStepTime*rStepTime*rStepTime; + toNearPlane = 5; + } , + [ + lightFunc(3,20) + ] + ] , [ + 18 , + 0 , + function( ) { + tun1CamCommon(); + toNearPlane = 5 - 2.25 * rStepTime; + misc[2] = 0; + } , + [ + lightFunc(3,20) + ] + ] , [ + 36 , + 0 , + function( ) { + tun1CamCommon(); + toNearPlane = 2.75 - 2.25 * rStepTime; + misc[2] = rStepTime; + } , + [ + lightFunc(3,20) + ] + ] , [ + 18 , + 3 , + function( ) { + var z = demoTime*3; + vecSet(camPos,0,4,z); + vecSet(lookAt,4,0,z); + vecSet(camUp,0,0,1); + z = rStepTime; + z *= z*z; + misc[2] = 1 - z; + toNearPlane = 2.5; + } , + [ + lightFunc(.75,8) + ] + ] , [ + 22 , + 3 , + balls1CamFunc(4,0,0) , + [ + lightFunc(1,8) + ] + ] , [ + 22 , + 3 , + balls1CamFunc(2,-2,0) , + [ + lightFunc(1,8) + ] + ] , [ + 3 , + 3 , + balls1CamFunc( 6 , 0 , -.5 ) , + [ + lightFunc(.5,4) + ] + ] , [ + 9 , + 3 , + balls1CamFunc( 6 , 0 , .5 ) , + [ + lightFunc(.5,4) + ] + ] , [ + 3 , + 3 , + balls1CamFunc( 2 , 2 , -.2 ) , + [ + lightFunc(1,8) + ] + ] , [ + 9 , + 3 , + balls1CamFunc( 2 , 2 , .2 ) , + [ + lightFunc(1,8) + ] + ] , [ + 3 , + 3 , + balls1CamFunc( 2 , 5 , -.7 ) , + [ + lightFunc(1,2) + ] + ] , [ + 7 , + 3 , + balls1CamFunc( 2 , 2 , .7 ) , + [ + lightFunc(1,2) + ] + ] , [ + 9 , + 3 , + function() { + var z = demoTime*3; + misc[2] = rStepTime; + vecSet(camPos,0,4+rStepTime*2,z); + vecSet(lookAt,2,0,z+2); + vecSet(camUp,0,0,1); + misc[3] = 1; + } , + [ + lightFunc(1,2) + ] + ] , [ + 21 , + 1 , + function( ) { + fract1CamCommon(); + misc[3] = 1; + misc[2] = 1 - rStepTime*rStepTime*rStepTime; + } , [ + fractLight = function(lctx) { + vecCopy(lctx[0],camPos); + lctx[0][2]+=2; + lctx[1] = 1; + lctx[2] = 3; + } + ] + ] , [ + 14 , + 1 , + fract1CamFunc(0) , + [ + fractLight + ] + ] , [ + 3 , + 1 , + fract1CamFunc(-.4) , + [ fractLight ] + ] , [ + 9 , + 1 , + fract1CamFunc(.4) , + [ fractLight ] + ] , [ + 3 , + 1 , + fract1CamFunc(-.2) , + [ fractLight ] + ] , [ + 9 , + 1 , + fract1CamFunc(.2) , + [ fractLight ] + ] , [ + 12 , + 1 , + function() { + fract1CamCommon(); + misc[4] = -( 6 * rStepTime ) % 1; + misc[4] *= randAround(.875,.125); + } , + [ fractLight ] + ] , [ + 22 , + 1 , + function() { + fract1CamCommon(); + misc[3] = .4; + misc[2] = rStepTime; + toNearPlane = 3 - 2.5*Math.max(1,2*rStepTime); + misc[4] = ( 30 * misc[2] ) % 1; + misc[4] *= randAround(.925,.075); + } , + [ fractLight ] + ] , [ + 3 , + 1 , + neutral = function() { + fract1CamCommon(); + misc[3] = .4; + misc[2] = 1; + misc[4] = 0; + } , + [ fractLight ] + ] , [ + 12 , + 1 , + neutral , + [ fractLight ], + function() { + titleText( "TheT(ourist)" , .08 , 1 , 1 , 1 , 1 ); + } + ] , [ + 12 , + 1 , + neutral , + [ fractLight ], + function() { + titleText( "TheT(ourist)" , .08 , 1 - rStepTime , 1 , 1 , 1 ); + } + ] , [ + 12 , + 1 , + neutral , + [ fractLight ], + function() { + titleText( "presents" , .08 , 1 - rStepTime , 1 , 1 , 1 ); + } + ] , [ + 20 , + 2 , + function() { + squaresCam(); + toNearPlane = 2.5; + misc[2] = 1 - rStepTime; + } , + [ lightFunc(1,30) ], + function() { + titleText( "Sine City" , .04 , rStepTime , 1 , 1 , 1 ); + } + ] , [ + 52 , + 2 , + function() { + squaresCam(); + misc[2] = 0; + } , + [ lightFunc(1,30) ], + function() { + titleText( "Sine City" , .04 , 1 , 1 , 1 , 1 ); + } + ] , [ + 12 , + 2 , + function(){ + squaresCam(); + misc[3] = 1; + misc[2] = Math.max(0,1-rStepTime*2); + } , + [ lightFunc(1,30) ], + function() { + titleText( "Sine City" , .04 , 1 , 1 - rStepTime , 1 - rStepTime * .5 , 1 - rStepTime ); + } + ] , [ + 12 , + 2 , + function() { + squaresCam(); + misc[4] = ( 1 - rStepTime ) * .7 + randAround(.0125,.0125); + misc[1] = 1 - .5 * rStepTime; + } , + [ lightFunc(1,30) ], + function() { + titleText( "Sine City" , .04 , 1 , 0 , .5 , 0 ); + } + ] , [ + 9 , + 2 , + function() { + squaresCam2(29); + misc[2] = Math.max(0,1-rStepTime*1.5); + misc[4] += ( rStepTime - 1 ) * .3; + misc[1] = .5 - .5 * rStepTime; + } , + [ lightFunc(1,30) ], + function() { + titleText( "Sine City" , .04 , 1 - rStepTime , 0 , .5 , 0 ); + } + ] , [ + 69 , + 2 , + function() { + squaresCam2(29); + misc[1] = 0; + } , + [ lightFunc(1,30) ] + ] , [ + 11 , + 2 , + function() { + squaresCam2(29); + misc[3] = .2; + misc[2] = rStepTime; + } , + [ lightFunc(1,30) ] + ] , [ + 11 , + 0 , + function() { + tunnelCam(); + misc[2] = 1 - rStepTime; + } , + [ tunnelLight ] + ] , [ + 17 , + 0 , + function() { + tunnelCam(); + misc[2] = 0; + misc[4] = (1.2 - 1.2 * rStepTime) * randAround(1,.02); + } , + [ tunnelLight ] + ] , [ + 18 , + 0 , + function() { + tunnelCam(); + misc[4] = 0; + misc[8] = rStepTime; + } , + [ tunnelLight ], + greetingsText + ] , [ + 36 , + 0 , + function() { + tunnelCam(); + misc[2] = 1 - Math.min(4*rStepTime,1); + misc[8] = 1; + } , + tunLights = [ tunnelLight , tunnelLightBall ], + greetingsText + ] , [ + 33 , + 0 , + function() { + tunnelCam(); + misc[2] = rStepTime; + misc[3] = .7; + misc[4] = -((4*rStepTime)%1)*randAround(1,.05); + } , + tunLights , + greetingsText + ] , [ + 9 , + 1 , + function() { + fract2CamCommon(0); + misc[2] = rStepTime; + misc[3] = 1; + } , + [ fractLight ], + greetingsText + ] , [ + 20 , + 1 , + function() { + fract2CamCommon(rStepTime); + misc[2] = 0; + } , + [ fractLight ], + greetingsText + ] , [ + 31 , + 1 , + function() { + fract2CamCommon(1); + misc[2] = Math.min(0,1-5*rStepTime); + } , + [ fractLight ], + greetingsText + ] , [ + 5 , + 1 , + function() { + fract2CamCommon(1); + misc[2] = 1-rStepTime; + } , + [ fractLight ], + greetingsText + ] , [ + 18 , + 1 , + function() { + fract2CamCommon(1); + misc[2] = Math.min(0,1-5*rStepTime); + misc[4] = Math.max(0,1.6*rStepTime - .8 )*randAround(1,.05); + } , + [ fractLight ], + greetingsText + ] , [ + 12 , + 1 , + function() { + fract2CamCommon(1); + misc[3] = .1; + misc[2] = rStepTime; + misc[4] = .8*(1-rStepTime)*randAround(1,.1); + } , + [ fractLight ], + greetingsText + ] , [ + 22 , + 3 , + function() { + balls2CamCommon(); + misc[2] = 1-rStepTime; + misc[4] = 0; + } , + ballsLights = [ lightFunc(.6,30) , balls2LightFunc(1),balls2LightFunc(-1) ], + greetingsText + ] , [ + 59 , + 3 , + function() { + balls2CamCommon(); + misc[3] = .8; + misc[2] = Math.max(0,1-(12*rStepTime)%4); + } , + ballsLights, + greetingsText + ] , [ + 8 , + 3 , + function() { + balls2CamCommon(); + misc[3] = .1; + misc[2] = rStepTime; + misc[4] = randAround(.1,.1); + } , + ballsLights + ] , [ + 7 , + 0 , + function() { + tunMul = 2; + tunnelCam(); + misc[2] = 1-rStepTime; + misc[4] = randAround(.1,.1); + } , + tunLights + ] , [ + 22 , + 0 , + function() { + tunnelCam(); + misc[4] = randAround(.1,.1); + } , + tunLights + ] , [ + 10 , + 0 , + function() { + tunnelCam(); + misc[4] = stepTime*4+randAround(.1,.1); + misc[3] = 1; + misc[2] = rStepTime; + } , + tunLights + ] , [ + 10 , + 2 , + function() { + squaresCam2(49); + misc[4] = (demoTime-direction[48][5])*4+randAround(.1,.1); + misc[2] = 1-rStepTime; + } , + [ lightFunc(1,30) ] + ] , [ + 40 , + 2 , + function() { + squaresCam2(49); + misc[4] = -(demoTime-direction[48][5])*6; + } , + [ lightFunc(1,30) ] + ] , [ + 40 , + 2 , + function() { + squaresCam2(49); + misc[4] = (demoTime-direction[48][5])*8; + misc[3] = 0; + misc[2] = rStepTime; + } , + [ lightFunc(1,30) ] + ] , [ + 68 , + 2 , + function() { + squaresCam2(49); + misc[2] = 1 + } , + [ lightFunc(1,30) ] + ] +]; +var t = 0; +for ( var i in direction ) { + direction[ i ][5] = t; + t += ( direction[i][6] = direction[ i ][0] * .125 ); + direction[ i ][7] = t; +} +t = 0; + +function createRaymarcherCode( def ) { + var w = 'uniform '; + var code = shaderHeader + + [ w+'mat3 u0;' , + w+'sampler2D u1;' , + w+'!3 u2,u3;' , + w+'float u4[10];' + ].join('\n'); + var u = 5; + for ( var i in def[15] ) { + code += w+'!3 u' + u++ + ';'+w+'float u' + u++ + ', u' + u++ + ';'; + } + code += [ + "const !2 c=!2(1.,-1.)*"+def[5]+";" , + "float p,z,w,u,o,zy,q,x,a,zz;" , + "!2 e,h;" , + "!3 l=!3(zx,1.),m,r,s=u2,yx=!3(1.),n=!3(.0),b,v,xxx,xy,d,xx,xz,y;" , + "!4 f;" , + + "float g(float x)" , + "{" , + "return fract(sin(x)*43758.5453);" , + "}" , + + "float yy(!3 x)" , + "{" , + "m=floor(x),y=fract(x)," , + "y*=y*(3.-2.*y)," , + "z=m.x+m.y*57.+m.z*113.;" , + "return mix(mix(mix(g(z),g(z+1.),y.x)," , + "mix(g(z+57.),g(z+58.),y.x),y.y)," , + "mix(mix(g(z+113.),g(z+114.),y.x)," , + "mix(g(z+170.),g(z+171.),y.x),y.y),y.z);" , + "}" , + + "float yyx(!2 x,float a)" , + "{" , + "e=pow(abs(x),!2(a));" , + "return pow(e.x+e.y,1./a);" , + "}" , + + "mat2 t(float x)" , + "{" , + "e=!2(cos(x),sin(x));" , + "return mat2(-e.x,e.y,e.y,e.x);" , + "}" , + + "float yz(!3 x)" , + "{" , + "return length(mod(x.xy,!2(15.))-!2(7.5))-.5+.05*sin(x.z*9.42477);" , + "}" , + + "!2 k(!3 x,float a) {" + ].join("\n"); + code += def[14] + '}'; + code += [ + "void main()" , + "{" , + "l.y+=mod(u4[4],1.)*2.2;" , + "if(l.y>1.){" , + "if(l.y < 1.2)discard;" , + "l.y-=2.2;" , + "}" , + "l.x*=1.6," , + "r=normalize(l*u0);" , + + "for(int j=0;j<2;j++){" , + "v=r,xxx=s,xy=!3(.0)," , + "x=.0,a=" + def[1] + ';' , + "for(int i=0;i<" + def[4] + ";i++){" , + "h=k(s+r*x,x);" , + "if(h.x< a||i>" + def[4] + "/(j+1)||x>" + def[0] + ".)break;" , + "x+=h.x*" + def[3] + ",a*=" + shaderFloat( def[2] ) + ";" , + "}" , + "h.x=x;", + + "if(x<"+ def[0]+ ".){" , + "d=s+r*x," , + "f=!4(" , + "k(d+c.xyy,x).x," , + "k(d+c.yyx,x).x," , + "k(d+c.yxy,x).x," , + "k(d+c.xxx,x).x" , + ")," , + "xx=normalize(f.x*c.xyy+f.y*c.yyx+f.z*c.yxy+f.w*c.xxx)," , + "a=.0," , + "p=" + def[12] + ";" , + "for(int i=1;i<="+def[10]+";i++)" , + "x=(float(i)/"+def[10]+".)*"+ shaderFloat( def[11] ) + "," , + "m=d+xx*x," , + "a+=p*(x-k(m,distance(m,s)).x)," , + "p*=.5;" , + "q=max(.1,1.-clamp(pow(a,1.),.0,1.));" , + ].join('\n'); + + for(var i in def[13]) + w=materials[def[13][i]],code+=(i>0?'else ':'')+'if(h.y==' + i + '.)xz='+(w[4]?('mix(!3('+shaderVec(w[0])+'),!3('+shaderVec(w[5])+'),yy(d*'+shaderFloat(def[6]*w[4])+'))'):('!3('+shaderVec(w[0])+')'))+',w='+shaderFloat(w[1])+',u='+w[2]+',o='+w[3]+';'; + + code += [ + "v=reflect(r,xx)," , + "z="+def[9]+"*h.x," , + "z=clamp(exp(-z*z*z*1.442695),.0,1.)," , + "x=clamp((1.+dot(normalize(v+r),r)),.0,1.),a=x*x," , + "zz=o+(1.-o)*x*a*a*(u*.9+.1)," , + "y=mix(!3(1.),xz/dot(!3(.299,.587,.114),xz),w)," , + "m=!3(.0)," , + "zy=exp2(4.+6.*u)," , + ].join('\n'); + + u = 5; + for ( var l in def[15] ) { + var b = def[15][l]; + code += [ + "p=length(b=u" + u + "-d)," , + "b/=p," , + "p=max(1.,p-u" + (u+2) + ")*" + b[0] + "," , + "p=1./max(1.,p*p)," , + "m+=mix((1.-w)*xz*q,y*pow(max(dot(reflect(r,xx),b),.0),zy)*(zy+2.)/8.,zz)*p*max(dot(b,xx),.0)*!3(u" + (u+1) + ")," + ].join('\n'); + u+=3; + } + code += [ + "xy=yx*z*normalize(y)*o*(u*.9+.1)*zz," , + "m=mix(!3(" + shaderFloat(def[8]) + "),m,z)," , + "xxx+=normalize(v)*" + def[7] + ";" , + "}else" , + "m=!3(" + shaderFloat(def[8]) + ');' + ].join('\n'); + + u=5; + for ( var l in def[15] ) { + var b = def[15][l]; + var h = b[1]; + if ( h ) { + code += [ + "b=s-u" + u + "," , + "p=dot(r,r),a=2.*dot(b,r)," , + "x=a*a-4.*p*(dot(b,b)-" + (h*h) + ")," , + "e=x<.0?!2(-1.):(x=sqrt(x),-.5*!2(a+x,a-x)/p)," , + "e=!2(min(e.x,e.y),max(e.x,e.y));" , + "if(e.x>.0&&e.y<h.x)" , + "m+=u" + (u+2) + "*!3(u" + (u+1) + ")*pow((e.y-e.x)/" + shaderFloat(h*2) + ",64.);" + ].join( "\n" ); + } + u+=3; + } + + code += [ + "n+=m*yx;" , + "if(all(lessThan(xy,!3(.01))))break;" , + "yx=xy," , + "s=xxx," , + "r=normalize(v);" , + "}" , + + "h=!2(zx.x,l.y)*.5+.5," , + "h.y=(1.-h.y-u4[5])/u4[7]," , + "f=texture2D(u1,h)," , + "n=max(!3(.0),mix(mix(mix(n,(n.x==n.y&&n.x==n.z)?n:!3(dot(n,!3(.299,.587,.114))),u4[1]),!3(u4[3]),smoothstep(.05,.95,u4[2])),f.rgb*u3,f.a*u4[6])-!3(.004)),", + + "x=(l.x+1.)*(l.y+1.)*(u4[0]*10.),", + "gl_FragColor=!4((1.-(smoothstep(.98,1.,yy(l*8.+u4[0]*20.))+smoothstep(.95,1.,yy(l*1.5+u4[0]*10.))))*smoothstep(1.042+.008*cos(u4[0]*40.),.8,yyx(zx,8.))*(1.-(mod((mod(x,13.)+1.)*(mod(x,47.)+1.),.01))*8.)*((.95+.05*cos(u4[0]*41.))*(n*(6.2*n+.5))/(n*(6.2*n+!3(1.7))+!3(.06))+!3(smoothstep(.98,1.,yy(l*8.-u4[0]*40.)))),1.);", + "}" , + ].join('\n'); + return code; +} + +var cmU=vomNew(3), + cmV=vomNew(3), + cmW=vomNew(3), + cd=vomNew(3), + cu=vomNew(3), + cm=vomNew(9); + + +// Main + +function resize() { + var vw=window.innerWidth,vh=window.innerHeight; + var cw=Math.floor(vh*1.6),ch=Math.floor(vw*.625); + if(cw>vw){ + C1.width=canvasWidth=vw; + C1.height=canvasHeight=ch; + }else{ + C1.width=canvasWidth=cw; + C1.height=canvasHeight=vh; + } + C2.style.width=C2.width=canvasWidth; + c2height=C2.style.height=C2.height=Math.max(canvasHeight/8,100); + c2rHeight=c2height/canvasHeight; + twoDCtx.shadowColor = "#ccc"; + twoDCtx.font = "normal small-caps bold " + Math.floor(c2height/2) + "px monospace"; + twoDCtx.fillStyle = "#111"; + twoDCtx.strokeStyle = "#ddd"; + C1.style.left=Math.floor((vw-canvasWidth)*.5); + C1.style.top=Math.floor((vh-canvasHeight)*.5); + glCtx.viewport(0,0,canvasWidth,canvasHeight); +} + +// FIXME: re-enable! document.body.style.cursor = 'none'; +document.body.style.background = 'black'; +document.body.innerHTML = '<canvas id=C1 style=position:fixed></canvas><canvas id=C2 style=display:none>'; +glCtx=C1.getContext('webgl'); +twoDCtx = C2.getContext('2d'); +(window.onresize=resize)(); +var shaders = [ + [ glCtx.VERTEX_SHADER , shaderHeader + "attribute !2 i;void main(){gl_Position=!4(i,.0,1.),zx=i;}" + ] +]; +var programs = {}; +var misc = vomNew(10) , camPos = vomNew(3),lookAt=vomNew(3),camUp=vomNew(3),toNearPlane=0,textColour=vomNew(3) , lights= [[vomNew(3),0,0],[vomNew(3),0,0],[vomNew(3),0,0]]; +var sn = 1; +for ( var i in raymarchers ) { + var rm = raymarchers[i]; + shaders[sn] = [glCtx.FRAGMENT_SHADER,createRaymarcherCode(rm)]; + programs[i] = [ 5+rm[15].length*3 , 0 , sn++ ]; +} +for ( var i in shaders ) { + var def = shaders[i]; + glCtx.shaderSource( i= shaders[i] = glCtx.createShader( def[0] ) , def[1].replace(/!/g,'vec') ); + glCtx.compileShader( i ); + if (!glCtx.getShaderParameter(i, glCtx.COMPILE_STATUS)) { + def[1] = def[1].split( /\n/ ); + for ( var k in def[1] ) { + var j = parseInt(k)+1; + def[1][k] = j + ": " + def[1][k]; + } + throw "SHADER ERROR\n" + glCtx.getShaderInfoLog(i) + "\n" + def[1].join('\n'); + } +} +for ( var name in programs ) { + var p = glCtx.createProgram( ); + var d = programs[name]; + var ul = d.shift(); + while( d.length ) { + glCtx.attachShader( p , shaders[ d.shift() ] ); + } + glCtx.linkProgram( p ); + var nul = []; + while ( ul-- ) { + nul[ul] = glCtx.getUniformLocation( p , 'u' + ul ); + } + programs[name] = [p,nul]; +} +vtxBuffer = glCtx.createBuffer( ); +glCtx.bindBuffer( glCtx.ARRAY_BUFFER , glCtx.createBuffer( ) ); +glCtx.bufferData( glCtx.ARRAY_BUFFER , vomNew([1,4,1,-1,-4,-1]) , glCtx.STATIC_DRAW ); +glCtx.clearColor(0,0,0,1); + +textTexture = glCtx.createTexture( ); +glCtx.bindTexture( glCtx.TEXTURE_2D , textTexture ); +glCtx.texParameteri( glCtx.TEXTURE_2D , glCtx.TEXTURE_WRAP_S, glCtx.CLAMP_TO_EDGE ); +glCtx.texParameteri( glCtx.TEXTURE_2D , glCtx.TEXTURE_WRAP_T, glCtx.CLAMP_TO_EDGE ); +glCtx.texParameteri( glCtx.TEXTURE_2D , glCtx.TEXTURE_MIN_FILTER, glCtx.NEAREST ); +glCtx.texParameteri( glCtx.TEXTURE_2D , glCtx.TEXTURE_MAG_FILTER, glCtx.NEAREST ); +glCtx.texImage2D( glCtx.TEXTURE_2D , 0 , glCtx.RGBA , glCtx.RGBA , glCtx.UNSIGNED_BYTE , C2 ); + +timeStart = previousFrame = 0; +FRAME_TIME = 100/3; + +paused = 0; +document.body.onkeypress = function(e) { + if ( e.keyCode == 32 ) { + var now = Date.now(); + if ( paused ) { + timeStart += now - paused; + paused = 0; + requestAnimationFrame(draw); + A.play( ); + } else { + paused = now; + A.pause( ); + } + } +}; + +var demoTime, rStepTime,stepTime; +mainfunc = function(){ +requestAnimationFrame(draw=function(time){ + if ( ! paused ) { + requestAnimationFrame(draw); + } + if ( timeStart == 0 ) { + A.play( ); + timeStart = time; + previousFrame = timeStart - FRAME_TIME; + } + var delta = time - previousFrame; + demoTime = .001*(time - timeStart); + if ( delta < FRAME_TIME ) { + return; + } + previousFrame = time - ( delta % FRAME_TIME ); + + var ds = direction[t]; + while ( ds && ds[7] < demoTime ) { + ds=direction[++t]; + } + if ( ! ds ) { + A.pause( ); + return; + } + misc[0] = demoTime; + misc[7] = c2rHeight; + stepTime = demoTime - ds[5]; + rStepTime = stepTime / ds[6]; + if ( ds[4] ) { + twoDCtx.clearRect( 0 , 0 , canvasWidth , 100 ); + ds[4](); + glCtx.texImage2D( glCtx.TEXTURE_2D , 0 , glCtx.RGBA , glCtx.RGBA , glCtx.UNSIGNED_BYTE , C2 ); + } + + ds[2](); + vecNorm(cmW,vecSub(cmW,lookAt,camPos)); + vecNorm(cmU,vecCross(cmU,camUp,cmW)); + vecNorm(cmV,vecCross(cmV,cmW,cmU)); + vecScale(cmW,cmW,toNearPlane); + vecs2Mat3(cm,cmU,cmV,cmW); + + for ( var i in ds[3] ) { + ds[3][i](lights[ i ]); + } + + var p = programs[ds[1]]; + glCtx.useProgram( p[ 0 ] ); + glCtx.enableVertexAttribArray( 0 ); + glCtx.vertexAttribPointer( 0 , 2 , glCtx.FLOAT , false , 8 , 0 ); + p = p[1]; + + var u = 0; + glCtx.uniformMatrix3fv( p[u++] , false , cm ); + glCtx.uniform1i( p[u++] , 0 ); + glCtx.uniform3fv( p[u++] , camPos ); + glCtx.uniform3fv( p[u++] , textColour ); + glCtx.uniform1fv( p[u++] , misc ); + for ( var i in ds[3] ) { + glCtx.uniform3fv( p[u++] , lights[ i ][0] ); + glCtx.uniform1f( p[u++] , lights[ i ][1] ); + glCtx.uniform1f( p[u++] , lights[ i ][2] ); + } + glCtx.drawArrays( 4 , 0 , 3 ); +}) +} + +if ( USE_SYNTH ) { + synth = new CPlayer(); + synth.init(song); + synthGen = setInterval(function(){ + if ( synth.generate() == 1 ) { + clearInterval(synthGen); + var s = '' , a = synth.createWave(); + for(var i=0;i<a.length;i++) + s+= String.fromCharCode(a[i]); + A = document.createElement("audio"); + A.src= 'data:audio/wav;base64,' + btoa(s); + A.oncanplaythrough=mainfunc; + } + + }, 0); +} else { + A = document.createElement("audio"); + A.oncanplaythrough=mainfunc; + A.src= 'music.ogg'; +} diff --git a/201410_-_Sine_City/sine-city-packing-4-sound.html b/201410_-_Sine_City/sine-city-packing-4-sound.html new file mode 100644 index 0000000..543ae8d --- /dev/null +++ b/201410_-_Sine_City/sine-city-packing-4-sound.html @@ -0,0 +1,3 @@ +<body> +<script language="javascript" src="sine-city-packing-4-sound.js"></script> + diff --git a/201410_-_Sine_City/sine-city-packing-4-sound.js b/201410_-_Sine_City/sine-city-packing-4-sound.js new file mode 100644 index 0000000..0e508b0 --- /dev/null +++ b/201410_-_Sine_City/sine-city-packing-4-sound.js @@ -0,0 +1,1069 @@ +var USE_SYNTH = 1; + +var song=[[[0,198,128,0,3,192,128,1,0,0,96,128,28,0,0,0,0,2,63,61,13,16,44,8,0,0],[1,2,3,4,5,2,3,4,6,7,1,2,3,4,5,2,3,4,5,2,3,4,1,2,3,8,9],[[[115,,,,,,,,,,,,117,,,,,,,,,,,,113],[12,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,96]],[[115,,,,,,,,,,,,,,,110],[12,,,,,,,,,,,,,,,12,,,,,,,,,,,,,,,,,,,,,115,,,,,,,,,,,,,,,148]],[[115,,,,,,,,,,,,117,,,,,,,,,,,,118],[12,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,96]],[[122,,,,,,,,,,,,,,,123,,,,,115],[12,,,,,,,,,,,,,,,12,,,,,12,,,,,,,,,,,,,,,,115,,,,,,,,,,,,,,,8,,,,,128]],[[118,,,,,,,,,,,,117,,,,,,,,,,,,113],[12,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,96]],[[115],[12,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,255]],[[,,,,,,,,,,,,,,,,118,118,118],[,,,,,,,,,,,,,,,,12,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,128]],[[122,,,,,,,,,,,,,,,123,,,,,115],[12,,,,,,,,,,,,,,,12,,,,,13,12,,,,,,,,,,,,,,,115,,,,,,,,,,,,,,,8,,,,,95,61]],[[],[]]]],[[0,255,116,1,0,255,101,0,0,15,1,4,45,0,13,6,1,2,62,27,60,48,0,0,44,2],[,1,,2,,1,,2,,3,4,4,5,4,5,4,5,4,5,4,5,4,5,4,3,6],[[[,,,,,139,,,139,139,,,,,,139,,,,,,,,139,,,139,139,,,,,139,139,139],[]],[[,,139,139,,,,,139,139,,,,,139,139,,,,,,,,,,139,139,139,,,,,139,139,139],[]],[[,,,139,,,,,139,139,,,,,,139,,,,,139,139,,,,,,139,,,,139,139,139],[]],[[139,,,,139,,139,,,139,,,139,,,,139,,139,,,139,,,139,,,,139,,139,,,139],[]],[[139,,,139,139,,139,,,139,,,139,,,139,139,,139,,,139,,,139,,,139,139,,139,,,139],[]],[[139,,,139,139,,139,,,139,,,139,,,139,139,,139,,,139,139],[]]]],[[0,0,140,0,0,0,140,0,0,128,4,10,34,0,187,5,0,1,239,135,34,19,108,8,8,4],[,,1,,1,,3,,1,3,2,2,2,2,2,3,2,3,2,3,2,3,2,3,1],[[[,,,,,,,,,,127,,,,,,,,,,,,127,,,,,,,,,,,,127],[]],[[,,,139,,,,,,139,139,,,,,139,,,,,,139,139,,,,,139,,,,,139,,139],[]],[[,,127,,,,,,,,127,,,,127,,,,,,,,127,,,,127,,,,,,,,127],[]]]],[[1,192,128,0,3,201,128,0,0,93,5,6,58,3,195,6,1,3,35,63,14,17,11,10,61,6],[,,,,1,2,3,4,5,6,7,5,8,9,10,11,8,9,10,11,12,13,14,15,16],[[[,,,,,,,,147,146,145,,,,,,,,,,145,147,146,,,,,,,,,,149,148,147],[]],[[,,,,,,151,151,151,,,,,,,146,142,138,,,,,,,,,,,,,,,147,150,147],[]],[[,,146,,,146,,,,,,,,,147,146,145,,,,,,,,,,146,145,142,,,142,,,142],[]],[[,,141,,,,,,,,,,,,141,140,139,,,146,,,146,,,127],[]],[[,139,,151,,,,,,,,,,151,,139,,,,,,,,,,139,,151],[]],[[,139,,151,150,149,,,,,,,,139,,149,148,147,,,,,,,,139,,,146,,,145,,,144],[]],[[,139,,,139,142,,,142,144,146,,144,,,,146,147,,,147,146,141,,137,,,,142,141,,141,,137],[]],[[139,,127,,142,,,130,,,144,142,141,,129,,141,,,144,,,141,144,142,,,,149,,,146,,,151],[]],[[,149,,149,,146,144,142,,,141,,142,,,139,,,,151,147,,,,146,147,,144,146,,142,144,141,146],[]],[[,,,,,,,,147,146,145,,,,,141,144,147,146,,144,,137,,,144,146,142,144,,,142,144,141,146],[]],[[,146,,151,,146,,,,144,142,144,146,,,,142,,,,,139,,,,,151,146,139,144,139,142,141,142,151],[]],[[,,147,,,149,146,,,142,,142,141,,,144,,144,,,144,146,142,144,142,,,,151,150,149,,137,,149],[]],[[,151,,,147,151,,,146,151,,,,,144,151,,149,147,149,151,,146,,,144,143,142,,,139,,151,139],[]],[[,,134,,,134,,,134,,,146,144,,,141,144,,,146,147,146,,,144,,139,140,141,,,153,,,141],[]],[[,142,,151,,,142,143,144,,,,151,,,139,,,137,,149,,137,,,,125,,,141,142,141,,,146],[]],[[139,,127,139,,127,139,,127,139,127],[]]]],[[2,160,128,1,0,160,128,0,1,60,4,7,41,0,60,4,1,3,14,0,35,32,31,12,89,1],[,,,,,,,,,,,,1,2,1,2,1,2,1,2,1,2,1,2,1,3],[[[,,139,,,,,,,,,,,,139,,,,,,,,,,,,139,,,,,139,139,,,139],[]],[[,,139,,,151,,,139,,,151,,,139,,,151,,,139,,,151,,,139,,,151,,,146,146,146,146],[]],[[,,139,,,151,,,139,,,151,,,139,,139,139,139,139,127],[]]]],[[2,100,128,0,3,201,128,0,0,0,0,6,29,0,195,6,1,3,28,229,119,77,147,6,61,2],[,,,,,,,,,6,1,2,3,4,5,2,3,4,1,2,3,4,1,2,3,7],[[[115,115,115,115,115,115,115,115,115,115,115,115,117,117,117,117,117,117,117,117,117,117,117,117,113,113,113,113,113,113,113,113,113,113,113,113],[]],[[115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110],[]],[[115,115,115,115,115,115,115,115,115,115,115,115,117,117,117,117,117,117,117,117,117,117,117,117,118,118,118,118,118,118,118,118,118,118,118,118],[]],[[110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,111,111,111,111,111,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115],[]],[[118,118,118,118,118,118,118,118,118,118,118,118,117,117,117,117,117,117,117,117,117,117,117,117,113,113,113,113,113,113,113,113,113,113,113,113],[]],[[,,,,,,,,,,,,,,,,,,130,,130,,130,,130,,130,,130,118,130,118,130,118,130,118],[,,,,,,,,,,,,,,,,,,26,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2]],[[110,122,,122,134,,110,122,,122,134,,110,122,,111,123,,111,123,115,127,139,127,115],[,,,,,,,,,,,,,,,,,,,,26,25,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,8,147]]]],[[2,100,128,0,3,201,128,0,0,0,5,6,58,0,195,6,1,2,135,0,0,32,147,6,121,6],[],[]],[[2,100,128,0,3,201,128,0,0,0,5,6,58,0,195,6,1,2,135,0,0,32,147,6,121,6],[],[]]]; + + +var getnotefreq=function(n){return .003959503758*Math.pow(2,(n-128)/12)}; + +var mOscillators = [ + function(v){return Math.sin(v*6.283184)}, + function(v){return (v%1)<.5?1:-1}, + function(v){return 2*(v%1)-1}, + function(v){var v2=(v%1)*4;return(v2<2)?(v2-1):(3-v2)} +]; + +var mCurrentCol=0,mNumWords=10717272,mMixBuf=new Int32Array(mNumWords); + + +// Vector stuff +function vecOp(code) { + return eval('(function(o,a,b){for(var i=o.length;--i>=0;)' + code + ';return o})') +} +function vomNew(s) { + return new Float32Array(s) +} +var vecNorm = function(o,a) { + var l = Math.sqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]); + return l ? vecScale(o,a,1/l) : vecCopy(o,a); +}; +var vecCross = function(o,a,b) { + return vecSet(o, + a[1]*b[2]-a[2]*b[1] , + a[2]*b[0]-a[0]*b[2] , + a[0]*b[1]-a[1]*b[0] + ); +}; +var vecs2Mat3 = function(o,a,b,c){ + for ( var i = 0 ; i < 3 ; i ++ ) { + o[i*3+0] = a[i]; + o[i*3+1] = b[i]; + o[i*3+2] = c[i]; + } +}; +var vecSet = vecOp('o[i]=arguments[i+1]') , + vecCopy = vecOp('o[i]=a[i]') , + vecSub = vecOp('o[i]=a[i]-b[i]') , + vecScale = vecOp('o[i]=a[i]*b'); + + +// Shaders +var shaderHeader = 'precision highp float;varying !2 zx;'; + + +function shaderFloat( v ) { + return '' + v + ( v == Math.floor(v) ? '.' : '' ); +} +function shaderVec( v ) { + return v.map(shaderFloat).join(','); +} + + +// Raymarchers + +var materials = [[[.05],.7,.02,.01],[[.2],.7,.9,.01,5,[.1]],[[1],.5,.4,.02],[[3,0,0],.3,.1,.6,6,[.6,0,0]],[[0,2,0],.9,.5,.4,15,[0,.2,0]],[[3,1.5,0],.95,.6,.9,.3,[.3,.6,0]],[[.1],0,.04,.002,3,[3]],[[0,1.5,2],.9,.3,.4]]; +var raymarchers = [[100,.025,1,.7,64,.0005,.5,.3,.4,.015,4,2,.75,[0,1,2,3],'y=x+.1*(sin(x.zxy*.17+u4[0]*.5)+sin(x.yzx*.7+u4[0]*1.5))*8.5*(1.+cos(sin(x.z*.1)+x.z*.3)),z=14.-length(y.xy),w=x.x==.0?1.570795*(x.y>.0?1.:-1.):atan(x.y,x.x),q=8.35-u4[8]*1.35,y=!3(9.*(mod(w+x.z*.02,.628)-.314),length(x.xy)-9.,mod(x.z,12.56)-6.28),u=min(length(y.xy)-.25+.1*cos(x.z*8.+u4[0]*.1),length(y.yz)-.5),y=!3(q*(mod(w+x.z*.02,1.256636)-.628318),y.y+9.-q,mod(x.z,62.8318)-31.4159),o=step(u,z)+1.,z=min(u,z),u=length(y)-1.3;if(u<z)z=u,o=3.;y.y+=q-9.,u=yyx(y.yz,8.)-2.;if(u<z)z=u,o=.0;return !2(z,o);',[[.25,0],[.5,.5]]],[6,.00025,1.08,.7,100,.000008,10,.03,2.1,.2,6,.4,5.1,[0,2,5],'z=1.,y=x;for(int i=0;i<7;i++)x=2.*clamp(x,-!3(.58,.9,1.1),!3(.58,.9,1.1))-x,w=max((1.3+u4[9]*.1*cos(u4[0]*.5))/dot(x,x),1.),x*=w,z*=w;w=length(x.xy),e=!2(w-3.,-w*x.z/length(x)-2.*log(1.+.01*a))/abs(z),w=max(e.x,e.y),o=step(e.y,e.x),y+=!3(.1,.3,-.4)*u0-u2+.25*sin(x*1.),e.x=length(y)-.1*u4[8];if(e.x<w)w=e.x,o=2.;return !2(w,o);',[[.05]]],[100,.000025,1,.75,80,.00005,.5,.3,3,.01,4,.75,4.75,[6,0,4],'x.xy*=t(a*.009),w=min(min(yz(x.xzy),yz(x)),yz(x.yzx)),y=mod(x,!3(15.))-!3(7.5),o=step(z=max(length(max(abs(y)-!3(2.5),!3(.0)))-.25,3.5-length(y)),w),w=min(w,z),z=length(y+.1*sin(y*5.5+u4[0]))-2.;if(z<w)w=z,o=2.;return !2(w,o);',[[.05]]],[20,.0005,1,.6,128,.0001,.5,.002,.01,.08,4,.5,1.75,[2,7],'y=x,y.xz=mod(x.xz,8.)-4.,y.yz*=t(u4[8]+.1*a),y.xy*=t(u4[8]*.5+.2*a),y.y*=.9+.1*sin(u4[8]*5.),w=max(length(y)-3.,-min(length(y)-2.8,max(mod(y.y,.8)-.4,-mod(y.y+.4,.8)+.4))),z=x.y+1.+sin(x.x*4.+u4[8]*2.)*sin(x.z+u4[8])*.1,o=clamp(.5+.5*(z-w)/1.,.0,1.),w=mix(z,w,o)-1.*o*(1.-o),y=x,y.xz=mod(y.xz,8.)-4.,y/=1.25+.25*sin(u4[8]*5.),y.xy*=t(u4[8]*5.),y.yz*=t(u4[8]*2.5),z=max(length(y)-1.,.04-length(max(abs(mod(y,.5)-.25)-!3(.15),!3(.0))));return !2(min(w,z),step(z,w));',[[.02],[.05,.5],[.05,.5]]]]; + +var tunMul=1; +var randAround = function(c,d) { return c - d + Math.random()*d*2 }; +var lightFunc = function(intensity,distance) { + return function(lctx) { + vecCopy(lctx[0],camPos); + lctx[1]=intensity; + lctx[2] = distance; + } +}; +var tun1CamCommon = function(dir) { + var z = demoTime*6; + vecSet(camPos,-6,0,z); + vecSet(lookAt,1,0,z); + vecSet(camUp,0,1,0); + misc[1] = 1; + misc[8] = 0; +}; +var desyncFunc = function(desync) { + return function(tt) { + var z = stepTime / direction[t][6]; + misc[4] = -z * desync; + if ( desync > 0 ) { + misc[4] += desync; + } + misc[4] *= randAround(.875,.125); + }; +}; +var balls1CamFunc = function(lax,laz,desync) { + var dsf = desyncFunc(desync); + return function() { + var z = demoTime*3; + vecSet(camPos,0,4,z); + vecSet(lookAt,lax,0,z+laz); + vecSet(camUp,0,0,1); + misc[8]= misc[2] = 0; + dsf(); + }; +}; +var balls2CamCommon = function() { + var z = demoTime*5; + vecSet(camPos,Math.cos(demoTime)*12,8,Math.sin(demoTime)*12+z); + vecSet(lookAt,1,0,z); + vecSet(camUp,0,1,0); + toNearPlane = 2.5; + z = demoTime - direction[43][5]; + misc[8]=z; +}; +var balls2LightFunc = function(scale) { + return function(lctx) { + var z = demoTime*30; + vecSet(lctx[0],scale*Math.cos(demoTime*2)*5,3,scale*Math.sin(demoTime*2)*5+z); + lctx[1] = 1; + lctx[2] = 4; + }; +}; +var fract1CamCommon = function() { + var z = demoTime; + vecSet(camPos,4,2.5+.025*z,6.7); + vecSet(lookAt,0,2.5-.05*z,6.7); + vecSet(camUp,0,0,1); + misc[8] = misc[9] = 0; + toNearPlane = 3; +}; +var fract1CamFunc = function(desync) { + var dsf = desyncFunc(desync); + return function(){ + fract1CamCommon(); + dsf(); + }; +}; +var fract2CamCommon = function(bs) { + vecSet(camPos,5*Math.sin(demoTime*.2),9*Math.cos(demoTime*.41),7.8); + vecCopy(lookAt,camPos); + lookAt[0] = Math.cos(demoTime*.2); + lookAt[1] = Math.sin(demoTime*.33); + lookAt[2] -= 2; + vecSet(camUp,0,0,1); + toNearPlane = 3; + misc[8] = bs; + misc[9] = 1; +}; + +var drawText = function(str,x) { + twoDCtx.shadowBlur = c2height/5; + twoDCtx.fillText( str , x , c2height / 2 ); + twoDCtx.shadowBlur = 0; + twoDCtx.strokeText( str , x , c2height / 2 ); +}; +var titleText = function(str,shake,alpha,r,g,b) { + drawText( str , canvasWidth/15 ); + misc[5] = 1 - c2rHeight + randAround(0,shake); + misc[6] = alpha; + vecSet( textColour , r , g , b ); +}; +var greetingsText = function() { + var t = ( demoTime - direction[34][5] ) * canvasWidth * .5; + drawText( "Greetings to ... Mog, Sycop, Tim & Wullon ... Adinpsz ... Alcatraz ... ASD ... Bits'n'Bites ... Brain Control ... Cocoon ... Conspiracy ... Ctrl+Alt+Test ... Fairlight ... Farbrausch ... Kewlers ... LNX ... Loonies ... Mercury ... Popsy Team ... Razor 1911 ... RGBA ... 7th Cube ... Still ... TPOLM ... TRBL ... Umlaut Design ... X-Men ... Youth Uprising ... Everyone here at DemoJS 2014!" , canvasWidth - t ); + misc[5] = 1 - c2rHeight + randAround(.01,.01); + misc[6] = 1; + vecSet( textColour , 1 , 1 , 1 ); +}; + +var squaresCam = function() { + var t = demoTime - direction[25][5]; + var z = t*10 - 80; + vecSet(camPos,z,0,0); + vecSet(lookAt,z+Math.cos(t*.5) * 80,Math.sin(t*.25)*40,100); + vecSet(camUp,0,1,0); +}; + +var squaresCam2 = function(s) { + var t = demoTime - direction[s][5]; + var z = t*20 - 80; + vecSet(camPos,0,0,z); + vecSet(lookAt,Math.cos(t*.5) * 80,Math.sin(t*.25)*40,z+100); + vecSet(camUp,Math.sin(t),Math.cos(t),0); + misc[4] = randAround(.0125,.0125); +}; + +var tunnelLight = function(lctx) { + vecSub(lctx[0],camPos,vecNorm(lctx[0],lookAt)); + lctx[0][1] -= .5; + lctx[1] = 3; + lctx[2] = 30; +}; +var tunnelCam = function(mul) { + var z = demoTime*30*tunMul; + vecSet(camPos,1.1*Math.cos(z*.1),Math.sin(z*.02),z); + z += 5; + vecSet(lookAt,-Math.sin(z*.05),-.7*Math.cos(z*.033),z); + vecSet(camUp,0,1,0); + toNearPlane = 2; +}; +var tunnelLightBall = function(lctx) { + vecSet(lctx[0] , 4*Math.sin(demoTime*.5)*Math.cos(demoTime*.7) , + 3*Math.cos(demoTime*1.5), + demoTime*30*tunMul+14+16*Math.sin(demoTime*3.3)*Math.cos(demoTime*.77) + ); + lctx[1] = 1; + lctx[2] = 15; +}; + +// direction 0<->rows / 1<->rm / 2<->setGlobals / 3<->lights / 4<->updateText / 5<->startTime / 6<->time / 7<->endTime +var direction = [ + [ + // Music rows + 36 , + // Raymarcher id + 0 , + function( ) { + tun1CamCommon(); + misc[2] = 1 - rStepTime*rStepTime*rStepTime; + toNearPlane = 5; + } , + [ + lightFunc(3,20) + ] + ] , [ + 18 , + 0 , + function( ) { + tun1CamCommon(); + toNearPlane = 5 - 2.25 * rStepTime; + misc[2] = 0; + } , + [ + lightFunc(3,20) + ] + ] , [ + 36 , + 0 , + function( ) { + tun1CamCommon(); + toNearPlane = 2.75 - 2.25 * rStepTime; + misc[2] = rStepTime; + } , + [ + lightFunc(3,20) + ] + ] , [ + 18 , + 3 , + function( ) { + var z = demoTime*3; + vecSet(camPos,0,4,z); + vecSet(lookAt,4,0,z); + vecSet(camUp,0,0,1); + z = rStepTime; + z *= z*z; + misc[2] = 1 - z; + toNearPlane = 2.5; + } , + [ + lightFunc(.75,8) + ] + ] , [ + 22 , + 3 , + balls1CamFunc(4,0,0) , + [ + lightFunc(1,8) + ] + ] , [ + 22 , + 3 , + balls1CamFunc(2,-2,0) , + [ + lightFunc(1,8) + ] + ] , [ + 3 , + 3 , + balls1CamFunc( 6 , 0 , -.5 ) , + [ + lightFunc(.5,4) + ] + ] , [ + 9 , + 3 , + balls1CamFunc( 6 , 0 , .5 ) , + [ + lightFunc(.5,4) + ] + ] , [ + 3 , + 3 , + balls1CamFunc( 2 , 2 , -.2 ) , + [ + lightFunc(1,8) + ] + ] , [ + 9 , + 3 , + balls1CamFunc( 2 , 2 , .2 ) , + [ + lightFunc(1,8) + ] + ] , [ + 3 , + 3 , + balls1CamFunc( 2 , 5 , -.7 ) , + [ + lightFunc(1,2) + ] + ] , [ + 7 , + 3 , + balls1CamFunc( 2 , 2 , .7 ) , + [ + lightFunc(1,2) + ] + ] , [ + 9 , + 3 , + function() { + var z = demoTime*3; + misc[2] = rStepTime; + vecSet(camPos,0,4+rStepTime*2,z); + vecSet(lookAt,2,0,z+2); + vecSet(camUp,0,0,1); + misc[3] = 1; + } , + [ + lightFunc(1,2) + ] + ] , [ + 21 , + 1 , + function( ) { + fract1CamCommon(); + misc[3] = 1; + misc[2] = 1 - rStepTime*rStepTime*rStepTime; + } , [ + fractLight = function(lctx) { + vecCopy(lctx[0],camPos); + lctx[0][2]+=2; + lctx[1] = 1; + lctx[2] = 3; + } + ] + ] , [ + 14 , + 1 , + fract1CamFunc(0) , + [ + fractLight + ] + ] , [ + 3 , + 1 , + fract1CamFunc(-.4) , + [ fractLight ] + ] , [ + 9 , + 1 , + fract1CamFunc(.4) , + [ fractLight ] + ] , [ + 3 , + 1 , + fract1CamFunc(-.2) , + [ fractLight ] + ] , [ + 9 , + 1 , + fract1CamFunc(.2) , + [ fractLight ] + ] , [ + 12 , + 1 , + function() { + fract1CamCommon(); + misc[4] = -( 6 * rStepTime ) % 1; + misc[4] *= randAround(.875,.125); + } , + [ fractLight ] + ] , [ + 22 , + 1 , + function() { + fract1CamCommon(); + misc[3] = .4; + misc[2] = rStepTime; + toNearPlane = 3 - 2.5*Math.max(1,2*rStepTime); + misc[4] = ( 30 * misc[2] ) % 1; + misc[4] *= randAround(.925,.075); + } , + [ fractLight ] + ] , [ + 3 , + 1 , + neutral = function() { + fract1CamCommon(); + misc[3] = .4; + misc[2] = 1; + misc[4] = 0; + } , + [ fractLight ] + ] , [ + 12 , + 1 , + neutral , + [ fractLight ], + function() { + titleText( "TheT(ourist)" , .08 , 1 , 1 , 1 , 1 ); + } + ] , [ + 12 , + 1 , + neutral , + [ fractLight ], + function() { + titleText( "TheT(ourist)" , .08 , 1 - rStepTime , 1 , 1 , 1 ); + } + ] , [ + 12 , + 1 , + neutral , + [ fractLight ], + function() { + titleText( "presents" , .08 , 1 - rStepTime , 1 , 1 , 1 ); + } + ] , [ + 20 , + 2 , + function() { + squaresCam(); + toNearPlane = 2.5; + misc[2] = 1 - rStepTime; + } , + [ lightFunc(1,30) ], + function() { + titleText( "Sine City" , .04 , rStepTime , 1 , 1 , 1 ); + } + ] , [ + 52 , + 2 , + function() { + squaresCam(); + misc[2] = 0; + } , + [ lightFunc(1,30) ], + function() { + titleText( "Sine City" , .04 , 1 , 1 , 1 , 1 ); + } + ] , [ + 12 , + 2 , + function(){ + squaresCam(); + misc[3] = 1; + misc[2] = Math.max(0,1-rStepTime*2); + } , + [ lightFunc(1,30) ], + function() { + titleText( "Sine City" , .04 , 1 , 1 - rStepTime , 1 - rStepTime * .5 , 1 - rStepTime ); + } + ] , [ + 12 , + 2 , + function() { + squaresCam(); + misc[4] = ( 1 - rStepTime ) * .7 + randAround(.0125,.0125); + misc[1] = 1 - .5 * rStepTime; + } , + [ lightFunc(1,30) ], + function() { + titleText( "Sine City" , .04 , 1 , 0 , .5 , 0 ); + } + ] , [ + 9 , + 2 , + function() { + squaresCam2(29); + misc[2] = Math.max(0,1-rStepTime*1.5); + misc[4] += ( rStepTime - 1 ) * .3; + misc[1] = .5 - .5 * rStepTime; + } , + [ lightFunc(1,30) ], + function() { + titleText( "Sine City" , .04 , 1 - rStepTime , 0 , .5 , 0 ); + } + ] , [ + 69 , + 2 , + function() { + squaresCam2(29); + misc[1] = 0; + } , + [ lightFunc(1,30) ] + ] , [ + 11 , + 2 , + function() { + squaresCam2(29); + misc[3] = .2; + misc[2] = rStepTime; + } , + [ lightFunc(1,30) ] + ] , [ + 11 , + 0 , + function() { + tunnelCam(); + misc[2] = 1 - rStepTime; + } , + [ tunnelLight ] + ] , [ + 17 , + 0 , + function() { + tunnelCam(); + misc[2] = 0; + misc[4] = (1.2 - 1.2 * rStepTime) * randAround(1,.02); + } , + [ tunnelLight ] + ] , [ + 18 , + 0 , + function() { + tunnelCam(); + misc[4] = 0; + misc[8] = rStepTime; + } , + [ tunnelLight ], + greetingsText + ] , [ + 36 , + 0 , + function() { + tunnelCam(); + misc[2] = 1 - Math.min(4*rStepTime,1); + misc[8] = 1; + } , + tunLights = [ tunnelLight , tunnelLightBall ], + greetingsText + ] , [ + 33 , + 0 , + function() { + tunnelCam(); + misc[2] = rStepTime; + misc[3] = .7; + misc[4] = -((4*rStepTime)%1)*randAround(1,.05); + } , + tunLights , + greetingsText + ] , [ + 9 , + 1 , + function() { + fract2CamCommon(0); + misc[2] = rStepTime; + misc[3] = 1; + } , + [ fractLight ], + greetingsText + ] , [ + 20 , + 1 , + function() { + fract2CamCommon(rStepTime); + misc[2] = 0; + } , + [ fractLight ], + greetingsText + ] , [ + 31 , + 1 , + function() { + fract2CamCommon(1); + misc[2] = Math.min(0,1-5*rStepTime); + } , + [ fractLight ], + greetingsText + ] , [ + 5 , + 1 , + function() { + fract2CamCommon(1); + misc[2] = 1-rStepTime; + } , + [ fractLight ], + greetingsText + ] , [ + 18 , + 1 , + function() { + fract2CamCommon(1); + misc[2] = Math.min(0,1-5*rStepTime); + misc[4] = Math.max(0,1.6*rStepTime - .8 )*randAround(1,.05); + } , + [ fractLight ], + greetingsText + ] , [ + 12 , + 1 , + function() { + fract2CamCommon(1); + misc[3] = .1; + misc[2] = rStepTime; + misc[4] = .8*(1-rStepTime)*randAround(1,.1); + } , + [ fractLight ], + greetingsText + ] , [ + 22 , + 3 , + function() { + balls2CamCommon(); + misc[2] = 1-rStepTime; + misc[4] = 0; + } , + ballsLights = [ lightFunc(.6,30) , balls2LightFunc(1),balls2LightFunc(-1) ], + greetingsText + ] , [ + 59 , + 3 , + function() { + balls2CamCommon(); + misc[3] = .8; + misc[2] = Math.max(0,1-(12*rStepTime)%4); + } , + ballsLights, + greetingsText + ] , [ + 8 , + 3 , + function() { + balls2CamCommon(); + misc[3] = .1; + misc[2] = rStepTime; + misc[4] = randAround(.1,.1); + } , + ballsLights + ] , [ + 7 , + 0 , + function() { + tunMul = 2; + tunnelCam(); + misc[2] = 1-rStepTime; + misc[4] = randAround(.1,.1); + } , + tunLights + ] , [ + 22 , + 0 , + function() { + tunnelCam(); + misc[4] = randAround(.1,.1); + } , + tunLights + ] , [ + 10 , + 0 , + function() { + tunnelCam(); + misc[4] = stepTime*4+randAround(.1,.1); + misc[3] = 1; + misc[2] = rStepTime; + } , + tunLights + ] , [ + 10 , + 2 , + function() { + squaresCam2(49); + misc[4] = (demoTime-direction[48][5])*4+randAround(.1,.1); + misc[2] = 1-rStepTime; + } , + [ lightFunc(1,30) ] + ] , [ + 40 , + 2 , + function() { + squaresCam2(49); + misc[4] = -(demoTime-direction[48][5])*6; + } , + [ lightFunc(1,30) ] + ] , [ + 40 , + 2 , + function() { + squaresCam2(49); + misc[4] = (demoTime-direction[48][5])*8; + misc[3] = 0; + misc[2] = rStepTime; + } , + [ lightFunc(1,30) ] + ] , [ + 68 , + 2 , + function() { + squaresCam2(49); + misc[2] = 1 + } , + [ lightFunc(1,30) ] + ] +]; +var t = 0; +for ( var i in direction ) { + direction[ i ][5] = t; + t += ( direction[i][6] = direction[ i ][0] * .125 ); + direction[ i ][7] = t; +} +t = 0; + +function createRaymarcherCode( def ) { + var w = 'uniform '; + var code = shaderHeader + + [ w+'mat3 u0;' , + w+'sampler2D u1;' , + w+'!3 u2,u3;' , + w+'float u4[10];' + ].join('\n'); + var u = 5; + for ( var i in def[15] ) { + code += w+'!3 u' + u++ + ';'+w+'float u' + u++ + ', u' + u++ + ';'; + } + code += [ + "const !2 c=!2(1.,-1.)*"+def[5]+";" , + "float p,z,w,u,o,zy,q,x,a,zz;" , + "!2 e,h;" , + "!3 l=!3(zx,1.),m,r,s=u2,yx=!3(1.),n=!3(.0),b,v,xxx,xy,d,xx,xz,y;" , + "!4 f;" , + + "float g(float x)" , + "{" , + "return fract(sin(x)*43758.5453);" , + "}" , + + "float yy(!3 x)" , + "{" , + "m=floor(x),y=fract(x)," , + "y*=y*(3.-2.*y)," , + "z=m.x+m.y*57.+m.z*113.;" , + "return mix(mix(mix(g(z),g(z+1.),y.x)," , + "mix(g(z+57.),g(z+58.),y.x),y.y)," , + "mix(mix(g(z+113.),g(z+114.),y.x)," , + "mix(g(z+170.),g(z+171.),y.x),y.y),y.z);" , + "}" , + + "float yyx(!2 x,float a)" , + "{" , + "e=pow(abs(x),!2(a));" , + "return pow(e.x+e.y,1./a);" , + "}" , + + "mat2 t(float x)" , + "{" , + "e=!2(cos(x),sin(x));" , + "return mat2(-e.x,e.y,e.y,e.x);" , + "}" , + + "float yz(!3 x)" , + "{" , + "return length(mod(x.xy,!2(15.))-!2(7.5))-.5+.05*sin(x.z*9.42477);" , + "}" , + + "!2 k(!3 x,float a) {" + ].join("\n"); + code += def[14] + '}'; + code += [ + "void main()" , + "{" , + "l.y+=mod(u4[4],1.)*2.2;" , + "if(l.y>1.){" , + "if(l.y < 1.2)discard;" , + "l.y-=2.2;" , + "}" , + "l.x*=1.6," , + "r=normalize(l*u0);" , + + "for(int j=0;j<2;j++){" , + "v=r,xxx=s,xy=!3(.0)," , + "x=.0,a=" + def[1] + ';' , + "for(int i=0;i<" + def[4] + ";i++){" , + "h=k(s+r*x,x);" , + "if(h.x< a||i>" + def[4] + "/(j+1)||x>" + def[0] + ".)break;" , + "x+=h.x*" + def[3] + ",a*=" + shaderFloat( def[2] ) + ";" , + "}" , + "h.x=x;", + + "if(x<"+ def[0]+ ".){" , + "d=s+r*x," , + "f=!4(" , + "k(d+c.xyy,x).x," , + "k(d+c.yyx,x).x," , + "k(d+c.yxy,x).x," , + "k(d+c.xxx,x).x" , + ")," , + "xx=normalize(f.x*c.xyy+f.y*c.yyx+f.z*c.yxy+f.w*c.xxx)," , + "a=.0," , + "p=" + def[12] + ";" , + "for(int i=1;i<="+def[10]+";i++)" , + "x=(float(i)/"+def[10]+".)*"+ shaderFloat( def[11] ) + "," , + "m=d+xx*x," , + "a+=p*(x-k(m,distance(m,s)).x)," , + "p*=.5;" , + "q=max(.1,1.-clamp(pow(a,1.),.0,1.));" , + ].join('\n'); + + for(var i in def[13]) + w=materials[def[13][i]],code+=(i>0?'else ':'')+'if(h.y==' + i + '.)xz='+(w[4]?('mix(!3('+shaderVec(w[0])+'),!3('+shaderVec(w[5])+'),yy(d*'+shaderFloat(def[6]*w[4])+'))'):('!3('+shaderVec(w[0])+')'))+',w='+shaderFloat(w[1])+',u='+w[2]+',o='+w[3]+';'; + + code += [ + "v=reflect(r,xx)," , + "z="+def[9]+"*h.x," , + "z=clamp(exp(-z*z*z*1.442695),.0,1.)," , + "x=clamp((1.+dot(normalize(v+r),r)),.0,1.),a=x*x," , + "zz=o+(1.-o)*x*a*a*(u*.9+.1)," , + "y=mix(!3(1.),xz/dot(!3(.299,.587,.114),xz),w)," , + "m=!3(.0)," , + "zy=exp2(4.+6.*u)," , + ].join('\n'); + + u = 5; + for ( var l in def[15] ) { + var b = def[15][l]; + code += [ + "p=length(b=u" + u + "-d)," , + "b/=p," , + "p=max(1.,p-u" + (u+2) + ")*" + b[0] + "," , + "p=1./max(1.,p*p)," , + "m+=mix((1.-w)*xz*q,y*pow(max(dot(reflect(r,xx),b),.0),zy)*(zy+2.)/8.,zz)*p*max(dot(b,xx),.0)*!3(u" + (u+1) + ")," + ].join('\n'); + u+=3; + } + code += [ + "xy=yx*z*normalize(y)*o*(u*.9+.1)*zz," , + "m=mix(!3(" + shaderFloat(def[8]) + "),m,z)," , + "xxx+=normalize(v)*" + def[7] + ";" , + "}else" , + "m=!3(" + shaderFloat(def[8]) + ');' + ].join('\n'); + + u=5; + for ( var l in def[15] ) { + var b = def[15][l]; + var h = b[1]; + if ( h ) { + code += [ + "b=s-u" + u + "," , + "p=dot(r,r),a=2.*dot(b,r)," , + "x=a*a-4.*p*(dot(b,b)-" + (h*h) + ")," , + "e=x<.0?!2(-1.):(x=sqrt(x),-.5*!2(a+x,a-x)/p)," , + "e=!2(min(e.x,e.y),max(e.x,e.y));" , + "if(e.x>.0&&e.y<h.x)" , + "m+=u" + (u+2) + "*!3(u" + (u+1) + ")*pow((e.y-e.x)/" + shaderFloat(h*2) + ",64.);" + ].join( "\n" ); + } + u+=3; + } + + code += [ + "n+=m*yx;" , + "if(all(lessThan(xy,!3(.01))))break;" , + "yx=xy," , + "s=xxx," , + "r=normalize(v);" , + "}" , + + "h=!2(zx.x,l.y)*.5+.5," , + "h.y=(1.-h.y-u4[5])/u4[7]," , + "f=texture2D(u1,h)," , + "n=max(!3(.0),mix(mix(mix(n,(n.x==n.y&&n.x==n.z)?n:!3(dot(n,!3(.299,.587,.114))),u4[1]),!3(u4[3]),smoothstep(.05,.95,u4[2])),f.rgb*u3,f.a*u4[6])-!3(.004)),", + + "x=(l.x+1.)*(l.y+1.)*(u4[0]*10.),", + "gl_FragColor=!4((1.-(smoothstep(.98,1.,yy(l*8.+u4[0]*20.))+smoothstep(.95,1.,yy(l*1.5+u4[0]*10.))))*smoothstep(1.042+.008*cos(u4[0]*40.),.8,yyx(zx,8.))*(1.-(mod((mod(x,13.)+1.)*(mod(x,47.)+1.),.01))*8.)*((.95+.05*cos(u4[0]*41.))*(n*(6.2*n+.5))/(n*(6.2*n+!3(1.7))+!3(.06))+!3(smoothstep(.98,1.,yy(l*8.-u4[0]*40.)))),1.);", + "}" , + ].join('\n'); + return code; +} + +var cmU=vomNew(3), + cmV=vomNew(3), + cmW=vomNew(3), + cd=vomNew(3), + cu=vomNew(3), + cm=vomNew(9); + + +// Main + +function resize() { + var vw=window.innerWidth,vh=window.innerHeight; + var cw=Math.floor(vh*1.6),ch=Math.floor(vw*.625); + if(cw>vw){ + C1.width=canvasWidth=vw; + C1.height=canvasHeight=ch; + }else{ + C1.width=canvasWidth=cw; + C1.height=canvasHeight=vh; + } + C2.style.width=C2.width=canvasWidth; + c2height=C2.style.height=C2.height=Math.max(canvasHeight/8,100); + c2rHeight=c2height/canvasHeight; + twoDCtx.shadowColor = "#ccc"; + twoDCtx.font = "normal small-caps bold " + Math.floor(c2height/2) + "px monospace"; + twoDCtx.fillStyle = "#111"; + twoDCtx.strokeStyle = "#ddd"; + C1.style.left=Math.floor((vw-canvasWidth)*.5); + C1.style.top=Math.floor((vh-canvasHeight)*.5); + glCtx.viewport(0,0,canvasWidth,canvasHeight); +} + +// FIXME: re-enable! document.body.style.cursor = 'none'; +document.body.style.background = 'black'; +document.body.innerHTML = '<canvas id=C1 style=position:fixed></canvas><canvas id=C2 style=display:none>'; +glCtx=C1.getContext('webgl'); +twoDCtx = C2.getContext('2d'); +(window.onresize=resize)(); +var shaders = [ + [ glCtx.VERTEX_SHADER , shaderHeader + "attribute !2 i;void main(){gl_Position=!4(i,.0,1.),zx=i;}" + ] +]; +var programs = {}; +var misc = vomNew(10) , camPos = vomNew(3),lookAt=vomNew(3),camUp=vomNew(3),toNearPlane=0,textColour=vomNew(3) , lights= [[vomNew(3),0,0],[vomNew(3),0,0],[vomNew(3),0,0]]; +var sn = 1; +for ( var i in raymarchers ) { + var rm = raymarchers[i]; + shaders[sn] = [glCtx.FRAGMENT_SHADER,createRaymarcherCode(rm)]; + programs[i] = [ 5+rm[15].length*3 , 0 , sn++ ]; +} +for ( var i in shaders ) { + var def = shaders[i]; + glCtx.shaderSource( i= shaders[i] = glCtx.createShader( def[0] ) , def[1].replace(/!/g,'vec') ); + glCtx.compileShader( i ); + if (!glCtx.getShaderParameter(i, glCtx.COMPILE_STATUS)) { + def[1] = def[1].split( /\n/ ); + for ( var k in def[1] ) { + var j = parseInt(k)+1; + def[1][k] = j + ": " + def[1][k]; + } + throw "SHADER ERROR\n" + glCtx.getShaderInfoLog(i) + "\n" + def[1].join('\n'); + } +} +for ( var name in programs ) { + var p = glCtx.createProgram( ); + var d = programs[name]; + var ul = d.shift(); + while( d.length ) { + glCtx.attachShader( p , shaders[ d.shift() ] ); + } + glCtx.linkProgram( p ); + var nul = []; + while ( ul-- ) { + nul[ul] = glCtx.getUniformLocation( p , 'u' + ul ); + } + programs[name] = [p,nul]; +} +vtxBuffer = glCtx.createBuffer( ); +glCtx.bindBuffer( glCtx.ARRAY_BUFFER , glCtx.createBuffer( ) ); +glCtx.bufferData( glCtx.ARRAY_BUFFER , vomNew([1,4,1,-1,-4,-1]) , glCtx.STATIC_DRAW ); +glCtx.clearColor(0,0,0,1); + +textTexture = glCtx.createTexture( ); +glCtx.bindTexture( glCtx.TEXTURE_2D , textTexture ); +glCtx.texParameteri( glCtx.TEXTURE_2D , glCtx.TEXTURE_WRAP_S, glCtx.CLAMP_TO_EDGE ); +glCtx.texParameteri( glCtx.TEXTURE_2D , glCtx.TEXTURE_WRAP_T, glCtx.CLAMP_TO_EDGE ); +glCtx.texParameteri( glCtx.TEXTURE_2D , glCtx.TEXTURE_MIN_FILTER, glCtx.NEAREST ); +glCtx.texParameteri( glCtx.TEXTURE_2D , glCtx.TEXTURE_MAG_FILTER, glCtx.NEAREST ); +glCtx.texImage2D( glCtx.TEXTURE_2D , 0 , glCtx.RGBA , glCtx.RGBA , glCtx.UNSIGNED_BYTE , C2 ); + +timeStart = previousFrame = 0; +FRAME_TIME = 100/3; + +paused = 0; +document.body.onkeypress = function(e) { + if ( e.keyCode == 32 ) { + var now = Date.now(); + if ( paused ) { + timeStart += now - paused; + paused = 0; + requestAnimationFrame(draw); + A.play( ); + } else { + paused = now; + A.pause( ); + } + } +}; + +var demoTime, rStepTime,stepTime; +mainfunc = function(){setTimeout(function(){ +requestAnimationFrame(draw=function(time){ + if ( ! paused ) { + requestAnimationFrame(draw); + } + if ( timeStart == 0 ) { + A.currentTime = 0; + A.play( ); + timeStart = time; + previousFrame = timeStart - FRAME_TIME; + } + var delta = time - previousFrame; + demoTime = .001*(time - timeStart); + if ( delta < FRAME_TIME ) { + return; + } + previousFrame = time - ( delta % FRAME_TIME ); + + var ds = direction[t]; + while ( ds && ds[7] < demoTime ) { + ds=direction[++t]; + } + if ( ! ds ) { + A.pause( ); + return; + } + misc[0] = demoTime; + misc[7] = c2rHeight; + stepTime = demoTime - ds[5]; + rStepTime = stepTime / ds[6]; + if ( ds[4] ) { + twoDCtx.clearRect( 0 , 0 , canvasWidth , 100 ); + ds[4](); + glCtx.texImage2D( glCtx.TEXTURE_2D , 0 , glCtx.RGBA , glCtx.RGBA , glCtx.UNSIGNED_BYTE , C2 ); + } + + ds[2](); + vecNorm(cmW,vecSub(cmW,lookAt,camPos)); + vecNorm(cmU,vecCross(cmU,camUp,cmW)); + vecNorm(cmV,vecCross(cmV,cmW,cmU)); + vecScale(cmW,cmW,toNearPlane); + vecs2Mat3(cm,cmU,cmV,cmW); + + for ( var i in ds[3] ) { + ds[3][i](lights[ i ]); + } + + var p = programs[ds[1]]; + glCtx.useProgram( p[ 0 ] ); + glCtx.enableVertexAttribArray( 0 ); + glCtx.vertexAttribPointer( 0 , 2 , glCtx.FLOAT , false , 8 , 0 ); + p = p[1]; + + var u = 0; + glCtx.uniformMatrix3fv( p[u++] , false , cm ); + glCtx.uniform1i( p[u++] , 0 ); + glCtx.uniform3fv( p[u++] , camPos ); + glCtx.uniform3fv( p[u++] , textColour ); + glCtx.uniform1fv( p[u++] , misc ); + for ( var i in ds[3] ) { + glCtx.uniform3fv( p[u++] , lights[ i ][0] ); + glCtx.uniform1f( p[u++] , lights[ i ][1] ); + glCtx.uniform1f( p[u++] , lights[ i ][2] ); + } + glCtx.drawArrays( 4 , 0 , 3 ); +}) +},500)}; + +if ( USE_SYNTH ) { + synthGen = setInterval(function(){ + var i,j,a,n,b,k,t,e,c,d=new Int32Array(mNumWords),f=song[mCurrentCol],g,h,l,m,o=[],q,r,s,u,v,p; + for(g=h=m=p=0;p<=26;p++)for(b=f[1][p],a=0;a<36;a++){((e=b?f[2][b-1][1][a]:0)?((f[0][e-1]=f[2][b-1][1][a+36]||0),e<14?(o=[]):0):0),c=(p*36+a)*5513;for(j=0;j<4;j++)if(n=b?f[2][b-1][0][a+j*36]:0){if(!o[n])for(q=f[0][10],r=f[0][11],s=f[0][12],t=getnotefreq(n+f[0][2]-128),l=getnotefreq(n+f[0][6]-128)*(1+.0008*f[0][7]),u=v=0,q*=q*4,r*=r*4,s*=s*4,o[n]=new Int32Array(q+r+s),k=0;k<q+r+s;k++)e=k<q?(k/q):(1-(k<q+r?0:((k-q-r)/s))),o[n][k]=(80*(mOscillators[f[0][0]](u+=t*(f[0][3]?(e*e):1))*f[0][1]+mOscillators[f[0][4]](v+=l*(f[0][8]?(e*e):1))*f[0][5]+randAround(0,1)*f[0][9])*e)|0;for(k=0,i=c*2;k<o[n].length;k++,i+=2)d[i]+=o[n][k]}q=f[0][20]*1e-5,r=f[0][24]/255,s=f[0][25]*5513;for(j=0;j<5513;j++)(((n=e=d[k=(c+j)*2])||m)?(t=1.5*Math.sin(f[0][18]*.00307999186353015873*(f[0][16]?(mOscillators[f[0][13]](Math.pow(2,f[0][15]-9)*k/5513)*f[0][14]/512+.5):1)),g+=t*h,l=(1-f[0][19]/255)*(e-h)-g,h+=t*l,e=f[0][17]==3?h:f[0][17]==1?l:g,q?(e*=q,e=(e<1?e>-1?mOscillators[0](e*.25):-1:1)/q):0,e*=f[0][21]/32,m=e*e>1e-5,t=Math.sin(6.283184*Math.pow(2,f[0][23]-9)*k/5513)*f[0][22]/512+.5,n=e*(1-t),e*=t):0),(k>=s?(n+=d[k-s+1]*r,e+=d[k-s]*r):0),mMixBuf[k]+=(d[k]=n|0),mMixBuf[k+1]+=(d[k+1]=e|0)} + if(++mCurrentCol==8)for(clearInterval(synthGen),s=(f=String.fromCharCode).apply(String,[82,73,70,70,168,16,71,1,87,65,86,69,102,109,116,32,16,0,0,0,1,0,2,0,68,172,0,0,16,177,2,0,4,0,16,0,100,97,116,97,132,16,71,1]),i=0;i<mNumWords||(((A=document.createElement("audio")).src='data:audio/wav;base64,'+btoa(s),A.oncanplaythrough=mainfunc)&&0);i++)e=mMixBuf[i],e=e<-32767?-32767:(e>32767?32767:e),s+=f(e&255,(e>>8)&255) + }, 0); +} else { + A = document.createElement("audio"); + A.oncanplaythrough=mainfunc; + A.src= 'music.ogg'; +} diff --git a/201410_-_Sine_City/sine-city-packing-5-misc.html b/201410_-_Sine_City/sine-city-packing-5-misc.html new file mode 100644 index 0000000..fc0a717 --- /dev/null +++ b/201410_-_Sine_City/sine-city-packing-5-misc.html @@ -0,0 +1,3 @@ +<body> +<script language="javascript" src="sine-city-packing-5-misc.js"></script> + diff --git a/201410_-_Sine_City/sine-city-packing-5-misc.js b/201410_-_Sine_City/sine-city-packing-5-misc.js new file mode 100644 index 0000000..1cc5f01 --- /dev/null +++ b/201410_-_Sine_City/sine-city-packing-5-misc.js @@ -0,0 +1,489 @@ +var USE_SYNTH = 0; + +with(Math)S=sin,C=cos,M=max,N=min,P=pow; + + +f = function(a,b,c){return eval('(function('+a+'){'+b+(b?';':'')+(c?('return '+c):'')+'})')}, + +getnotefreq=f('a','','.003959503758*P(2,(a-128)/12)'), +mOscillators=[ + f('a','','S(a*6.283184)'), + f('a','','(a%1)<.5?1:-1'), + f('a','','2*(a%1)-1'), + f('a,b','b=(a%1)*4','(b<2)?(b-1):(3-b)') +], + +// Vector stuff +vecOp=f('a','','f(\'a,b,c\',\'for(var i=a.length;--i>=0;)\'+a,\'a\')'), +vomNew=f('a','','new Float32Array(a)'), +vecNorm=f('a,b,c','c=Math.sqrt(b[0]*b[0]+b[1]*b[1]+b[2]*b[2])','c?vecScale(a,b,1/c):vecCopy(a,b)'), +vecCross=f('a,b,c','','vecSet(a,b[1]*c[2]-b[2]*c[1],b[2]*c[0]-b[0]*c[2],b[0]*c[1]-b[1]*c[0])'), +vecSet=vecOp('a[i]=arguments[i+1]'), +vecCopy=vecOp('a[i]=b[i]'), +vecSub=vecOp('a[i]=b[i]-c[i]'), +vecScale=vecOp('a[i]=b[i]*c'), + + +// Shaders +shaderHeader='precision highp %;varying !2 zx;', +shaderFloat=f('a','','a+(a==(a|0)?\'.\':\'\')'), +shaderVec=f('a','','a.map(shaderFloat).join(\',\')'); + + +// Raymarchers + +materials = [[[.05],.7,.02,.01],[[.2],.7,.9,.01,5,[.1]],[[1],.5,.4,.02],[[3,0,0],.3,.1,.6,6,[.6,0,0]],[[0,2,0],.9,.5,.4,15,[0,.2,0]],[[3,1.5,0],.95,.6,.9,.3,[.3,.6,0]],[[.1],0,.04,.002,3,[3]],[[0,1.5,2],.9,.3,.4]]; +raymarchers = [[100,.025,1,.7,64,.0005,.5,.3,.4,.015,4,2,.75,[0,1,2,3],'y=x+.1*(sin(x.zxy*.17+u4[0]*.5)+sin(x.yzx*.7+u4[0]*1.5))*8.5*(1.+cos(sin(x.z*.1)+x.z*.3)),z=14.-length(y.xy),w=x.x==.0?1.570795*(x.y>.0?1.:-1.):atan(x.y,x.x),q=8.35-u4[8]*1.35,y=!3(9.*(mod(w+x.z*.02,.628)-.314),length(x.xy)-9.,mod(x.z,12.56)-6.28),u=min(length(y.xy)-.25+.1*cos(x.z*8.+u4[0]*.1),length(y.yz)-.5),y=!3(q*(mod(w+x.z*.02,1.256636)-.628318),y.y+9.-q,mod(x.z,62.8318)-31.4159),o=step(u,z)+1.,z=min(u,z),u=length(y)-1.3;if(u<z)z=u,o=3.;y.y+=q-9.,u=yyx(y.yz,8.)-2.;if(u<z)z=u,o=.0;return !2(z,o);',[[.25,0],[.5,.5]]],[6,.00025,1.08,.7,100,.000008,10,.03,2.1,.2,6,.4,5.1,[0,2,5],'z=1.,y=x;for(int i=0;i<7;i++)x=2.*clamp(x,-!3(.58,.9,1.1),!3(.58,.9,1.1))-x,w=max((1.3+u4[9]*.1*cos(u4[0]*.5))/dot(x,x),1.),x*=w,z*=w;w=length(x.xy),e=!2(w-3.,-w*x.z/length(x)-2.*log(1.+.01*a))/abs(z),w=max(e.x,e.y),o=step(e.y,e.x),y+=!3(.1,.3,-.4)*u0-u2+.25*sin(x*1.),e.x=length(y)-.1*u4[8];if(e.x<w)w=e.x,o=2.;return !2(w,o);',[[.05]]],[100,.000025,1,.75,80,.00005,.5,.3,3,.01,4,.75,4.75,[6,0,4],'x.xy*=t(a*.009),w=min(min(yz(x.xzy),yz(x)),yz(x.yzx)),y=mod(x,!3(15.))-!3(7.5),o=step(z=max(length(max(abs(y)-!3(2.5),!3(.0)))-.25,3.5-length(y)),w),w=min(w,z),z=length(y+.1*sin(y*5.5+u4[0]))-2.;if(z<w)w=z,o=2.;return !2(w,o);',[[.05]]],[20,.0005,1,.6,128,.0001,.5,.002,.01,.08,4,.5,1.75,[2,7],'y=x,y.xz=mod(x.xz,8.)-4.,y.yz*=t(u4[8]+.1*a),y.xy*=t(u4[8]*.5+.2*a),y.y*=.9+.1*sin(u4[8]*5.),w=max(length(y)-3.,-min(length(y)-2.8,max(mod(y.y,.8)-.4,-mod(y.y+.4,.8)+.4))),z=x.y+1.+sin(x.x*4.+u4[8]*2.)*sin(x.z+u4[8])*.1,o=clamp(.5+.5*(z-w)/1.,.0,1.),w=mix(z,w,o)-1.*o*(1.-o),y=x,y.xz=mod(y.xz,8.)-4.,y/=1.25+.25*sin(u4[8]*5.),y.xy*=t(u4[8]*5.),y.yz*=t(u4[8]*2.5),z=max(length(y)-1.,.04-length(max(abs(mod(y,.5)-.25)-!3(.15),!3(.0))));return !2(min(w,z),step(z,w));',[[.02],[.05,.5],[.05,.5]]]]; + +tunMul=1, +R=f('a,b','','a-b+Math.random()*b*2'), +lightFunc=f('a,b','','f(\'a\',\'vecCopy(a[0],camPos),a[1]=\'+a+\',a[2]=\'+b)'), + +tun1CamCommon=f('a','vecSet(camPos,-6,0,a=demoTime*6),vecSet(lookAt,misc[1]=1,misc[8]=0,a),vecSet(camUp,0,1,0)'), +desyncFunc=f('a','','f(\'\',\'misc[4]=(\'+(a>0?a:\'\')+\'-stepTime*\'+a+\'/direction[t][6])*R(.875,.125)\')'), +balls1CamFunc=f('a,b,c,d','c=desyncFunc(c),d=f(\'a,b,c,d\',\'vecSet(camPos,misc[2]=misc[8]=0,4,d=demoTime*3),vecSet(lookAt,a,0,d+b),vecSet(camUp,0,0,1),c()\')','function(){d(a,b,c)}'), +balls2CamCommon=f('a','a=demoTime*5,vecSet(camPos,C(demoTime)*12,8,S(demoTime)*12+a),vecSet(lookAt,1,0,a),vecSet(camUp,0,1,0),toNearPlane=2.5,misc[8]=demoTime-direction[43][5]'), +balls2LightFunc=f('a','','f(\'a\',\'vecSet(a[0],\'+a+\'*C(demoTime*2)*5,3,\'+a+\'*S(demoTime*2)*5+demoTime*30),a[1]=1,a[2]=4\')'), +fract1CamCommon=f('','vecSet(camPos,4,2.5+.025*demoTime,6.7),vecSet(lookAt,misc[8]=misc[9]=0,2.5-.05*demoTime,6.7),vecSet(camUp,0,0,1),toNearPlane=3'), +fract1CamFunc=f('a','a=desyncFunc(a)','function(){fract1CamCommon(),a()}'), +fract2CamCommon=f('a,b','vecSet(camPos,5*S(b=demoTime*.2),9*C(demoTime*.41),7.8),vecSet(lookAt,C(b),S(demoTime*.33),camPos[2]-2),vecSet(camUp,0,0,misc[9]=1),misc[8]=a,toNearPlane=3'), + +drawText=f('a,b,c','with(twoDCtx)shadowBlur=c2height/5,fillText(a,b,c=c2height/2),shadowBlur=0,strokeText(a,b,c)'), +titleParts=['TheT(ourist)','presents','Sine City'], +titleText=f('a,b,c,d,e,f','drawText(titleParts[a],canvasWidth/15),misc[5]=1-c2rHeight+R(0,b),misc[6]=c,vecSet(textColour,d,e,f)'), +greetingsText=f('','drawText(\'Greetings to ... Mog, Sycop, Tim & Wullon ... Adinpsz ... Alcatraz ... ASD ... Bits\\\'n\\\'Bites ... Brain Control ... Cocoon ... Conspiracy ... Ctrl+Alt+Test ... Fairlight ... Farbrausch ... Kewlers ... LNX ... Loonies ... Mercury ... Popsy Team ... Razor 1911 ... RGBA ... 7th Cube ... Still ... TPOLM ... TRBL ... Umlaut Design ... X-Men ... Youth Uprising ... Everyone here at DemoJS 2014!\',canvasWidth*(1-(demoTime-direction[34][5])/2)),misc[5]=1-c2rHeight+R(.01,.01),vecSet(textColour,misc[6]=1,1,1)'), +squaresCam=f('a,b','a=demoTime-direction[25][5],vecSet(camPos,b=a*10-80,0,0),vecSet(lookAt,b+C(a*.5)*80,S(a*.25)*40,100),vecSet(camUp,0,toNearPlane=2.5,0)'), +squaresCam2=f('a,b','a=demoTime-direction[a][5],vecSet(camPos,0,0,b=a*20-80),vecSet(lookAt,C(a*.5)*80,S(a*.25)*40,100+b),vecSet(camUp,0,1,0),misc[4]=R(a=.0125,a)'), +tunnelLight=f('a','vecSub(a[0],camPos,vecNorm(a[0],lookAt)),a[0][1]-=.5,a[1]=3,a[2]=30'), +tunnelCam=f('a','a=(demoTime-direction[a][5])*30*tunMul,vecSet(camPos,1.1*C(a*.1),S(a*.02),a),a+=5,vecSet(lookAt,-S(a*.05),-.7*C(a*.033),a),vecSet(camUp,0,toNearPlane=2,0)'), +tunnelLightBall=f('a','','f(\'a,b\',\'b=demoTime-direction[\'+a+\'][5],vecSet(a[0],4*S(b*.5)*C(b*.7),3*C(b*1.5),b*30*tunMul+14+16*S(b*3.3)*C(b*.77)),a[1]=1,a[2]=2\')'), + +// direction 0<->rows / 1<->rm / 2<->setGlobals / 3<->lights / 4<->updateText / 5<->startTime / 6<->time / 7<->endTime +direction = [ + [ + 36 , + 0 , + f('','tun1CamCommon(misc[2]=1-rStepTime*rStepTime*rStepTime,toNearPlane=5)') , + a=[lightFunc(3,20)] + ] , [ + 18 , + 0 , + f('','tun1CamCommon(misc[2]=0,toNearPlane=5-2.25*rStepTime)') , + a + ] , [ + 36 , + 0 , + f('','tun1CamCommon(misc[2]=rStepTime,toNearPlane=2.75-2.25*rStepTime)') , + a + ] , [ + 18 , + 3 , + f('a','vecSet(camPos,0,4,a=demoTime*3),vecSet(lookAt,4,0,a),vecSet(camUp,0,0,1),misc[2]=1-rStepTime*rStepTime*rStepTime,toNearPlane=2.5') , + [ lightFunc(.75,8) ] + ] , [ + 22 , + 3 , + balls1CamFunc(4,0,0) , + a=[lightFunc(1,8)] + ] , [ + 22 , + 3 , + balls1CamFunc(2,-2,0) , + a + ] , [ + 3 , + 3 , + balls1CamFunc( 6 , 0 , -.5 ) , + b=[lightFunc(.5,4)] + ] , [ + 9 , + 3 , + balls1CamFunc( 6 , 0 , .5 ) , + b + ] , [ + 3 , + 3 , + balls1CamFunc( 2 , 2 , -.2 ) , + a + ] , [ + 9 , + 3 , + balls1CamFunc( 2 , 2 , .2 ) , + a + ] , [ + 3 , + 3 , + balls1CamFunc( 2 , 5 , -.7 ) , + a=[ lightFunc(1,2) ] + ] , [ + 7 , + 3 , + balls1CamFunc( 2 , 2 , .7 ) , + a + ] , [ + 9 , + 3 , + f('a','vecSet(camPos,0,4+rStepTime*2,a=demoTime*3),vecSet(lookAt,2,0,a+2),vecSet(camUp,0,0,misc[3]=1),misc[2]=rStepTime') , + a + ] , [ + 21 , + 1 , + f('','fract1CamCommon(misc[2]=1-rStepTime*rStepTime*rStepTime,misc[3]=1)'), + a=[f('a','vecCopy(a[0],camPos),a[0][2]+=2,a[1]=1,a[2]=3')] + ] , [ + 14 , + 1 , + fract1CamFunc(0) , + a + ] , [ + 3 , + 1 , + fract1CamFunc(-.4) , + a + ] , [ + 9 , + 1 , + fract1CamFunc(.4) , + a + ] , [ + 3 , + 1 , + fract1CamFunc(-.2) , + a + ] , [ + 9 , + 1 , + fract1CamFunc(.2) , + a + ] , [ + 12 , + 1 , + f('','fract1CamCommon(misc[4]=(-(6*rStepTime)%1)*R(.875,.125))'), + a + ] , [ + 22 , + 1 , + f('','fract1CamCommon(misc[4]=((30*rStepTime)%1)*R(.925,.075),misc[2]=rStepTime,misc[3]=.4),toNearPlane=3-2.5*M(1,2*rStepTime)'), + a + ] , [ + 3 , + 1 , + b=f('','fract1CamCommon(misc[4]=0,misc[2]=1)'), + a + ] , [ + 12 , + 1 , + b , + a, + f('','titleText(0,.08,1,1,1,1)') + ] , [ + 12 , + 1 , + b , + a, + f('','titleText(0,.08,1-rStepTime,1,1,1)') + ] , [ + 12 , + 1 , + b , + a, + f('','titleText(1,.08,1-rStepTime,1,1,1)') + ] , [ + 20 , + 2 , + f('','squaresCam(misc[2]=1-rStepTime)') , + b=[lightFunc(1,30)], + f('','titleText(2,.04,rStepTime,1,1,1)') + ] , [ + 52 , + 2 , + f('','squaresCam(misc[2]=0)'), + b, + f('','titleText(2,.04,1,1,1,1)') + ] , [ + 12 , + 2 , + f('','squaresCam(misc[2]=1-M(0,rStepTime*2),misc[3]=1)'), + b, + f('','titleText(2,.04,1,1-rStepTime,1-rStepTime/2,1-rStepTime)') + ] , [ + 12 , + 2 , + f('a','squaresCam(misc[1]=1-rStepTime/2,misc[4]=(1-rStepTime)*.7+R(a=.0125,a))') , + b, + f('','titleText(2,.04,1,0,.5,0)') + ] , [ + 9 , + 2 , + f('','squaresCam2(29,misc[1]=(1-rStepTime)/2,misc[2]=1-M(0,rStepTime*1.5)),misc[4]+=misc[1]*.6'), + b, + f('','titleText(2,.04,1-rStepTime,0,.5,0)') + ] , [ + 69 , + 2 , + f('','squaresCam2(29,misc[1]=0)') , + b + ] , [ + 11 , + 2 , + f('','squaresCam2(29,misc[2]=rStepTime,misc[3]=.2)'), + b + ] , [ + 11 , + 0 , + f('','tunnelCam(32,misc[2]=1-rStepTime)'), + b=[ tunnelLight ] + ] , [ + 17 , + 0 , + f('','tunnelCam(32,misc[2]=0,misc[4]=(1-rStepTime)*1.2*R(1,.02))') , + b + ] , [ + 18 , + 0 , + f('','tunnelCam(32,misc[4]=0,misc[8]=rStepTime)') , + b , + greetingsText + ] , [ + 36 , + 0 , + f('','tunnelCam(32,misc[2]=1-N(misc[8]=1,4*rStepTime))'), + b = [ tunnelLight , tunnelLightBall(32) ], + greetingsText + ] , [ + 33 , + 0 , + f('','tunnelCam(32,misc[2]=rStepTime,misc[3]=.7,misc[4]=-((4*rStepTime)%1)*R(1,.05))'), + b , + greetingsText + ] , [ + 9 , + 1 , + f('','fract2CamCommon(misc[4]=0,misc[2]=rStepTime,misc[3]=1)'), + a, + greetingsText + ] , [ + 20 , + 1 , + f('','fract2CamCommon(rStepTime,misc[2]=0)'), + a, + greetingsText + ] , [ + 31 , + 1 , + f('','fract2CamCommon(1,misc[2]=1-N(1,5*rStepTime))'), + a, + greetingsText + ] , [ + 5 , + 1 , + f('','fract2CamCommon(1,misc[2]=1-rStepTime)'), + a, + greetingsText + ] , [ + 18 , + 1 , + f('','fract2CamCommon(1,misc[2]=1-N(1,5*rStepTime),misc[4]=M(0,1.6*rStepTime-.8)*R(1,.05))'), + a, + greetingsText + ] , [ + 12 , + 1 , + f('','fract2CamCommon(1,misc[2]=rStepTime,misc[4]=(1-rStepTime)*.8*R(1,.05),misc[3]=.1)'), + a, + greetingsText + ] , [ + 22 , + 3 , + f('','balls2CamCommon(misc[2]=1-rStepTime,misc[4]=0)'), + a = [ lightFunc(.6,30) , balls2LightFunc(1),balls2LightFunc(-1) ], + greetingsText + ] , [ + 59 , + 3 , + f('','balls2CamCommon(misc[2]=1-N(1,(12*rStepTime)%4),misc[3]=.8)'), + a, + greetingsText + ] , [ + 8 , + 3 , + f('','balls2CamCommon(misc[2]=rStepTime,misc[4]=R(0,misc[3]=.1))'), + a + ] , [ + 7 , + 0 , + f('','misc[tunMul=2]=1-rStepTime,tunnelCam(46,misc[4]=R(0,.1),misc[8]=1)'), + a = [ tunnelLight , tunnelLightBall(46) ] + ] , [ + 22 , + 0 , + f('','tunnelCam(46,misc[4]=R(0,.1))'), + a + ] , [ + 10 , + 0 , + f('','tunnelCam(46,misc[4]=R(0,.1+rStepTime*.4)+stepTime*4,misc[2]=rStepTime,misc[3]=1)'), + a + ] , [ + 10 , + 2 , + f('','squaresCam2(49,misc[2]=1-rStepTime),misc[4]=R(0,.5)+(demoTime-direction[48][5])*4'), + a=[ lightFunc(1,30) ] + ] , [ + 40 , + 2 , + f('','squaresCam2(49),misc[4]=R(0,.5)-(demoTime-direction[48][5])*6'), + a + ] , [ + 40 , + 2 , + f('','squaresCam2(49),misc[4]=R(misc[3]=0,.5)+(demoTime-direction[48][5])*8,misc[2]=rStepTime'), + a + ] , [ + 68 , + 2 , + f('','squaresCam2(49,misc[2]=1)'), + a + ] +]; + +cmU=vomNew(3), + cmV=vomNew(3), + cmW=vomNew(3), + cd=vomNew(3), + cu=vomNew(3), + cm=vomNew(9); + + +// Main + +with(document.body)style.background='black',innerHTML='<canvas id=C1 style=position:fixed;cursor:none></canvas><canvas id=C2 style=display:none>'; +twoDCtx = C2.getContext('2d'); +glCtx=C1.getContext('webgl'); +(window.onresize=f('a,b,c,d,e','with(twoDCtx)a=innerWidth,b=innerHeight,c=(b*1.6)|0,d=(a*.625)|0,glCtx.viewport(0,0,C2.style.width=C2.width=C1.width=canvasWidth=c>a?a:c,C1.height=e=c>a?d:b),c2height=C2.style.height=C2.height=M(e/8,100),c2rHeight=c2height/e,C1.style.left=((a-canvasWidth)/2)|0,C1.style.top=((b-e)/2)|0,shadowColor=\'#ccc\',font=\'normal small-caps bold \'+((c2height/2)|0)+\'px monospace\',fillStyle=\'#111\',strokeStyle=\'#ddd\''))(); + + +for(shaders=[[glCtx.VERTEX_SHADER,shaderHeader+'attribute !2 i;void main(){gl_Position=!4(i,.0,1.),zx=i;}']],programs=[],i=0;i<4;i++)shaders[i+1]=[glCtx.FRAGMENT_SHADER,f('a,b,c,d,e','b=\'uniform \',d=5,c=shaderHeader+b+\'mat3 u0;\'+b+\'sampler2D u1;\'+b+\'!3 u2,u3;\'+b+\'% u4[10];\';for(e in a[15])c+=b+\'!3 u\'+d+++\';\'+b+\'% u\'+d+++\', u\'+d+++\';\';c+=\'const !2 c=!2(1.,-1.)*\'+a[5]+\';% p,z,w,u,o,zy,q,x,a,zz;!2 e,h;!3 l=!3(zx,1.),m,r,s=u2,yx=!3(1.),n=!3(.0),b,v,xxx,xy,d,xx,xz,y;!4 f;% g(% x){return fract(sin(x)*43758.5453);}% yy(!3 x){m=floor(x),y=fract(x),y*=y*(3.-2.*y),z=m.x+m.y*57.+m.z*113.;return mix(mix(mix(g(z),g(z+1.),y.x),mix(g(z+57.),g(z+58.),y.x),y.y),mix(mix(g(z+113.),g(z+114.),y.x),mix(g(z+170.),g(z+171.),y.x),y.y),y.z);}% yyx(!2 x,% a){e=pow(abs(x),!2(a));return pow(e.x+e.y,1./a);}mat2 t(% x){e=!2(cos(x),sin(x));return mat2(-e.x,e.y,e.y,e.x);}% yz(!3 x){return length(mod(x.xy,!2(15.))-!2(7.5))-.5+.05*sin(x.z*9.42477);}!2 k(!3 x,% a){\'+a[14]+\'}void main(){l.y+=mod(u4[4],1.)*2.2;if(l.y>1.){if(l.y<1.2)discard;l.y-=2.2;}l.x*=1.6,r=normalize(l*u0);for(int j=0;j<2;j++){v=r,xxx=s,xy=!3(.0),x=.0,a=\'+a[1]+\';for(int i=0;i<\'+a[4]+\';i++){h=k(s+r*x,x);if(h.x<a||i>\'+a[4]+\'/(j+1)||x>\'+a[0]+\'.)break;x+=h.x*\'+a[3]+\',a*=\'+shaderFloat(a[2])+\';}h.x=x;if(x<\'+a[0]+\'.){d=s+r*x,f=!4(k(d+c.xyy,x).x,k(d+c.yyx,x).x,k(d+c.yxy,x).x,k(d+c.xxx,x).x),xx=normalize(f.x*c.xyy+f.y*c.yyx+f.z*c.yxy+f.w*c.xxx),a=.0,p=\'+a[12]+\';for(int i=1;i<=\'+a[10]+\';i++)x=(%(i)/\'+a[10]+\'.)*\'+shaderFloat(a[11])+\',m=d+xx*x,q=max(.1,1.-clamp(pow(a+=p*(x-k(m,distance(m,s)).x),1.),.0,1.)),p*=.5;\';for(e in d=a[13])b=materials[d[e]],c+=(e>0?\'else \':\'\')+\'if(h.y==\'+e+\'.)xz=\'+(b[4]?(\'mix(!3(\'+shaderVec(b[0])+\'),!3(\'+shaderVec(b[5])+\'),yy(d*\'+shaderFloat(a[6]*b[4])+\'))\'):(\'!3(\'+shaderVec(b[0])+\')\'))+\',w=\'+shaderFloat(b[1])+\',u=\'+b[2]+\',o=\'+b[3]+\';\';d=5,c+=\'v=reflect(r,xx),z=\'+a[9]+\'*h.x,z=clamp(exp(-z*z*z*1.442695),.0,1.),x=clamp((1.+dot(normalize(v+r),r)),.0,1.),a=x*x,zz=o+(1.-o)*x*a*a*(u*.9+.1),y=mix(!3(1.),xz/dot(!3(.299,.587,.114),xz),w),m=!3(.0),zy=exp2(4.+6.*u),\';for(e in b=a[15])c+=\'p=length(b=u\'+d+\'-d),b/=p,p=max(1.,p-u\'+(d+2)+\')*\'+b[e][0]+\',p=1./max(1.,p*p),m+=mix((1.-w)*xz*q,y*pow(max(dot(reflect(r,xx),b),.0),zy)*(zy+2.)/8.,zz)*p*max(dot(b,xx),.0)*!3(u\'+(d+1)+\'),\',d+=3;d=5,c+=\'xy=yx*z*normalize(y)*o*(u*.9+.1)*zz,m=mix(!3(\'+shaderFloat(a[8])+\'),m,z),xxx+=normalize(v)*\'+a[7]+\';}else m=!3(\'+shaderFloat(a[8])+\');\';for(e in b=a[15])(a=b[e][1])?c+=\'b=s-u\'+d+\',p=dot(r,r),a=2.*dot(b,r),x=a*a-4.*p*(dot(b,b)-\'+(a*a)+\'),e=x<.0?!2(-1.):(x=sqrt(x),-.5*!2(a+x,a-x)/p),e=!2(min(e.x,e.y),max(e.x,e.y));if(e.x>.0&&e.y<h.x)m+=u\'+(d+2)+\'*!3(u\'+(d+1)+\')*pow((e.y-e.x)/\'+shaderFloat(a*2)+\',64.);\':0,d+=3','c+=\'n+=m*yx;if(all(lessThan(xy,!3(.01))))break;yx=xy,s=xxx,r=normalize(v);}h=!2(zx.x,l.y)*.5+.5,h.y=(1.-h.y-u4[5])/u4[7],f=texture2D(u1,h),n=max(!3(.0),mix(mix(mix(n,(n.x==n.y&&n.x==n.z)?n:!3(dot(n,!3(.299,.587,.114))),u4[1]),!3(u4[3]),smoothstep(.05,.95,u4[2])),f.rgb*u3,f.a*u4[6])-!3(.004)),x=(l.x+1.)*(l.y+1.)*(u4[0]*10.),gl_FragColor=!4((1.-(smoothstep(.98,1.,yy(l*8.+u4[0]*20.))+smoothstep(.95,1.,yy(l*1.5+u4[0]*10.))))*smoothstep(1.042+.008*cos(u4[0]*40.),.8,yyx(zx,8.))*(1.-(mod((mod(x,13.)+1.)*(mod(x,47.)+1.),.01))*8.)*((.95+.05*cos(u4[0]*41.))*(n*(6.2*n+.5))/(n*(6.2*n+!3(1.7))+!3(.06))+!3(smoothstep(.98,1.,yy(l*8.-u4[0]*40.)))),1.);}\';')(misc=raymarchers[i])],programs[i]=[5+misc[15].length*3,0,i+1]; + +misc = vomNew(10) , camPos = vomNew(3),lookAt=vomNew(3),camUp=vomNew(3),toNearPlane=0,textColour=vomNew(3) , lights= [[vomNew(3),0,0],[vomNew(3),0,0],[vomNew(3),0,0]]; +for ( i in shaders ) { + var def = shaders[i]; + glCtx.shaderSource( i= shaders[i] = glCtx.createShader( def[0] ) , def[1].replace(/!/g,'vec').replace(/%/g,'float') ); + glCtx.compileShader( i ); + if (!glCtx.getShaderParameter(i, glCtx.COMPILE_STATUS)) { + def[1] = def[1].split( /\n/ ); + for ( var k in def[1] ) { + var j = parseInt(k)+1; + def[1][k] = j + ": " + def[1][k]; + } + throw "SHADER ERROR\n" + glCtx.getShaderInfoLog(i) + "\n" + def[1].join('\n'); + } +} +for ( var name in programs ) { + var p = glCtx.createProgram( ); + var d = programs[name]; + var ul = d.shift(); + while( d.length ) { + glCtx.attachShader( p , shaders[ d.shift() ] ); + } + glCtx.linkProgram( p ); + var nul = []; + while ( ul-- ) { + nul[ul] = glCtx.getUniformLocation( p , 'u' + ul ); + } + programs[name] = [p,nul]; +} +glCtx.bindBuffer( glCtx.ARRAY_BUFFER , glCtx.createBuffer( ) ); +glCtx.bufferData( glCtx.ARRAY_BUFFER , vomNew([1,4,1,-1,-4,-1]) , glCtx.STATIC_DRAW ); +glCtx.clearColor(0,0,0,1); + +textTexture = glCtx.createTexture( ); +glCtx.bindTexture( glCtx.TEXTURE_2D , textTexture ); +glCtx.texParameteri( glCtx.TEXTURE_2D , glCtx.TEXTURE_WRAP_S, glCtx.CLAMP_TO_EDGE ); +glCtx.texParameteri( glCtx.TEXTURE_2D , glCtx.TEXTURE_WRAP_T, glCtx.CLAMP_TO_EDGE ); +glCtx.texParameteri( glCtx.TEXTURE_2D , glCtx.TEXTURE_MIN_FILTER, glCtx.NEAREST ); +glCtx.texParameteri( glCtx.TEXTURE_2D , glCtx.TEXTURE_MAG_FILTER, glCtx.NEAREST ); +glCtx.texImage2D( glCtx.TEXTURE_2D , 0 , glCtx.RGBA , glCtx.RGBA , glCtx.UNSIGNED_BYTE , C2 ); + + +mCurrentCol=timeStart = 0,mNumWords=10717272,mMixBuf=new Int32Array(mNumWords); + +mainfunc = function(){setTimeout(function(){ +requestAnimationFrame(draw=function(time){ + requestAnimationFrame(draw); + if ( timeStart == 0 ) { + A.currentTime = 0; + A.play( ); + timeStart = time; + previousFrame = timeStart - 33; + } + var delta = time - previousFrame; + demoTime = .001*(time - timeStart); + if ( delta < 33 ) { + return; + } + previousFrame = time - ( delta % 33 ); + + var ds = direction[t]; + while ( ds && ds[7] < demoTime ) { + ds=direction[++t]; + } + if ( ! ds ) { + A.pause( ); + return; + } + misc[0] = demoTime; + misc[7] = c2rHeight; + stepTime = demoTime - ds[5]; + rStepTime = stepTime / ds[6]; + if ( ds[4] ) { + twoDCtx.clearRect( 0 , 0 , canvasWidth , 100 ); + ds[4](); + glCtx.texImage2D( glCtx.TEXTURE_2D , 0 , glCtx.RGBA , glCtx.RGBA , glCtx.UNSIGNED_BYTE , C2 ); + } + + ds[2](); + vecNorm(cmW,vecSub(cmW,lookAt,camPos)); + vecNorm(cmU,vecCross(cmU,camUp,cmW)); + vecNorm(cmV,vecCross(cmV,cmW,cmU)); + vecScale(cmW,cmW,toNearPlane); + for(var i=0;i<3;i++)cm[i*3]=cmU[i],cm[i*3+1]=cmV[i],cm[i*3+2]=cmW[i]; + + for ( var i in ds[3] ) { + ds[3][i](lights[ i ]); + } + + var p = programs[ds[1]]; + glCtx.useProgram( p[ 0 ] ); + glCtx.enableVertexAttribArray( 0 ); + glCtx.vertexAttribPointer( 0 , 2 , glCtx.FLOAT , false , 8 , 0 ); + p = p[1]; + + var u = 0; + glCtx.uniformMatrix3fv( p[u++] , false , cm ); + glCtx.uniform1i( p[u++] , 0 ); + glCtx.uniform3fv( p[u++] , camPos ); + glCtx.uniform3fv( p[u++] , textColour ); + glCtx.uniform1fv( p[u++] , misc ); + for ( var i in ds[3] ) { + glCtx.uniform3fv( p[u++] , lights[ i ][0] ); + glCtx.uniform1f( p[u++] , lights[ i ][1] ); + glCtx.uniform1f( p[u++] , lights[ i ][2] ); + } + glCtx.drawArrays( 4 , 0 , 3 ); +}) +},500)}; + +for(t=i=0;i<53;i++)direction[i][5]=t,t+=(direction[i][6]=direction[i][0]/8),direction[i][7]=t; +t=0; + +if ( USE_SYNTH ) { + synthGen = setInterval(function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v){ + for(d=new Int32Array(mNumWords),f=[[[0,198,128,0,3,192,128,1,0,0,96,128,28,0,0,0,0,2,63,61,13,16,44,8,0,0],[1,2,3,4,5,2,3,4,6,7,1,2,3,4,5,2,3,4,5,2,3,4,1,2,3,8,9],[[[115,,,,,,,,,,,,117,,,,,,,,,,,,113],[12,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,96]],[[115,,,,,,,,,,,,,,,110],[12,,,,,,,,,,,,,,,12,,,,,,,,,,,,,,,,,,,,,115,,,,,,,,,,,,,,,148]],[[115,,,,,,,,,,,,117,,,,,,,,,,,,118],[12,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,96]],[[122,,,,,,,,,,,,,,,123,,,,,115],[12,,,,,,,,,,,,,,,12,,,,,12,,,,,,,,,,,,,,,,115,,,,,,,,,,,,,,,8,,,,,128]],[[118,,,,,,,,,,,,117,,,,,,,,,,,,113],[12,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,96]],[[115],[12,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,255]],[[,,,,,,,,,,,,,,,,118,118,118],[,,,,,,,,,,,,,,,,12,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,128]],[[122,,,,,,,,,,,,,,,123,,,,,115],[12,,,,,,,,,,,,,,,12,,,,,13,12,,,,,,,,,,,,,,,115,,,,,,,,,,,,,,,8,,,,,95,61]],[[],[]]]],[[0,255,116,1,0,255,101,0,0,15,1,4,45,0,13,6,1,2,62,27,60,48,0,0,44,2],[,1,,2,,1,,2,,3,4,4,5,4,5,4,5,4,5,4,5,4,5,4,3,6],[[[,,,,,139,,,139,139,,,,,,139,,,,,,,,139,,,139,139,,,,,139,139,139],[]],[[,,139,139,,,,,139,139,,,,,139,139,,,,,,,,,,139,139,139,,,,,139,139,139],[]],[[,,,139,,,,,139,139,,,,,,139,,,,,139,139,,,,,,139,,,,139,139,139],[]],[[139,,,,139,,139,,,139,,,139,,,,139,,139,,,139,,,139,,,,139,,139,,,139],[]],[[139,,,139,139,,139,,,139,,,139,,,139,139,,139,,,139,,,139,,,139,139,,139,,,139],[]],[[139,,,139,139,,139,,,139,,,139,,,139,139,,139,,,139,139],[]]]],[[0,0,140,0,0,0,140,0,0,128,4,10,34,0,187,5,0,1,239,135,34,19,108,8,8,4],[,,1,,1,,3,,1,3,2,2,2,2,2,3,2,3,2,3,2,3,2,3,1],[[[,,,,,,,,,,127,,,,,,,,,,,,127,,,,,,,,,,,,127],[]],[[,,,139,,,,,,139,139,,,,,139,,,,,,139,139,,,,,139,,,,,139,,139],[]],[[,,127,,,,,,,,127,,,,127,,,,,,,,127,,,,127,,,,,,,,127],[]]]],[[1,192,128,0,3,201,128,0,0,93,5,6,58,3,195,6,1,3,35,63,14,17,11,10,61,6],[,,,,1,2,3,4,5,6,7,5,8,9,10,11,8,9,10,11,12,13,14,15,16],[[[,,,,,,,,147,146,145,,,,,,,,,,145,147,146,,,,,,,,,,149,148,147],[]],[[,,,,,,151,151,151,,,,,,,146,142,138,,,,,,,,,,,,,,,147,150,147],[]],[[,,146,,,146,,,,,,,,,147,146,145,,,,,,,,,,146,145,142,,,142,,,142],[]],[[,,141,,,,,,,,,,,,141,140,139,,,146,,,146,,,127],[]],[[,139,,151,,,,,,,,,,151,,139,,,,,,,,,,139,,151],[]],[[,139,,151,150,149,,,,,,,,139,,149,148,147,,,,,,,,139,,,146,,,145,,,144],[]],[[,139,,,139,142,,,142,144,146,,144,,,,146,147,,,147,146,141,,137,,,,142,141,,141,,137],[]],[[139,,127,,142,,,130,,,144,142,141,,129,,141,,,144,,,141,144,142,,,,149,,,146,,,151],[]],[[,149,,149,,146,144,142,,,141,,142,,,139,,,,151,147,,,,146,147,,144,146,,142,144,141,146],[]],[[,,,,,,,,147,146,145,,,,,141,144,147,146,,144,,137,,,144,146,142,144,,,142,144,141,146],[]],[[,146,,151,,146,,,,144,142,144,146,,,,142,,,,,139,,,,,151,146,139,144,139,142,141,142,151],[]],[[,,147,,,149,146,,,142,,142,141,,,144,,144,,,144,146,142,144,142,,,,151,150,149,,137,,149],[]],[[,151,,,147,151,,,146,151,,,,,144,151,,149,147,149,151,,146,,,144,143,142,,,139,,151,139],[]],[[,,134,,,134,,,134,,,146,144,,,141,144,,,146,147,146,,,144,,139,140,141,,,153,,,141],[]],[[,142,,151,,,142,143,144,,,,151,,,139,,,137,,149,,137,,,,125,,,141,142,141,,,146],[]],[[139,,127,139,,127,139,,127,139,127],[]]]],[[2,160,128,1,0,160,128,0,1,60,4,7,41,0,60,4,1,3,14,0,35,32,31,12,89,1],[,,,,,,,,,,,,1,2,1,2,1,2,1,2,1,2,1,2,1,3],[[[,,139,,,,,,,,,,,,139,,,,,,,,,,,,139,,,,,139,139,,,139],[]],[[,,139,,,151,,,139,,,151,,,139,,,151,,,139,,,151,,,139,,,151,,,146,146,146,146],[]],[[,,139,,,151,,,139,,,151,,,139,,139,139,139,139,127],[]]]],[[2,100,128,0,3,201,128,0,0,0,0,6,29,0,195,6,1,3,28,229,119,77,147,6,61,2],[,,,,,,,,,6,1,2,3,4,5,2,3,4,1,2,3,4,1,2,3,7],[[[115,115,115,115,115,115,115,115,115,115,115,115,117,117,117,117,117,117,117,117,117,117,117,117,113,113,113,113,113,113,113,113,113,113,113,113],[]],[[115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110],[]],[[115,115,115,115,115,115,115,115,115,115,115,115,117,117,117,117,117,117,117,117,117,117,117,117,118,118,118,118,118,118,118,118,118,118,118,118],[]],[[110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,111,111,111,111,111,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115],[]],[[118,118,118,118,118,118,118,118,118,118,118,118,117,117,117,117,117,117,117,117,117,117,117,117,113,113,113,113,113,113,113,113,113,113,113,113],[]],[[,,,,,,,,,,,,,,,,,,130,,130,,130,,130,,130,,130,118,130,118,130,118,130,118],[,,,,,,,,,,,,,,,,,,26,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2]],[[110,122,,122,134,,110,122,,122,134,,110,122,,111,123,,111,123,115,127,139,127,115],[,,,,,,,,,,,,,,,,,,,,26,25,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,8,147]]]],[[2,100,128,0,3,201,128,0,0,0,5,6,58,0,195,6,1,2,135,0,0,32,147,6,121,6],[],[]],[[2,100,128,0,3,201,128,0,0,0,5,6,58,0,195,6,1,2,135,0,0,32,147,6,121,6],[],[]]][mCurrentCol],o=[],g=h=m=p=0;p<=26;p++)for(b=f[1][p],a=0;a<36;a++){((e=b?f[2][b-1][1][a]:0)?((f[0][e-1]=f[2][b-1][1][a+36]||0),e<14?(o=[]):0):0),c=(p*36+a)*5513;for(j=0;j<4;j++)if(n=b?f[2][b-1][0][a+j*36]:0){if(!o[n])for(q=f[0][10],r=f[0][11],s=f[0][12],t=getnotefreq(n+f[0][2]-128),l=getnotefreq(n+f[0][6]-128)*(1+.0008*f[0][7]),u=v=0,q*=q*4,r*=r*4,s*=s*4,o[n]=new Int32Array(q+r+s),k=0;k<q+r+s;k++)e=k<q?(k/q):(1-(k<q+r?0:((k-q-r)/s))),o[n][k]=(80*(mOscillators[f[0][0]](u+=t*(f[0][3]?(e*e):1))*f[0][1]+mOscillators[f[0][4]](v+=l*(f[0][8]?(e*e):1))*f[0][5]+R(0,1)*f[0][9])*e)|0;for(k=0,i=c*2;k<o[n].length;k++,i+=2)d[i]+=o[n][k]}q=f[0][20]*1e-5,r=f[0][24]/255,s=f[0][25]*5513;for(j=0;j<5513;j++)(((n=e=d[k=(c+j)*2])||m)?(t=1.5*S(f[0][18]*.00307999186353015873*(f[0][16]?(mOscillators[f[0][13]](P(2,f[0][15]-9)*k/5513)*f[0][14]/512+.5):1)),g+=t*h,l=(1-f[0][19]/255)*(e-h)-g,h+=t*l,e=f[0][17]==3?h:f[0][17]==1?l:g,q?(e*=q,e=(e<1?e>-1?mOscillators[0](e*.25):-1:1)/q):0,e*=f[0][21]/32,m=e*e>1e-5,t=S(6.283184*P(2,f[0][23]-9)*k/5513)*f[0][22]/512+.5,n=e*(1-t),e*=t):0),(k>=s?(n+=d[k-s+1]*r,e+=d[k-s]*r):0),mMixBuf[k]+=(d[k]=n|0),mMixBuf[k+1]+=(d[k+1]=e|0)} + if(++mCurrentCol==8)for(clearInterval(synthGen),s=(f=String.fromCharCode).apply(String,[82,73,70,70,168,16,71,1,87,65,86,69,102,109,116,32,16,0,0,0,1,0,2,0,68,172,0,0,16,177,2,0,4,0,16,0,100,97,116,97,132,16,71,1]),i=0;i<mNumWords||(((A=document.createElement('audio')).src='data:audio/wav;base64,'+btoa(s),A.oncanplaythrough=mainfunc)&&0);i++)e=mMixBuf[i],e=e<-32767?-32767:(e>32767?32767:e),s+=f(e&255,(e>>8)&255) + }, 0); +} else { + A = document.createElement("audio"); + A.oncanplaythrough=mainfunc; + A.src= 'music.ogg'; +} diff --git a/201410_-_Sine_City/sine-city-packing-6-gl.html b/201410_-_Sine_City/sine-city-packing-6-gl.html new file mode 100644 index 0000000..4a22369 --- /dev/null +++ b/201410_-_Sine_City/sine-city-packing-6-gl.html @@ -0,0 +1,3 @@ +<body> +<script language="javascript" src="sine-city-packing-6-gl.js"></script> + diff --git a/201410_-_Sine_City/sine-city-packing-6-gl.js b/201410_-_Sine_City/sine-city-packing-6-gl.js new file mode 100644 index 0000000..244c1b1 --- /dev/null +++ b/201410_-_Sine_City/sine-city-packing-6-gl.js @@ -0,0 +1,455 @@ +var USE_SYNTH = 0; + +with(Math)S=sin,C=cos,M=max,N=min,P=pow; + + +f = function(a,b,c){return eval('(function('+a+'){'+b+(b?';':'')+(c?('return '+c):'')+'})')}, + +getnotefreq=f('a','','.003959503758*P(2,(a-128)/12)'), +mOscillators=[ + f('a','','S(a*6.283184)'), + f('a','','(a%1)<.5?1:-1'), + f('a','','2*(a%1)-1'), + f('a,b','b=(a%1)*4','(b<2)?(b-1):(3-b)') +], + +// Vector stuff +vecOp=f('a','','f(\'a,b,c\',\'for(var i=a.length;--i>=0;)\'+a,\'a\')'), +vomNew=f('a','','new Float32Array(a)'), +vecNorm=f('a,b,c','c=Math.sqrt(b[0]*b[0]+b[1]*b[1]+b[2]*b[2])','c?vecScale(a,b,1/c):vecCopy(a,b)'), +vecCross=f('a,b,c','','vecSet(a,b[1]*c[2]-b[2]*c[1],b[2]*c[0]-b[0]*c[2],b[0]*c[1]-b[1]*c[0])'), +vecSet=vecOp('a[i]=arguments[i+1]'), +vecCopy=vecOp('a[i]=b[i]'), +vecSub=vecOp('a[i]=b[i]-c[i]'), +vecScale=vecOp('a[i]=b[i]*c'), + + +// Shaders +shaderHeader='precision highp %;varying !2 zx;', +shaderFloat=f('a','','a+(a==(a|0)?\'.\':\'\')'), +shaderVec=f('a','','a.map(shaderFloat).join(\',\')'); + + +// Raymarchers + +materials = [[[.05],.7,.02,.01],[[.2],.7,.9,.01,5,[.1]],[[1],.5,.4,.02],[[3,0,0],.3,.1,.6,6,[.6,0,0]],[[0,2,0],.9,.5,.4,15,[0,.2,0]],[[3,1.5,0],.95,.6,.9,.3,[.3,.6,0]],[[.1],0,.04,.002,3,[3]],[[0,1.5,2],.9,.3,.4]]; +raymarchers = [[100,.025,1,.7,64,.0005,.5,.3,.4,.015,4,2,.75,[0,1,2,3],'y=x+.1*(sin(x.zxy*.17+u4[0]*.5)+sin(x.yzx*.7+u4[0]*1.5))*8.5*(1.+cos(sin(x.z*.1)+x.z*.3)),z=14.-length(y.xy),w=x.x==.0?1.570795*(x.y>.0?1.:-1.):atan(x.y,x.x),q=8.35-u4[8]*1.35,y=!3(9.*(mod(w+x.z*.02,.628)-.314),length(x.xy)-9.,mod(x.z,12.56)-6.28),u=min(length(y.xy)-.25+.1*cos(x.z*8.+u4[0]*.1),length(y.yz)-.5),y=!3(q*(mod(w+x.z*.02,1.256636)-.628318),y.y+9.-q,mod(x.z,62.8318)-31.4159),o=step(u,z)+1.,z=min(u,z),u=length(y)-1.3;if(u<z)z=u,o=3.;y.y+=q-9.,u=yyx(y.yz,8.)-2.;if(u<z)z=u,o=.0;return !2(z,o);',[[.25,0],[.5,.5]]],[6,.00025,1.08,.7,100,.000008,10,.03,2.1,.2,6,.4,5.1,[0,2,5],'z=1.,y=x;for(int i=0;i<7;i++)x=2.*clamp(x,-!3(.58,.9,1.1),!3(.58,.9,1.1))-x,w=max((1.3+u4[9]*.1*cos(u4[0]*.5))/dot(x,x),1.),x*=w,z*=w;w=length(x.xy),e=!2(w-3.,-w*x.z/length(x)-2.*log(1.+.01*a))/abs(z),w=max(e.x,e.y),o=step(e.y,e.x),y+=!3(.1,.3,-.4)*u0-u2+.25*sin(x*1.),e.x=length(y)-.1*u4[8];if(e.x<w)w=e.x,o=2.;return !2(w,o);',[[.05]]],[100,.000025,1,.75,80,.00005,.5,.3,3,.01,4,.75,4.75,[6,0,4],'x.xy*=t(a*.009),w=min(min(yz(x.xzy),yz(x)),yz(x.yzx)),y=mod(x,!3(15.))-!3(7.5),o=step(z=max(length(max(abs(y)-!3(2.5),!3(.0)))-.25,3.5-length(y)),w),w=min(w,z),z=length(y+.1*sin(y*5.5+u4[0]))-2.;if(z<w)w=z,o=2.;return !2(w,o);',[[.05]]],[20,.0005,1,.6,128,.0001,.5,.002,.01,.08,4,.5,1.75,[2,7],'y=x,y.xz=mod(x.xz,8.)-4.,y.yz*=t(u4[8]+.1*a),y.xy*=t(u4[8]*.5+.2*a),y.y*=.9+.1*sin(u4[8]*5.),w=max(length(y)-3.,-min(length(y)-2.8,max(mod(y.y,.8)-.4,-mod(y.y+.4,.8)+.4))),z=x.y+1.+sin(x.x*4.+u4[8]*2.)*sin(x.z+u4[8])*.1,o=clamp(.5+.5*(z-w)/1.,.0,1.),w=mix(z,w,o)-1.*o*(1.-o),y=x,y.xz=mod(y.xz,8.)-4.,y/=1.25+.25*sin(u4[8]*5.),y.xy*=t(u4[8]*5.),y.yz*=t(u4[8]*2.5),z=max(length(y)-1.,.04-length(max(abs(mod(y,.5)-.25)-!3(.15),!3(.0))));return !2(min(w,z),step(z,w));',[[.02],[.05,.5],[.05,.5]]]]; + +tunMul=1, +R=f('a,b','','a-b+Math.random()*b*2'), +lightFunc=f('a,b','','f(\'a\',\'vecCopy(a[0],camPos),a[1]=\'+a+\',a[2]=\'+b)'), + +tun1CamCommon=f('a','vecSet(camPos,-6,0,a=demoTime*6),vecSet(lookAt,misc[1]=1,misc[8]=0,a),vecSet(camUp,0,1,0)'), +desyncFunc=f('a','','f(\'\',\'misc[4]=(\'+(a>0?a:\'\')+\'-stepTime*\'+a+\'/direction[t][6])*R(.875,.125)\')'), +balls1CamFunc=f('a,b,c,d','c=desyncFunc(c),d=f(\'a,b,c,d\',\'vecSet(camPos,misc[2]=misc[8]=0,4,d=demoTime*3),vecSet(lookAt,a,0,d+b),vecSet(camUp,0,0,1),c()\')','function(){d(a,b,c)}'), +balls2CamCommon=f('a','a=demoTime*5,vecSet(camPos,C(demoTime)*12,8,S(demoTime)*12+a),vecSet(lookAt,1,0,a),vecSet(camUp,0,1,0),toNearPlane=2.5,misc[8]=demoTime-direction[43][5]'), +balls2LightFunc=f('a','','f(\'a\',\'vecSet(a[0],\'+a+\'*C(demoTime*2)*5,3,\'+a+\'*S(demoTime*2)*5+demoTime*30),a[1]=1,a[2]=4\')'), +fract1CamCommon=f('','vecSet(camPos,4,2.5+.025*demoTime,6.7),vecSet(lookAt,misc[8]=misc[9]=0,2.5-.05*demoTime,6.7),vecSet(camUp,0,0,1),toNearPlane=3'), +fract1CamFunc=f('a','a=desyncFunc(a)','function(){fract1CamCommon(),a()}'), +fract2CamCommon=f('a,b','vecSet(camPos,5*S(b=demoTime*.2),9*C(demoTime*.41),7.8),vecSet(lookAt,C(b),S(demoTime*.33),camPos[2]-2),vecSet(camUp,0,0,misc[9]=1),misc[8]=a,toNearPlane=3'), + +drawText=f('a,b,c','with(twoDCtx)shadowBlur=c2height/5,fillText(a,b,c=c2height/2),shadowBlur=0,strokeText(a,b,c)'), +titleParts=['TheT(ourist)','presents','Sine City'], +titleText=f('a,b,c,d,e,f','drawText(titleParts[a],canvasWidth/15),misc[5]=1-c2rHeight+R(0,b),misc[6]=c,vecSet(textColour,d,e,f)'), +greetingsText=f('','drawText(\'Greetings to ... Mog, Sycop, Tim & Wullon ... Adinpsz ... Alcatraz ... ASD ... Bits\\\'n\\\'Bites ... Brain Control ... Cocoon ... Conspiracy ... Ctrl+Alt+Test ... Fairlight ... Farbrausch ... Kewlers ... LNX ... Loonies ... Mercury ... Popsy Team ... Razor 1911 ... RGBA ... 7th Cube ... Still ... TPOLM ... TRBL ... Umlaut Design ... X-Men ... Youth Uprising ... Everyone here at DemoJS 2014!\',canvasWidth*(1-(demoTime-direction[34][5])/2)),misc[5]=1-c2rHeight+R(.01,.01),vecSet(textColour,misc[6]=1,1,1)'), +squaresCam=f('a,b','a=demoTime-direction[25][5],vecSet(camPos,b=a*10-80,0,0),vecSet(lookAt,b+C(a*.5)*80,S(a*.25)*40,100),vecSet(camUp,0,toNearPlane=2.5,0)'), +squaresCam2=f('a,b','a=demoTime-direction[a][5],vecSet(camPos,0,0,b=a*20-80),vecSet(lookAt,C(a*.5)*80,S(a*.25)*40,100+b),vecSet(camUp,0,1,0),misc[4]=R(a=.0125,a)'), +tunnelLight=f('a','vecSub(a[0],camPos,vecNorm(a[0],lookAt)),a[0][1]-=.5,a[1]=3,a[2]=30'), +tunnelCam=f('a','a=(demoTime-direction[a][5])*30*tunMul,vecSet(camPos,1.1*C(a*.1),S(a*.02),a),a+=5,vecSet(lookAt,-S(a*.05),-.7*C(a*.033),a),vecSet(camUp,0,toNearPlane=2,0)'), +tunnelLightBall=f('a','','f(\'a,b\',\'b=demoTime-direction[\'+a+\'][5],vecSet(a[0],4*S(b*.5)*C(b*.7),3*C(b*1.5),b*30*tunMul+14+16*S(b*3.3)*C(b*.77)),a[1]=1,a[2]=2\')'), + +// direction 0<->rows / 1<->rm / 2<->setGlobals / 3<->lights / 4<->updateText / 5<->startTime / 6<->time / 7<->endTime +direction = [ + [ + 36 , + 0 , + f('','tun1CamCommon(misc[2]=1-rStepTime*rStepTime*rStepTime,toNearPlane=5)') , + a=[lightFunc(3,20)] + ] , [ + 18 , + 0 , + f('','tun1CamCommon(misc[2]=0,toNearPlane=5-2.25*rStepTime)') , + a + ] , [ + 36 , + 0 , + f('','tun1CamCommon(misc[2]=rStepTime,toNearPlane=2.75-2.25*rStepTime)') , + a + ] , [ + 18 , + 3 , + f('a','vecSet(camPos,0,4,a=demoTime*3),vecSet(lookAt,4,0,a),vecSet(camUp,0,0,1),misc[2]=1-rStepTime*rStepTime*rStepTime,toNearPlane=2.5') , + [ lightFunc(.75,8) ] + ] , [ + 22 , + 3 , + balls1CamFunc(4,0,0) , + a=[lightFunc(1,8)] + ] , [ + 22 , + 3 , + balls1CamFunc(2,-2,0) , + a + ] , [ + 3 , + 3 , + balls1CamFunc( 6 , 0 , -.5 ) , + b=[lightFunc(.5,4)] + ] , [ + 9 , + 3 , + balls1CamFunc( 6 , 0 , .5 ) , + b + ] , [ + 3 , + 3 , + balls1CamFunc( 2 , 2 , -.2 ) , + a + ] , [ + 9 , + 3 , + balls1CamFunc( 2 , 2 , .2 ) , + a + ] , [ + 3 , + 3 , + balls1CamFunc( 2 , 5 , -.7 ) , + a=[ lightFunc(1,2) ] + ] , [ + 7 , + 3 , + balls1CamFunc( 2 , 2 , .7 ) , + a + ] , [ + 9 , + 3 , + f('a','vecSet(camPos,0,4+rStepTime*2,a=demoTime*3),vecSet(lookAt,2,0,a+2),vecSet(camUp,0,0,misc[3]=1),misc[2]=rStepTime') , + a + ] , [ + 21 , + 1 , + f('','fract1CamCommon(misc[2]=1-rStepTime*rStepTime*rStepTime,misc[3]=1)'), + a=[f('a','vecCopy(a[0],camPos),a[0][2]+=2,a[1]=1,a[2]=3')] + ] , [ + 14 , + 1 , + fract1CamFunc(0) , + a + ] , [ + 3 , + 1 , + fract1CamFunc(-.4) , + a + ] , [ + 9 , + 1 , + fract1CamFunc(.4) , + a + ] , [ + 3 , + 1 , + fract1CamFunc(-.2) , + a + ] , [ + 9 , + 1 , + fract1CamFunc(.2) , + a + ] , [ + 12 , + 1 , + f('','fract1CamCommon(misc[4]=(-(6*rStepTime)%1)*R(.875,.125))'), + a + ] , [ + 22 , + 1 , + f('','fract1CamCommon(misc[4]=((30*rStepTime)%1)*R(.925,.075),misc[2]=rStepTime,misc[3]=.4),toNearPlane=3-2.5*M(1,2*rStepTime)'), + a + ] , [ + 3 , + 1 , + b=f('','fract1CamCommon(misc[4]=0,misc[2]=1)'), + a + ] , [ + 12 , + 1 , + b , + a, + f('','titleText(0,.08,1,1,1,1)') + ] , [ + 12 , + 1 , + b , + a, + f('','titleText(0,.08,1-rStepTime,1,1,1)') + ] , [ + 12 , + 1 , + b , + a, + f('','titleText(1,.08,1-rStepTime,1,1,1)') + ] , [ + 20 , + 2 , + f('','squaresCam(misc[2]=1-rStepTime)') , + b=[lightFunc(1,30)], + f('','titleText(2,.04,rStepTime,1,1,1)') + ] , [ + 52 , + 2 , + f('','squaresCam(misc[2]=0)'), + b, + f('','titleText(2,.04,1,1,1,1)') + ] , [ + 12 , + 2 , + f('','squaresCam(misc[2]=1-M(0,rStepTime*2),misc[3]=1)'), + b, + f('','titleText(2,.04,1,1-rStepTime,1-rStepTime/2,1-rStepTime)') + ] , [ + 12 , + 2 , + f('a','squaresCam(misc[1]=1-rStepTime/2,misc[4]=(1-rStepTime)*.7+R(a=.0125,a))') , + b, + f('','titleText(2,.04,1,0,.5,0)') + ] , [ + 9 , + 2 , + f('','squaresCam2(29,misc[1]=(1-rStepTime)/2,misc[2]=1-M(0,rStepTime*1.5),misc[4]+=misc[1]*.6)'), + b, + f('','titleText(2,.04,1-rStepTime,0,.5,0)') + ] , [ + 69 , + 2 , + f('','squaresCam2(29,misc[1]=0)') , + b + ] , [ + 11 , + 2 , + f('','squaresCam2(29,misc[2]=rStepTime,misc[3]=.2)'), + b + ] , [ + 11 , + 0 , + f('','tunnelCam(32,misc[2]=1-rStepTime)'), + b=[ tunnelLight ] + ] , [ + 17 , + 0 , + f('','tunnelCam(32,misc[2]=0,misc[4]=(1-rStepTime)*1.2*R(1,.02))') , + b + ] , [ + 18 , + 0 , + f('','tunnelCam(32,misc[4]=0,misc[8]=rStepTime)') , + b , + greetingsText + ] , [ + 36 , + 0 , + f('','tunnelCam(32,misc[2]=1-N(misc[8]=1,4*rStepTime))'), + b = [ tunnelLight , tunnelLightBall(32) ], + greetingsText + ] , [ + 33 , + 0 , + f('','tunnelCam(32,misc[2]=rStepTime,misc[3]=.7,misc[4]=-((4*rStepTime)%1)*R(1,.05))'), + b , + greetingsText + ] , [ + 9 , + 1 , + f('','fract2CamCommon(misc[4]=0,misc[2]=rStepTime,misc[3]=1)'), + a, + greetingsText + ] , [ + 20 , + 1 , + f('','fract2CamCommon(rStepTime,misc[2]=0)'), + a, + greetingsText + ] , [ + 31 , + 1 , + f('','fract2CamCommon(1,misc[2]=1-N(1,5*rStepTime))'), + a, + greetingsText + ] , [ + 5 , + 1 , + f('','fract2CamCommon(1,misc[2]=1-rStepTime)'), + a, + greetingsText + ] , [ + 18 , + 1 , + f('','fract2CamCommon(1,misc[2]=1-N(1,5*rStepTime),misc[4]=M(0,1.6*rStepTime-.8)*R(1,.05))'), + a, + greetingsText + ] , [ + 12 , + 1 , + f('','fract2CamCommon(1,misc[2]=rStepTime,misc[4]=(1-rStepTime)*.8*R(1,.05),misc[3]=.1)'), + a, + greetingsText + ] , [ + 22 , + 3 , + f('','balls2CamCommon(misc[2]=1-rStepTime,misc[4]=0)'), + a = [ lightFunc(.6,30) , balls2LightFunc(1),balls2LightFunc(-1) ], + greetingsText + ] , [ + 59 , + 3 , + f('','balls2CamCommon(misc[2]=1-N(1,(12*rStepTime)%4),misc[3]=.8)'), + a, + greetingsText + ] , [ + 8 , + 3 , + f('','balls2CamCommon(misc[2]=rStepTime,misc[4]=R(0,misc[3]=.1))'), + a + ] , [ + 7 , + 0 , + f('','misc[tunMul=2]=1-rStepTime,tunnelCam(46,misc[4]=R(0,.1),misc[8]=1)'), + a = [ tunnelLight , tunnelLightBall(46) ] + ] , [ + 22 , + 0 , + f('','tunnelCam(46,misc[4]=R(0,.1))'), + a + ] , [ + 10 , + 0 , + f('','tunnelCam(46,misc[4]=R(0,.1+rStepTime*.4)+stepTime*4,misc[2]=rStepTime,misc[3]=1)'), + a + ] , [ + 10 , + 2 , + f('','squaresCam2(49,misc[2]=1-rStepTime),misc[4]=R(0,.5)+(demoTime-direction[48][5])*4'), + a=[ lightFunc(1,30) ] + ] , [ + 40 , + 2 , + f('','squaresCam2(49),misc[4]=R(0,.5)-(demoTime-direction[48][5])*6'), + a + ] , [ + 40 , + 2 , + f('','squaresCam2(49),misc[4]=R(misc[3]=0,.5)+(demoTime-direction[48][5])*8,misc[2]=rStepTime'), + a + ] , [ + 68 , + 2 , + f('','squaresCam2(49,misc[2]=1)'), + a + ] +]; + +cmU=vomNew(3), + cmV=vomNew(3), + cmW=vomNew(3), + cd=vomNew(3), + cu=vomNew(3), + cm=vomNew(9); + + +// Main + +with(document.body)style.background='black',innerHTML='<canvas id=C1 style=position:fixed;cursor:none></canvas><canvas id=C2 style=display:none>'; +twoDCtx = C2.getContext('2d'); +for(i in glCtx=C1.getContext('webgl'))glCtx[i.match(/^..|[A-Z]|\d[fi]v?$/g).join('')]=glCtx[i]; +(window.onresize=f('a,b,c,d,e','with(twoDCtx)a=innerWidth,b=innerHeight,c=(b*1.6)|0,d=(a*.625)|0,glCtx.vi(0,0,C2.style.width=C2.width=C1.width=canvasWidth=c>a?a:c,C1.height=e=c>a?d:b),c2height=C2.style.height=C2.height=M(e/8,100),c2rHeight=c2height/e,C1.style.left=((a-canvasWidth)/2)|0,C1.style.top=((b-e)/2)|0,shadowColor=\'#ccc\',font=\'normal small-caps bold \'+((c2height/2)|0)+\'px monospace\',fillStyle=\'#111\',strokeStyle=\'#ddd\''))(); + + +for(shaders=[[35633,shaderHeader+'attribute !2 i;void main(){gl_Position=!4(i,.0,1.),zx=i;}']],programs=[],i=0;i<4;i++)shaders[i+1]=[35632,f('a,b,c,d,e','b=\'uniform \',d=5,c=shaderHeader+b+\'mat3 u0;\'+b+\'sampler2D u1;\'+b+\'!3 u2,u3;\'+b+\'% u4[10];\';for(e in a[15])c+=b+\'!3 u\'+d+++\';\'+b+\'% u\'+d+++\', u\'+d+++\';\';c+=\'const !2 c=!2(1.,-1.)*\'+a[5]+\';% p,z,w,u,o,zy,q,x,a,zz;!2 e,h;!3 l=!3(zx,1.),m,r,s=u2,yx=!3(1.),n=!3(.0),b,v,xxx,xy,d,xx,xz,y;!4 f;% g(% x){return fract(sin(x)*43758.5453);}% yy(!3 x){m=floor(x),y=fract(x),y*=y*(3.-2.*y),z=m.x+m.y*57.+m.z*113.;return mix(mix(mix(g(z),g(z+1.),y.x),mix(g(z+57.),g(z+58.),y.x),y.y),mix(mix(g(z+113.),g(z+114.),y.x),mix(g(z+170.),g(z+171.),y.x),y.y),y.z);}% yyx(!2 x,% a){e=pow(abs(x),!2(a));return pow(e.x+e.y,1./a);}mat2 t(% x){e=!2(cos(x),sin(x));return mat2(-e.x,e.y,e.y,e.x);}% yz(!3 x){return length(mod(x.xy,!2(15.))-!2(7.5))-.5+.05*sin(x.z*9.42477);}!2 k(!3 x,% a){\'+a[14]+\'}void main(){l.y+=mod(u4[4],1.)*2.2;if(l.y>1.){if(l.y<1.2)discard;l.y-=2.2;}l.x*=1.6,r=normalize(l*u0);for(int j=0;j<2;j++){v=r,xxx=s,xy=!3(.0),x=.0,a=\'+a[1]+\';for(int i=0;i<\'+a[4]+\';i++){h=k(s+r*x,x);if(h.x<a||i>\'+a[4]+\'/(j+1)||x>\'+a[0]+\'.)break;x+=h.x*\'+a[3]+\',a*=\'+shaderFloat(a[2])+\';}h.x=x;if(x<\'+a[0]+\'.){d=s+r*x,f=!4(k(d+c.xyy,x).x,k(d+c.yyx,x).x,k(d+c.yxy,x).x,k(d+c.xxx,x).x),xx=normalize(f.x*c.xyy+f.y*c.yyx+f.z*c.yxy+f.w*c.xxx),a=.0,p=\'+a[12]+\';for(int i=1;i<=\'+a[10]+\';i++)x=(%(i)/\'+a[10]+\'.)*\'+shaderFloat(a[11])+\',m=d+xx*x,q=max(.1,1.-clamp(pow(a+=p*(x-k(m,distance(m,s)).x),1.),.0,1.)),p*=.5;\';for(e in d=a[13])b=materials[d[e]],c+=(e>0?\'else \':\'\')+\'if(h.y==\'+e+\'.)xz=\'+(b[4]?(\'mix(!3(\'+shaderVec(b[0])+\'),!3(\'+shaderVec(b[5])+\'),yy(d*\'+shaderFloat(a[6]*b[4])+\'))\'):(\'!3(\'+shaderVec(b[0])+\')\'))+\',w=\'+shaderFloat(b[1])+\',u=\'+b[2]+\',o=\'+b[3]+\';\';d=5,c+=\'v=reflect(r,xx),z=\'+a[9]+\'*h.x,z=clamp(exp(-z*z*z*1.442695),.0,1.),x=clamp((1.+dot(normalize(v+r),r)),.0,1.),a=x*x,zz=o+(1.-o)*x*a*a*(u*.9+.1),y=mix(!3(1.),xz/dot(!3(.299,.587,.114),xz),w),m=!3(.0),zy=exp2(4.+6.*u),\';for(e in b=a[15])c+=\'p=length(b=u\'+d+\'-d),b/=p,p=max(1.,p-u\'+(d+2)+\')*\'+b[e][0]+\',p=1./max(1.,p*p),m+=mix((1.-w)*xz*q,y*pow(max(dot(reflect(r,xx),b),.0),zy)*(zy+2.)/8.,zz)*p*max(dot(b,xx),.0)*!3(u\'+(d+1)+\'),\',d+=3;d=5,c+=\'xy=yx*z*normalize(y)*o*(u*.9+.1)*zz,m=mix(!3(\'+shaderFloat(a[8])+\'),m,z),xxx+=normalize(v)*\'+a[7]+\';}else m=!3(\'+shaderFloat(a[8])+\');\';for(e in b=a[15])(a=b[e][1])?c+=\'b=s-u\'+d+\',p=dot(r,r),a=2.*dot(b,r),x=a*a-4.*p*(dot(b,b)-\'+(a*a)+\'),e=x<.0?!2(-1.):(x=sqrt(x),-.5*!2(a+x,a-x)/p),e=!2(min(e.x,e.y),max(e.x,e.y));if(e.x>.0&&e.y<h.x)m+=u\'+(d+2)+\'*!3(u\'+(d+1)+\')*pow((e.y-e.x)/\'+shaderFloat(a*2)+\',64.);\':0,d+=3','c+=\'n+=m*yx;if(all(lessThan(xy,!3(.01))))break;yx=xy,s=xxx,r=normalize(v);}h=!2(zx.x,l.y)*.5+.5,h.y=(1.-h.y-u4[5])/u4[7],f=texture2D(u1,h),n=max(!3(.0),mix(mix(mix(n,(n.x==n.y&&n.x==n.z)?n:!3(dot(n,!3(.299,.587,.114))),u4[1]),!3(u4[3]),smoothstep(.05,.95,u4[2])),f.rgb*u3,f.a*u4[6])-!3(.004)),x=(l.x+1.)*(l.y+1.)*(u4[0]*10.),gl_FragColor=!4((1.-(smoothstep(.98,1.,yy(l*8.+u4[0]*20.))+smoothstep(.95,1.,yy(l*1.5+u4[0]*10.))))*smoothstep(1.042+.008*cos(u4[0]*40.),.8,yyx(zx,8.))*(1.-(mod((mod(x,13.)+1.)*(mod(x,47.)+1.),.01))*8.)*((.95+.05*cos(u4[0]*41.))*(n*(6.2*n+.5))/(n*(6.2*n+!3(1.7))+!3(.06))+!3(smoothstep(.98,1.,yy(l*8.-u4[0]*40.)))),1.);}\';')(misc=raymarchers[i])],programs[i]=[5+misc[15].length*3,0,i+1]; + +misc = vomNew(10) , camPos = vomNew(3),lookAt=vomNew(3),camUp=vomNew(3),toNearPlane=0,textColour=vomNew(3) , lights= [[vomNew(3),0,0],[vomNew(3),0,0],[vomNew(3),0,0]]; +with(glCtx) { + for(i in shaders) + j=shaders[i], + shS(i=shaders[i]=crS(j[0]),j[1].replace(/!/g,'vec').replace(/%/g,'float')), + coS(i), + geSP(i,35713); + for(i in programs){ + var p=crP(),d=programs[i],ul=d.shift(); + for(j in d)atS(p,shaders[d[j]]); + liP(p),d=[]; + for(;ul--;)d[ul]=geUL(p,'u'+ul); + programs[i]=[p,d] + } + biB(i=34962,crB()),buD(i,vomNew([1,4,1,-1,-4,-1]),35044),biT(i=3553,crT()) + teP(i,j=10240,k=9728),teP(i,++j,k),teP(i,++j,k=33071),teP(i,++j,k), + teID(i,0,j=6408,j,5121,C2) +} + +mCurrentCol=timeStart = 0,mNumWords=10717272,mMixBuf=new Int32Array(mNumWords); + +mainfunc = function(){setTimeout(function(){ +requestAnimationFrame(draw=function(time){ + requestAnimationFrame(draw); + if ( timeStart == 0 ) { + A.currentTime = 0; + A.play( ); + timeStart = time; + previousFrame = timeStart - 33; + } + var delta = time - previousFrame; + demoTime = .001*(time - timeStart); + if ( delta < 33 ) { + return; + } + previousFrame = time - ( delta % 33 ); + + var ds = direction[t]; + while ( ds && ds[7] < demoTime ) { + ds=direction[++t]; + } + if ( ! ds ) { + A.pause( ); + return; + } + misc[0] = demoTime; + misc[7] = c2rHeight; + stepTime = demoTime - ds[5]; + rStepTime = stepTime / ds[6]; + with (glCtx) { + if ( ds[4] ) { + twoDCtx.clearRect( 0 , 0 , canvasWidth , 100 ); + teID( 3553 , ds[4]() , j=6408 , j , 5121 , C2 ); + } + + ds[2](); + vecNorm(cmW,vecSub(cmW,lookAt,camPos)); + vecNorm(cmU,vecCross(cmU,camUp,cmW)); + vecNorm(cmV,vecCross(cmV,cmW,cmU)); + vecScale(cmW,cmW,toNearPlane); + for(i=0;i<3;i++)cm[i*3]=cmU[i],cm[i*3+1]=cmV[i],cm[i*3+2]=cmW[i]; + + for (i in ds[3])ds[3][i](lights[i]); + + var p = programs[ds[1]]; + var u = 0; + usP( p[ 0 ] ); + p = p[1]; + veAP(enVAA(unM3fv(p[u++],un1i(p[u++],un3fv(p[u++],camPos)),cm)),2,5126,un3fv(p[u++],textColour),8,un1fv(p[u++],misc)); + for(i in ds[3])un3fv(p[u++],lights[i][0]),un1f(p[u++],lights[i][1]),un1f(p[u++],lights[i][2]); + drA(4,0,3) + } +}) +},500)}; + +for(t=i=0;i<53;i++)direction[i][5]=t,t+=(direction[i][6]=direction[i][0]/8),direction[i][7]=t; +t=0; + +if ( USE_SYNTH ) { + synthGen = setInterval(function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v){ + for(d=new Int32Array(mNumWords),f=[[[0,198,128,0,3,192,128,1,0,0,96,128,28,0,0,0,0,2,63,61,13,16,44,8,0,0],[1,2,3,4,5,2,3,4,6,7,1,2,3,4,5,2,3,4,5,2,3,4,1,2,3,8,9],[[[115,,,,,,,,,,,,117,,,,,,,,,,,,113],[12,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,96]],[[115,,,,,,,,,,,,,,,110],[12,,,,,,,,,,,,,,,12,,,,,,,,,,,,,,,,,,,,,115,,,,,,,,,,,,,,,148]],[[115,,,,,,,,,,,,117,,,,,,,,,,,,118],[12,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,96]],[[122,,,,,,,,,,,,,,,123,,,,,115],[12,,,,,,,,,,,,,,,12,,,,,12,,,,,,,,,,,,,,,,115,,,,,,,,,,,,,,,8,,,,,128]],[[118,,,,,,,,,,,,117,,,,,,,,,,,,113],[12,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,96]],[[115],[12,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,255]],[[,,,,,,,,,,,,,,,,118,118,118],[,,,,,,,,,,,,,,,,12,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,128]],[[122,,,,,,,,,,,,,,,123,,,,,115],[12,,,,,,,,,,,,,,,12,,,,,13,12,,,,,,,,,,,,,,,115,,,,,,,,,,,,,,,8,,,,,95,61]],[[],[]]]],[[0,255,116,1,0,255,101,0,0,15,1,4,45,0,13,6,1,2,62,27,60,48,0,0,44,2],[,1,,2,,1,,2,,3,4,4,5,4,5,4,5,4,5,4,5,4,5,4,3,6],[[[,,,,,139,,,139,139,,,,,,139,,,,,,,,139,,,139,139,,,,,139,139,139],[]],[[,,139,139,,,,,139,139,,,,,139,139,,,,,,,,,,139,139,139,,,,,139,139,139],[]],[[,,,139,,,,,139,139,,,,,,139,,,,,139,139,,,,,,139,,,,139,139,139],[]],[[139,,,,139,,139,,,139,,,139,,,,139,,139,,,139,,,139,,,,139,,139,,,139],[]],[[139,,,139,139,,139,,,139,,,139,,,139,139,,139,,,139,,,139,,,139,139,,139,,,139],[]],[[139,,,139,139,,139,,,139,,,139,,,139,139,,139,,,139,139],[]]]],[[0,0,140,0,0,0,140,0,0,128,4,10,34,0,187,5,0,1,239,135,34,19,108,8,8,4],[,,1,,1,,3,,1,3,2,2,2,2,2,3,2,3,2,3,2,3,2,3,1],[[[,,,,,,,,,,127,,,,,,,,,,,,127,,,,,,,,,,,,127],[]],[[,,,139,,,,,,139,139,,,,,139,,,,,,139,139,,,,,139,,,,,139,,139],[]],[[,,127,,,,,,,,127,,,,127,,,,,,,,127,,,,127,,,,,,,,127],[]]]],[[1,192,128,0,3,201,128,0,0,93,5,6,58,3,195,6,1,3,35,63,14,17,11,10,61,6],[,,,,1,2,3,4,5,6,7,5,8,9,10,11,8,9,10,11,12,13,14,15,16],[[[,,,,,,,,147,146,145,,,,,,,,,,145,147,146,,,,,,,,,,149,148,147],[]],[[,,,,,,151,151,151,,,,,,,146,142,138,,,,,,,,,,,,,,,147,150,147],[]],[[,,146,,,146,,,,,,,,,147,146,145,,,,,,,,,,146,145,142,,,142,,,142],[]],[[,,141,,,,,,,,,,,,141,140,139,,,146,,,146,,,127],[]],[[,139,,151,,,,,,,,,,151,,139,,,,,,,,,,139,,151],[]],[[,139,,151,150,149,,,,,,,,139,,149,148,147,,,,,,,,139,,,146,,,145,,,144],[]],[[,139,,,139,142,,,142,144,146,,144,,,,146,147,,,147,146,141,,137,,,,142,141,,141,,137],[]],[[139,,127,,142,,,130,,,144,142,141,,129,,141,,,144,,,141,144,142,,,,149,,,146,,,151],[]],[[,149,,149,,146,144,142,,,141,,142,,,139,,,,151,147,,,,146,147,,144,146,,142,144,141,146],[]],[[,,,,,,,,147,146,145,,,,,141,144,147,146,,144,,137,,,144,146,142,144,,,142,144,141,146],[]],[[,146,,151,,146,,,,144,142,144,146,,,,142,,,,,139,,,,,151,146,139,144,139,142,141,142,151],[]],[[,,147,,,149,146,,,142,,142,141,,,144,,144,,,144,146,142,144,142,,,,151,150,149,,137,,149],[]],[[,151,,,147,151,,,146,151,,,,,144,151,,149,147,149,151,,146,,,144,143,142,,,139,,151,139],[]],[[,,134,,,134,,,134,,,146,144,,,141,144,,,146,147,146,,,144,,139,140,141,,,153,,,141],[]],[[,142,,151,,,142,143,144,,,,151,,,139,,,137,,149,,137,,,,125,,,141,142,141,,,146],[]],[[139,,127,139,,127,139,,127,139,127],[]]]],[[2,160,128,1,0,160,128,0,1,60,4,7,41,0,60,4,1,3,14,0,35,32,31,12,89,1],[,,,,,,,,,,,,1,2,1,2,1,2,1,2,1,2,1,2,1,3],[[[,,139,,,,,,,,,,,,139,,,,,,,,,,,,139,,,,,139,139,,,139],[]],[[,,139,,,151,,,139,,,151,,,139,,,151,,,139,,,151,,,139,,,151,,,146,146,146,146],[]],[[,,139,,,151,,,139,,,151,,,139,,139,139,139,139,127],[]]]],[[2,100,128,0,3,201,128,0,0,0,0,6,29,0,195,6,1,3,28,229,119,77,147,6,61,2],[,,,,,,,,,6,1,2,3,4,5,2,3,4,1,2,3,4,1,2,3,7],[[[115,115,115,115,115,115,115,115,115,115,115,115,117,117,117,117,117,117,117,117,117,117,117,117,113,113,113,113,113,113,113,113,113,113,113,113],[]],[[115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110],[]],[[115,115,115,115,115,115,115,115,115,115,115,115,117,117,117,117,117,117,117,117,117,117,117,117,118,118,118,118,118,118,118,118,118,118,118,118],[]],[[110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,111,111,111,111,111,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115],[]],[[118,118,118,118,118,118,118,118,118,118,118,118,117,117,117,117,117,117,117,117,117,117,117,117,113,113,113,113,113,113,113,113,113,113,113,113],[]],[[,,,,,,,,,,,,,,,,,,130,,130,,130,,130,,130,,130,118,130,118,130,118,130,118],[,,,,,,,,,,,,,,,,,,26,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2]],[[110,122,,122,134,,110,122,,122,134,,110,122,,111,123,,111,123,115,127,139,127,115],[,,,,,,,,,,,,,,,,,,,,26,25,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,8,147]]]],[[2,100,128,0,3,201,128,0,0,0,5,6,58,0,195,6,1,2,135,0,0,32,147,6,121,6],[],[]],[[2,100,128,0,3,201,128,0,0,0,5,6,58,0,195,6,1,2,135,0,0,32,147,6,121,6],[],[]]][mCurrentCol],o=[],g=h=m=p=0;p<=26;p++)for(b=f[1][p],a=0;a<36;a++){((e=b?f[2][b-1][1][a]:0)?((f[0][e-1]=f[2][b-1][1][a+36]||0),e<14?(o=[]):0):0),c=(p*36+a)*5513;for(j=0;j<4;j++)if(n=b?f[2][b-1][0][a+j*36]:0){if(!o[n])for(q=f[0][10],r=f[0][11],s=f[0][12],t=getnotefreq(n+f[0][2]-128),l=getnotefreq(n+f[0][6]-128)*(1+.0008*f[0][7]),u=v=0,q*=q*4,r*=r*4,s*=s*4,o[n]=new Int32Array(q+r+s),k=0;k<q+r+s;k++)e=k<q?(k/q):(1-(k<q+r?0:((k-q-r)/s))),o[n][k]=(80*(mOscillators[f[0][0]](u+=t*(f[0][3]?(e*e):1))*f[0][1]+mOscillators[f[0][4]](v+=l*(f[0][8]?(e*e):1))*f[0][5]+R(0,1)*f[0][9])*e)|0;for(k=0,i=c*2;k<o[n].length;k++,i+=2)d[i]+=o[n][k]}q=f[0][20]*1e-5,r=f[0][24]/255,s=f[0][25]*5513;for(j=0;j<5513;j++)(((n=e=d[k=(c+j)*2])||m)?(t=1.5*S(f[0][18]*.00307999186353015873*(f[0][16]?(mOscillators[f[0][13]](P(2,f[0][15]-9)*k/5513)*f[0][14]/512+.5):1)),g+=t*h,l=(1-f[0][19]/255)*(e-h)-g,h+=t*l,e=f[0][17]==3?h:f[0][17]==1?l:g,q?(e*=q,e=(e<1?e>-1?mOscillators[0](e*.25):-1:1)/q):0,e*=f[0][21]/32,m=e*e>1e-5,t=S(6.283184*P(2,f[0][23]-9)*k/5513)*f[0][22]/512+.5,n=e*(1-t),e*=t):0),(k>=s?(n+=d[k-s+1]*r,e+=d[k-s]*r):0),mMixBuf[k]+=(d[k]=n|0),mMixBuf[k+1]+=(d[k+1]=e|0)} + if(++mCurrentCol==8)for(clearInterval(synthGen),s=(f=String.fromCharCode).apply(String,[82,73,70,70,168,16,71,1,87,65,86,69,102,109,116,32,16,0,0,0,1,0,2,0,68,172,0,0,16,177,2,0,4,0,16,0,100,97,116,97,132,16,71,1]),i=0;i<mNumWords||(((A=document.createElement('audio')).src='data:audio/wav;base64,'+btoa(s),A.oncanplaythrough=mainfunc)&&0);i++)e=mMixBuf[i],e=e<-32767?-32767:(e>32767?32767:e),s+=f(e&255,(e>>8)&255) + }, 0); +} else { + A = document.createElement("audio"); + A.oncanplaythrough=mainfunc; + A.src= 'music.ogg'; +} diff --git a/201410_-_Sine_City/sine-city-packing-7-variables.html b/201410_-_Sine_City/sine-city-packing-7-variables.html new file mode 100644 index 0000000..33ea5c4 --- /dev/null +++ b/201410_-_Sine_City/sine-city-packing-7-variables.html @@ -0,0 +1,3 @@ +<body> +<script language="javascript" src="sine-city-packing-7-variables.js"></script> + diff --git a/201410_-_Sine_City/sine-city-packing-7-variables.js b/201410_-_Sine_City/sine-city-packing-7-variables.js new file mode 100644 index 0000000..55b4466 --- /dev/null +++ b/201410_-_Sine_City/sine-city-packing-7-variables.js @@ -0,0 +1,418 @@ +var USE_SYNTH = 1; + +with(Math)S=sin,C=cos,M=max,N=min,P=pow; + + +f = function(a,b,c){return eval('(function('+a+'){'+b+(b?';':'')+(c?('return '+c):'')+'})')}, + +yz=f('a','','.003959503758*P(2,(a-128)/12)'), +$=[ + f('a','','S(a*6.283184)'), + f('a','','(a%1)<.5?1:-1'), + f('a','','2*(a%1)-1'), + f('a,b','b=(a%1)*4','(b<2)?(b-1):(3-b)') +], + +e=f('a','','f(\'a,b,c\',\'for(var i=a.length;--i>=0;)\'+a,\'a\')'), +zw=f('a,b,c','c=Math.sqrt(b[0]*b[0]+b[1]*b[1]+b[2]*b[2])','c?$f(a,b,1/c):yf(a,b)'), +fw=f('a,b,c','','y(a,b[1]*c[2]-b[2]*c[1],b[2]*c[0]-b[0]*c[2],b[0]*c[1]-b[1]*c[0])'), +y=e('a[i]=arguments[i+1]'), +yf=e('a[i]=b[i]'), +_f=e('a[i]=b[i]-c[i]'), +$f=e('a[i]=b[i]*c'), +e=f('a','','new Float32Array(a)'), + + +R=f('a,b','','a-b+Math.random()*b*2'); + + + +with(document.body)style.background='black',innerHTML='<canvas id=C1 style=position:fixed;cursor:none></canvas><canvas id=C2 style=display:none>'; +for(i in zx=C1.getContext('webgl'))zx[i.match(/^..|[A-Z]|\d[fi]v?$/g).join('')]=zx[i]; + +yx='precision highp %;varying !2 zx;', +w=f('a','','a+(a==(a|0)?\'.\':\'\')'), +v=f('a','','a.map(w).join(\',\')'); + +for(h=[[35633,yx+'attribute !2 i;void main(){gl_Position=!4(i,.0,1.),zx=i;}']],zy=[],i=0;i<4;i++)h[i+1]=[35632,f('a,b,c,d,e','b=\'uniform \',d=5,c=yx+b+\'mat3 u0;\'+b+\'sampler2D u1;\'+b+\'!3 u2,u3;\'+b+\'% u4[10];\';for(e in a[15])c+=b+\'!3 u\'+d+++\';\'+b+\'% u\'+d+++\', u\'+d+++\';\';c+=\'const !2 c=!2(1.,-1.)*\'+a[5]+\';% p,z,w,u,o,zy,q,x,a,zz;!2 e,h;!3 l=!3(zx,1.),m,r,s=u2,yx=!3(1.),n=!3(.0),b,v,xxx,xy,d,xx,xz,y;!4 f;% g(% x){return fract(sin(x)*43758.5453);}% yy(!3 x){m=floor(x),y=fract(x),y*=y*(3.-2.*y),z=m.x+m.y*57.+m.z*113.;return mix(mix(mix(g(z),g(z+1.),y.x),mix(g(z+57.),g(z+58.),y.x),y.y),mix(mix(g(z+113.),g(z+114.),y.x),mix(g(z+170.),g(z+171.),y.x),y.y),y.z);}% yyx(!2 x,% a){e=pow(abs(x),!2(a));return pow(e.x+e.y,1./a);}mat2 t(% x){e=!2(cos(x),sin(x));return mat2(-e.x,e.y,e.y,e.x);}% yz(!3 x){return length(mod(x.xy,!2(15.))-!2(7.5))-.5+.05*sin(x.z*9.42477);}!2 k(!3 x,% a){\'+a[14]+\'}void main(){l.y+=mod(u4[4],1.)*2.2;if(l.y>1.){if(l.y<1.2)discard;l.y-=2.2;}l.x*=1.6,r=normalize(l*u0);for(int j=0;j<2;j++){v=r,xxx=s,xy=!3(.0),x=.0,a=\'+a[1]+\';for(int i=0;i<\'+a[4]+\';i++){h=k(s+r*x,x);if(h.x<a||i>\'+a[4]+\'/(j+1)||x>\'+a[0]+\'.)break;x+=h.x*\'+a[3]+\',a*=\'+w(a[2])+\';}h.x=x;if(x<\'+a[0]+\'.){d=s+r*x,f=!4(k(d+c.xyy,x).x,k(d+c.yyx,x).x,k(d+c.yxy,x).x,k(d+c.xxx,x).x),xx=normalize(f.x*c.xyy+f.y*c.yyx+f.z*c.yxy+f.w*c.xxx),a=.0,p=\'+a[12]+\';for(int i=1;i<=\'+a[10]+\';i++)x=(%(i)/\'+a[10]+\'.)*\'+w(a[11])+\',m=d+xx*x,q=max(.1,1.-clamp(pow(a+=p*(x-k(m,distance(m,s)).x),1.),.0,1.)),p*=.5;\';for(e in d=a[13])b=[[[.05],.7,.02,.01],[[.2],.7,.9,.01,5,[.1]],[[1],.5,.4,.02],[[3,0,0],.3,.1,.6,6,[.6,0,0]],[[0,2,0],.9,.5,.4,15,[0,.2,0]],[[3,1.5,0],.95,.6,.9,.3,[.3,.6,0]],[[.1],0,.04,.002,3,[3]],[[0,1.5,2],.9,.3,.4]][d[e]],c+=(e>0?\'else \':\'\')+\'if(h.y==\'+e+\'.)xz=\'+(b[4]?(\'mix(!3(\'+v(b[0])+\'),!3(\'+v(b[5])+\'),yy(d*\'+w(a[6]*b[4])+\'))\'):(\'!3(\'+v(b[0])+\')\'))+\',w=\'+w(b[1])+\',u=\'+b[2]+\',o=\'+b[3]+\';\';d=5,c+=\'v=reflect(r,xx),z=\'+a[9]+\'*h.x,z=clamp(exp(-z*z*z*1.442695),.0,1.),x=clamp((1.+dot(normalize(v+r),r)),.0,1.),a=x*x,zz=o+(1.-o)*x*a*a*(u*.9+.1),y=mix(!3(1.),xz/dot(!3(.299,.587,.114),xz),w),m=!3(.0),zy=exp2(4.+6.*u),\';for(e in b=a[15])c+=\'p=length(b=u\'+d+\'-d),b/=p,p=max(1.,p-u\'+(d+2)+\')*\'+b[e][0]+\',p=1./max(1.,p*p),m+=mix((1.-w)*xz*q,y*pow(max(dot(reflect(r,xx),b),.0),zy)*(zy+2.)/8.,zz)*p*max(dot(b,xx),.0)*!3(u\'+(d+1)+\'),\',d+=3;d=5,c+=\'xy=yx*z*normalize(y)*o*(u*.9+.1)*zz,m=mix(!3(\'+w(a[8])+\'),m,z),xxx+=normalize(v)*\'+a[7]+\';}else m=!3(\'+w(a[8])+\');\';for(e in b=a[15])(a=b[e][1])?c+=\'b=s-u\'+d+\',p=dot(r,r),a=2.*dot(b,r),x=a*a-4.*p*(dot(b,b)-\'+(a*a)+\'),e=x<.0?!2(-1.):(x=sqrt(x),-.5*!2(a+x,a-x)/p),e=!2(min(e.x,e.y),max(e.x,e.y));if(e.x>.0&&e.y<h.x)m+=u\'+(d+2)+\'*!3(u\'+(d+1)+\')*pow((e.y-e.x)/\'+w(a*2)+\',64.);\':0,d+=3','c+=\'n+=m*yx;if(all(lessThan(xy,!3(.01))))break;yx=xy,s=xxx,r=normalize(v);}h=!2(zx.x,l.y)*.5+.5,h.y=(1.-h.y-u4[5])/u4[7],f=texture2D(u1,h),n=max(!3(.0),mix(mix(mix(n,(n.x==n.y&&n.x==n.z)?n:!3(dot(n,!3(.299,.587,.114))),u4[1]),!3(u4[3]),smoothstep(.05,.95,u4[2])),f.rgb*u3,f.a*u4[6])-!3(.004)),x=(l.x+1.)*(l.y+1.)*(u4[0]*10.),gl_FragColor=!4((1.-(smoothstep(.98,1.,yy(l*8.+u4[0]*20.))+smoothstep(.95,1.,yy(l*1.5+u4[0]*10.))))*smoothstep(1.042+.008*cos(u4[0]*40.),.8,yyx(zx,8.))*(1.-(mod((mod(x,13.)+1.)*(mod(x,47.)+1.),.01))*8.)*((.95+.05*cos(u4[0]*41.))*(n*(6.2*n+.5))/(n*(6.2*n+!3(1.7))+!3(.06))+!3(smoothstep(.98,1.,yy(l*8.-u4[0]*40.)))),1.);}\';')(x=[[100,.025,1,.7,64,.0005,.5,.3,.4,.015,4,2,.75,[0,1,2,3],'y=x+.1*(sin(x.zxy*.17+u4[0]*.5)+sin(x.yzx*.7+u4[0]*1.5))*8.5*(1.+cos(sin(x.z*.1)+x.z*.3)),z=14.-length(y.xy),w=x.x==.0?1.570795*(x.y>.0?1.:-1.):atan(x.y,x.x),q=8.35-u4[8]*1.35,y=!3(9.*(mod(w+x.z*.02,.628)-.314),length(x.xy)-9.,mod(x.z,12.56)-6.28),u=min(length(y.xy)-.25+.1*cos(x.z*8.+u4[0]*.1),length(y.yz)-.5),y=!3(q*(mod(w+x.z*.02,1.256636)-.628318),y.y+9.-q,mod(x.z,62.8318)-31.4159),o=step(u,z)+1.,z=min(u,z),u=length(y)-1.3;if(u<z)z=u,o=3.;y.y+=q-9.,u=yyx(y.yz,8.)-2.;if(u<z)z=u,o=.0;return !2(z,o);',[[.25,0],[.5,.5]]],[6,.00025,1.08,.7,100,.000008,10,.03,2.1,.2,6,.4,5.1,[0,2,5],'z=1.,y=x;for(int i=0;i<7;i++)x=2.*clamp(x,-!3(.58,.9,1.1),!3(.58,.9,1.1))-x,w=max((1.3+u4[9]*.1*cos(u4[0]*.5))/dot(x,x),1.),x*=w,z*=w;w=length(x.xy),e=!2(w-3.,-w*x.z/length(x)-2.*log(1.+.01*a))/abs(z),w=max(e.x,e.y),o=step(e.y,e.x),y+=!3(.1,.3,-.4)*u0-u2+.25*sin(x*1.),e.x=length(y)-.1*u4[8];if(e.x<w)w=e.x,o=2.;return !2(w,o);',[[.05]]],[100,.000025,1,.75,80,.00005,.5,.3,3,.01,4,.75,4.75,[6,0,4],'x.xy*=t(a*.009),w=min(min(yz(x.xzy),yz(x)),yz(x.yzx)),y=mod(x,!3(15.))-!3(7.5),o=step(z=max(length(max(abs(y)-!3(2.5),!3(.0)))-.25,3.5-length(y)),w),w=min(w,z),z=length(y+.1*sin(y*5.5+u4[0]))-2.;if(z<w)w=z,o=2.;return !2(w,o);',[[.05]]],[20,.0005,1,.6,128,.0001,.5,.002,.01,.08,4,.5,1.75,[2,7],'y=x,y.xz=mod(x.xz,8.)-4.,y.yz*=t(u4[8]+.1*a),y.xy*=t(u4[8]*.5+.2*a),y.y*=.9+.1*sin(u4[8]*5.),w=max(length(y)-3.,-min(length(y)-2.8,max(mod(y.y,.8)-.4,-mod(y.y+.4,.8)+.4))),z=x.y+1.+sin(x.x*4.+u4[8]*2.)*sin(x.z+u4[8])*.1,o=clamp(.5+.5*(z-w)/1.,.0,1.),w=mix(z,w,o)-1.*o*(1.-o),y=x,y.xz=mod(y.xz,8.)-4.,y/=1.25+.25*sin(u4[8]*5.),y.xy*=t(u4[8]*5.),y.yz*=t(u4[8]*2.5),z=max(length(y)-1.,.04-length(max(abs(mod(y,.5)-.25)-!3(.15),!3(.0))));return !2(min(w,z),step(z,w));',[[.02],[.05,.5],[.05,.5]]]][i])],zy[i]=[5+x[15].length*3,0,i+1]; + +with(zx) { + for(i in h) + j=h[i], + shS(i=h[i]=crS(j[0]),j[1].replace(/!/g,'vec').replace(/%/g,'float')), + coS(i), + geSP(i,35713); + for(i in zy){ + w=crP(),m=zy[i],x=m.shift(); + for(j in m)atS(w,h[m[j]]); + liP(w),m=[]; + for(;x--;)m[x]=geUL(w,'u'+x); + zy[i]=[w,m] + } + biB(i=34962,crB()),buD(i,e([1,4,1,-1,-4,-1]),35044),biT(i=3553,crT()) + teP(i,j=10240,k=9728),teP(i,++j,k),teP(i,++j,k=33071),teP(i,++j,k), + teID(i,0,j=6408,j,5121,C2) +} + +w=f('a,b','','f(\'a\',\'yf(a[0],p),a[1]=\'+a+\',a[2]=\'+b)'), +v=f('a','','f(\'\',\'x[4]=(\'+(a>0?a:\'\')+\'-xz*\'+a+\'/h[t][6])*R(.875,.125)\')'), +q=f('a,b,c,d','c=v(c),d=f(\'a,b,c,d\',\'y(p,x[2]=x[8]=0,4,d=f*3),y(s,a,0,d+b),y(n,0,0,1),c()\')','function(){d(a,b,c)}'), +u=f('a','','f(\'a\',\'y(a[0],\'+a+\'*C(f*2)*5,3,\'+a+\'*S(f*2)*5+f*30),a[1]=1,a[2]=4\')'), +r=f('a','a=v(a)','function(){r(),a()}'), +o=f('a','_f(a[0],p,zw(a[0],s)),a[0][1]-=.5,a[1]=3,a[2]=30'), +m=f('','v(\'Greetings to ... Mog, Sycop, Tim & Wullon ... Adinpsz ... Alcatraz ... ASD ... Bits\\\'n\\\'Bites ... Brain Control ... Cocoon ... Conspiracy ... Ctrl+Alt+Test ... Fairlight ... Farbrausch ... Kewlers ... LNX ... Loonies ... Mercury ... Popsy Team ... Razor 1911 ... RGBA ... 7th Cube ... Still ... TPOLM ... TRBL ... Umlaut Design ... X-Men ... Youth Uprising ... Everyone here at DemoJS 2014!\',yw*(1-(f-h[34][5])/2)),x[5]=1-zf+R(.01,.01),y(fz,x[6]=1,1,1)'), +g=f('a','','f(\'a,b\',\'b=f-h[\'+a+\'][5],y(a[0],4*S(b*.5)*C(b*.7),3*C(b*1.5),b*30*fx+14+16*S(b*3.3)*C(b*.77)),a[1]=1,a[2]=2\')'), + +h = [ + [ + 36 , + 0 , + f('','w(x[2]=1-z*z*z,_=5)') , + a=[w(3,20)] + ] , [ + 18 , + 0 , + f('','w(x[2]=0,_=5-2.25*z)') , + a + ] , [ + 36 , + 0 , + f('','w(x[2]=z,_=2.75-2.25*z)') , + a + ] , [ + 18 , + 3 , + f('a','y(p,0,4,a=f*3),y(s,4,0,a),y(n,0,0,1),x[2]=1-z*z*z,_=2.5') , + [ w(.75,8) ] + ] , [ + 22 , + 3 , + q(4,0,0) , + a=[w(1,8)] + ] , [ + 22 , + 3 , + q(2,-2,0) , + a + ] , [ + 3 , + 3 , + q( 6 , 0 , -.5 ) , + b=[w(.5,4)] + ] , [ + 9 , + 3 , + q( 6 , 0 , .5 ) , + b + ] , [ + 3 , + 3 , + q( 2 , 2 , -.2 ) , + a + ] , [ + 9 , + 3 , + q( 2 , 2 , .2 ) , + a + ] , [ + 3 , + 3 , + q( 2 , 5 , -.7 ) , + a=[ w(1,2) ] + ] , [ + 7 , + 3 , + q( 2 , 2 , .7 ) , + a + ] , [ + 9 , + 3 , + f('a','y(p,0,4+z*2,a=f*3),y(s,2,0,a+2),y(n,0,0,x[3]=1),x[2]=z') , + a + ] , [ + 21 , + 1 , + f('','r(x[2]=1-z*z*z,x[3]=1)'), + a=[f('a','yf(a[0],p),a[0][2]+=2,a[1]=1,a[2]=3')] + ] , [ + 14 , + 1 , + r(0) , + a + ] , [ + 3 , + 1 , + r(-.4) , + a + ] , [ + 9 , + 1 , + r(.4) , + a + ] , [ + 3 , + 1 , + r(-.2) , + a + ] , [ + 9 , + 1 , + r(.2) , + a + ] , [ + 12 , + 1 , + f('','r(x[4]=(-(6*z)%1)*R(.875,.125))'), + a + ] , [ + 22 , + 1 , + f('','r(x[4]=((30*z)%1)*R(.925,.075),x[2]=z,x[3]=.4),_=3-2.5*M(1,2*z)'), + a + ] , [ + 3 , + 1 , + b=f('','r(x[4]=0,x[2]=1)'), + a + ] , [ + 12 , + 1 , + b , + a, + f('','m(0,.08,1,1,1,1)') + ] , [ + 12 , + 1 , + b , + a, + f('','m(0,.08,1-z,1,1,1)') + ] , [ + 12 , + 1 , + b , + a, + f('','m(1,.08,1-z,1,1,1)') + ] , [ + 20 , + 2 , + f('','o(x[2]=1-z)') , + b=[w(1,30)], + f('','m(2,.04,z,1,1,1)') + ] , [ + 52 , + 2 , + f('','o(x[2]=0)'), + b, + f('','m(2,.04,1,1,1,1)') + ] , [ + 12 , + 2 , + f('','o(x[2]=1-M(0,z*2),x[3]=1)'), + b, + f('','m(2,.04,1,1-z,1-z/2,1-z)') + ] , [ + 12 , + 2 , + f('a','o(x[1]=1-z/2,x[4]=(1-z)*.7+R(a=.0125,a))') , + b, + f('','m(2,.04,1,0,.5,0)') + ] , [ + 9 , + 2 , + f('','g(29,x[1]=(1-z)/2,x[2]=1-M(0,z*1.5),x[4]+=x[1]*.6)'), + b, + f('','m(2,.04,1-z,0,.5,0)') + ] , [ + 69 , + 2 , + f('','g(29,x[1]=0)') , + b + ] , [ + 11 , + 2 , + f('','g(29,x[2]=z,x[3]=.2)'), + b + ] , [ + 11 , + 0 , + f('','e(32,x[2]=1-z)'), + b=[ o ] + ] , [ + 17 , + 0 , + f('','e(32,x[2]=0,x[4]=(1-z)*1.2*R(1,.02))') , + b + ] , [ + 18 , + 0 , + f('','e(32,x[4]=0,x[8]=z)') , + b , + m + ] , [ + 36 , + 0 , + f('','e(32,x[2]=1-N(x[8]=1,4*z))'), + b = [ o , g(32) ], + m + ] , [ + 33 , + 0 , + f('','e(32,x[2]=z,x[3]=.7,x[4]=-((4*z)%1)*R(1,.05))'), + b , + m + ] , [ + 9 , + 1 , + f('','u(x[4]=0,x[2]=z,x[3]=1)'), + a, + m + ] , [ + 20 , + 1 , + f('','u(z,x[2]=0)'), + a, + m + ] , [ + 31 , + 1 , + f('','u(1,x[2]=1-N(1,5*z))'), + a, + m + ] , [ + 5 , + 1 , + f('','u(1,x[2]=1-z)'), + a, + m + ] , [ + 18 , + 1 , + f('','u(1,x[2]=1-N(1,5*z),x[4]=M(0,1.6*z-.8)*R(1,.05))'), + a, + m + ] , [ + 12 , + 1 , + f('','u(1,x[2]=z,x[4]=(1-z)*.8*R(1,.05),x[3]=.1)'), + a, + m + ] , [ + 22 , + 3 , + f('','q(x[2]=1-z,x[4]=0)'), + a = [ w(.6,30) , u(1),u(-1) ], + m + ] , [ + 59 , + 3 , + f('','q(x[2]=1-N(1,(12*z)%4),x[3]=.8)'), + a, + m + ] , [ + 8 , + 3 , + f('','q(x[2]=z,x[4]=R(0,x[3]=.1))'), + a + ] , [ + 7 , + 0 , + f('','x[fx=2]=1-z,e(46,x[4]=R(0,.1),x[8]=1)'), + a = [ o , g(46) ] + ] , [ + 22 , + 0 , + f('','e(46,x[4]=R(0,.1))'), + a + ] , [ + 10 , + 0 , + f('','e(46,x[4]=R(0,.1+z*.4)+xz*4,x[2]=z,x[3]=1)'), + a + ] , [ + 10 , + 2 , + f('','g(49,x[2]=1-z),x[4]=R(0,.5)+(f-h[48][5])*4'), + a=[ w(1,30) ] + ] , [ + 40 , + 2 , + f('','g(49),x[4]=R(0,.5)-(f-h[48][5])*6'), + a + ] , [ + 40 , + 2 , + f('','g(49),x[4]=R(x[3]=0,.5)+(f-h[48][5])*8,x[2]=z'), + a + ] , [ + 68 , + 2 , + f('','g(49,x[2]=1)'), + a + ] +], + +fx=1, +x = e(10) , p = e(3),s=e(3),n=e(3),fz=e(3),xw= [[e(3),0,0],[e(3),0,0],[e(3),0,0]], +ff=e(3),fy=e(3),yy=e(3),xf=e(9), +mCurrentCol=zz=0,_=new Int32Array(xz=10717272); + +w=f('a','y(p,-6,0,a=f*6),y(s,x[1]=1,x[8]=0,a),y(n,0,1,0)'), +q=f('a','a=f*5,y(p,C(f)*12,8,S(f)*12+a),y(s,1,0,a),y(n,0,1,0),_=2.5,x[8]=f-h[43][5]'), +r=f('','y(p,4,2.5+.025*f,6.7),y(s,x[8]=x[9]=0,2.5-.05*f,6.7),y(n,0,0,1),_=3'), +u=f('a,b','y(p,5*S(b=f*.2),9*C(f*.41),7.8),y(s,C(b),S(f*.33),p[2]-2),y(n,0,0,x[9]=1),x[8]=a,_=3'), +v=f('a,b,c','with(yx)shadowBlur=ww/5,fillText(a,b,c=ww/2),shadowBlur=0,strokeText(a,b,c)'), +m=f('a,b,c,d,e,f','v([\'TheT(ourist)\',\'presents\',\'Sine City\'][a],yw/15),x[5]=1-zf+R(0,b),x[6]=c,y(fz,d,e,f)'), +o=f('a,b','a=f-h[25][5],y(p,b=a*10-80,0,0),y(s,b+C(a*.5)*80,S(a*.25)*40,100),y(n,0,_=2.5,0)'), +g=f('a,b','a=f-h[a][5],y(p,0,0,b=a*20-80),y(s,C(a*.5)*80,S(a*.25)*40,100+b),y(n,0,1,0),x[4]=R(a=.0125,a)'), +e=f('a','a=(f-h[a][5])*30*fx,y(p,1.1*C(a*.1),S(a*.02),a),a+=5,y(s,-S(a*.05),-.7*C(a*.033),a),y(n,0,_=2,0)'), + +mainfunc = function(){setTimeout(function(){ +requestAnimationFrame(draw=function(a){ + requestAnimationFrame(draw); + zz?0:(A.currentTime=0,A.play(),zz=a,$=zz-33); + yz = a - $; + f = .001*(a - zz); + if ( yz < 33 ) { + return; + } + $ = a - ( yz % 33 ); + + j = h[t]; + while ( j && j[7] < f ) { + j=h[++t]; + } + if ( ! j ) { + A.pause( ); + return; + } + x[0] = f; + x[7] = zf; + xz = f - j[5]; + z = xz / j[6]; + with (zx) { + j[4]?(yx.clearRect(0,0,yw,100),teID(3553,j[4](),k=6408,k,5121,C2)):0,j[2](),zw(yy,_f(yy,s,p)),zw(ff,fw(ff,n,yy)),zw(fy,fw(fy,yy,ff)),$f(yy,yy,_); + for(i=0;i<3;i++)xf[i*3]=ff[i],xf[i*3+1]=fy[i],xf[i*3+2]=yy[i]; + for(i in j[3])j[3][i](xw[i]); + + f=zy[j[1]],usP(f[k=0]),f=f[1],veAP(enVAA(unM3fv(f[k++],un1i(f[k++],un3fv(f[k++],p)),xf)),2,5126,un3fv(f[k++],fz),8,un1fv(f[k++],x)); + for(i in j[3])un3fv(f[k++],xw[i][0]),un1f(f[k++],xw[i][1]),un1f(f[k++],xw[i][2]); + drA(4,0,3) + } +}) +},500)}; + +for(t=i=0;i<53;i++)h[i][5]=t,t+=(h[i][6]=h[i][0]/8),h[i][7]=t; +t=0, +yx = C2.getContext('2d'); +(onresize=f('a,b,c,d,e','with(yx)a=innerWidth,b=innerHeight,c=(b*1.6)|0,d=(a*.625)|0,zx.vi(0,0,C2.style.width=C2.width=C1.width=yw=c>a?a:c,C1.height=e=c>a?d:b),ww=C2.style.height=C2.height=M(e/8,100),zf=ww/e,C1.style.left=((a-yw)/2)|0,C1.style.top=((b-e)/2)|0,shadowColor=\'#ccc\',font=\'normal small-caps bold \'+((ww/2)|0)+\'px monospace\',fillStyle=\'#111\',strokeStyle=\'#ddd\''))(); + +if ( USE_SYNTH ) { + synthGen = setInterval(function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,u,v,w){ + for(d=new Int32Array(xz),f=[[[0,198,128,0,3,192,128,1,0,0,96,128,28,0,0,0,0,2,63,61,13,16,44,8,0,0],[1,2,3,4,5,2,3,4,6,7,1,2,3,4,5,2,3,4,5,2,3,4,1,2,3,8,9],[[[115,,,,,,,,,,,,117,,,,,,,,,,,,113],[12,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,96]],[[115,,,,,,,,,,,,,,,110],[12,,,,,,,,,,,,,,,12,,,,,,,,,,,,,,,,,,,,,115,,,,,,,,,,,,,,,148]],[[115,,,,,,,,,,,,117,,,,,,,,,,,,118],[12,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,96]],[[122,,,,,,,,,,,,,,,123,,,,,115],[12,,,,,,,,,,,,,,,12,,,,,12,,,,,,,,,,,,,,,,115,,,,,,,,,,,,,,,8,,,,,128]],[[118,,,,,,,,,,,,117,,,,,,,,,,,,113],[12,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,96]],[[115],[12,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,255]],[[,,,,,,,,,,,,,,,,118,118,118],[,,,,,,,,,,,,,,,,12,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,128]],[[122,,,,,,,,,,,,,,,123,,,,,115],[12,,,,,,,,,,,,,,,12,,,,,13,12,,,,,,,,,,,,,,,115,,,,,,,,,,,,,,,8,,,,,95,61]],[[],[]]]],[[0,255,116,1,0,255,101,0,0,15,1,4,45,0,13,6,1,2,62,27,60,48,0,0,44,2],[,1,,2,,1,,2,,3,4,4,5,4,5,4,5,4,5,4,5,4,5,4,3,6],[[[,,,,,139,,,139,139,,,,,,139,,,,,,,,139,,,139,139,,,,,139,139,139],[]],[[,,139,139,,,,,139,139,,,,,139,139,,,,,,,,,,139,139,139,,,,,139,139,139],[]],[[,,,139,,,,,139,139,,,,,,139,,,,,139,139,,,,,,139,,,,139,139,139],[]],[[139,,,,139,,139,,,139,,,139,,,,139,,139,,,139,,,139,,,,139,,139,,,139],[]],[[139,,,139,139,,139,,,139,,,139,,,139,139,,139,,,139,,,139,,,139,139,,139,,,139],[]],[[139,,,139,139,,139,,,139,,,139,,,139,139,,139,,,139,139],[]]]],[[0,0,140,0,0,0,140,0,0,128,4,10,34,0,187,5,0,1,239,135,34,19,108,8,8,4],[,,1,,1,,3,,1,3,2,2,2,2,2,3,2,3,2,3,2,3,2,3,1],[[[,,,,,,,,,,127,,,,,,,,,,,,127,,,,,,,,,,,,127],[]],[[,,,139,,,,,,139,139,,,,,139,,,,,,139,139,,,,,139,,,,,139,,139],[]],[[,,127,,,,,,,,127,,,,127,,,,,,,,127,,,,127,,,,,,,,127],[]]]],[[1,192,128,0,3,201,128,0,0,93,5,6,58,3,195,6,1,3,35,63,14,17,11,10,61,6],[,,,,1,2,3,4,5,6,7,5,8,9,10,11,8,9,10,11,12,13,14,15,16],[[[,,,,,,,,147,146,145,,,,,,,,,,145,147,146,,,,,,,,,,149,148,147],[]],[[,,,,,,151,151,151,,,,,,,146,142,138,,,,,,,,,,,,,,,147,150,147],[]],[[,,146,,,146,,,,,,,,,147,146,145,,,,,,,,,,146,145,142,,,142,,,142],[]],[[,,141,,,,,,,,,,,,141,140,139,,,146,,,146,,,127],[]],[[,139,,151,,,,,,,,,,151,,139,,,,,,,,,,139,,151],[]],[[,139,,151,150,149,,,,,,,,139,,149,148,147,,,,,,,,139,,,146,,,145,,,144],[]],[[,139,,,139,142,,,142,144,146,,144,,,,146,147,,,147,146,141,,137,,,,142,141,,141,,137],[]],[[139,,127,,142,,,130,,,144,142,141,,129,,141,,,144,,,141,144,142,,,,149,,,146,,,151],[]],[[,149,,149,,146,144,142,,,141,,142,,,139,,,,151,147,,,,146,147,,144,146,,142,144,141,146],[]],[[,,,,,,,,147,146,145,,,,,141,144,147,146,,144,,137,,,144,146,142,144,,,142,144,141,146],[]],[[,146,,151,,146,,,,144,142,144,146,,,,142,,,,,139,,,,,151,146,139,144,139,142,141,142,151],[]],[[,,147,,,149,146,,,142,,142,141,,,144,,144,,,144,146,142,144,142,,,,151,150,149,,137,,149],[]],[[,151,,,147,151,,,146,151,,,,,144,151,,149,147,149,151,,146,,,144,143,142,,,139,,151,139],[]],[[,,134,,,134,,,134,,,146,144,,,141,144,,,146,147,146,,,144,,139,140,141,,,153,,,141],[]],[[,142,,151,,,142,143,144,,,,151,,,139,,,137,,149,,137,,,,125,,,141,142,141,,,146],[]],[[139,,127,139,,127,139,,127,139,127],[]]]],[[2,160,128,1,0,160,128,0,1,60,4,7,41,0,60,4,1,3,14,0,35,32,31,12,89,1],[,,,,,,,,,,,,1,2,1,2,1,2,1,2,1,2,1,2,1,3],[[[,,139,,,,,,,,,,,,139,,,,,,,,,,,,139,,,,,139,139,,,139],[]],[[,,139,,,151,,,139,,,151,,,139,,,151,,,139,,,151,,,139,,,151,,,146,146,146,146],[]],[[,,139,,,151,,,139,,,151,,,139,,139,139,139,139,127],[]]]],[[2,100,128,0,3,201,128,0,0,0,0,6,29,0,195,6,1,3,28,229,119,77,147,6,61,2],[,,,,,,,,,6,1,2,3,4,5,2,3,4,1,2,3,4,1,2,3,7],[[[115,115,115,115,115,115,115,115,115,115,115,115,117,117,117,117,117,117,117,117,117,117,117,117,113,113,113,113,113,113,113,113,113,113,113,113],[]],[[115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110],[]],[[115,115,115,115,115,115,115,115,115,115,115,115,117,117,117,117,117,117,117,117,117,117,117,117,118,118,118,118,118,118,118,118,118,118,118,118],[]],[[110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,111,111,111,111,111,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115],[]],[[118,118,118,118,118,118,118,118,118,118,118,118,117,117,117,117,117,117,117,117,117,117,117,117,113,113,113,113,113,113,113,113,113,113,113,113],[]],[[,,,,,,,,,,,,,,,,,,130,,130,,130,,130,,130,,130,118,130,118,130,118,130,118],[,,,,,,,,,,,,,,,,,,26,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2]],[[110,122,,122,134,,110,122,,122,134,,110,122,,111,123,,111,123,115,127,139,127,115],[,,,,,,,,,,,,,,,,,,,,26,25,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,8,147]]]],[[2,100,128,0,3,201,128,0,0,0,5,6,58,0,195,6,1,2,135,0,0,32,147,6,121,6],[],[]],[[2,100,128,0,3,201,128,0,0,0,5,6,58,0,195,6,1,2,135,0,0,32,147,6,121,6],[],[]]][t],o=[],g=h=m=p=0;p<=26;p++)for(b=f[1][p],a=0;a<36;a++){((e=b?f[2][b-1][1][a]:0)?((f[0][e-1]=f[2][b-1][1][a+36]||0),e<14?(o=[]):0):0),c=(p*36+a)*5513;for(j=0;j<4;j++)if(n=b?f[2][b-1][0][a+j*36]:0){if(!o[n])for(q=f[0][10],r=f[0][11],s=f[0][12],w=yz(n+f[0][2]-128),l=yz(n+f[0][6]-128)*(1+.0008*f[0][7]),u=v=0,q*=q*4,r*=r*4,s*=s*4,o[n]=new Int32Array(q+r+s),k=0;k<q+r+s;k++)e=k<q?(k/q):(1-(k<q+r?0:((k-q-r)/s))),o[n][k]=(80*($[f[0][0]](u+=w*(f[0][3]?(e*e):1))*f[0][1]+$[f[0][4]](v+=l*(f[0][8]?(e*e):1))*f[0][5]+R(0,1)*f[0][9])*e)|0;for(k=0,i=c*2;k<o[n].length;k++,i+=2)d[i]+=o[n][k]}q=f[0][20]*1e-5,r=f[0][24]/255,s=f[0][25]*5513;for(j=0;j<5513;j++)(((n=e=d[k=(c+j)*2])||m)?(w=1.5*S(f[0][18]*.00307999186353015873*(f[0][16]?($[f[0][13]](P(2,f[0][15]-9)*k/5513)*f[0][14]/512+.5):1)),g+=w*h,l=(1-f[0][19]/255)*(e-h)-g,h+=w*l,e=f[0][17]==3?h:f[0][17]==1?l:g,q?(e*=q,e=(e<1?e>-1?$[0](e*.25):-1:1)/q):0,e*=f[0][21]/32,m=e*e>1e-5,w=S(6.283184*P(2,f[0][23]-9)*k/5513)*f[0][22]/512+.5,n=e*(1-w),e*=w):0),(k>=s?(n+=d[k-s+1]*r,e+=d[k-s]*r):0),_[k]+=(d[k]=n|0),_[k+1]+=(d[k+1]=e|0)} + if(++t==8)for(clearInterval(synthGen),s=(f=String.fromCharCode).apply(String,[82,73,70,70,168,16,71,1,87,65,86,69,102,109,116,32,16,0,0,0,1,0,2,0,68,172,0,0,16,177,2,0,4,0,16,0,100,97,116,97,132,16,71,1]),t=i=0;i<xz||(((A=document.createElement('audio')).src='data:audio/wav;base64,'+btoa(s),A.oncanplaythrough=mainfunc)&&0);i++)e=_[i],e=e<-32767?-32767:(e>32767?32767:e),s+=f(e&255,(e>>8)&255) + }, 0); +} else { + A = document.createElement("audio"); + A.oncanplaythrough=mainfunc; + A.src= 'music.ogg'; +} diff --git a/201410_-_Sine_City/sine-city-packing-8-finalize.html b/201410_-_Sine_City/sine-city-packing-8-finalize.html new file mode 100644 index 0000000..1f232fd --- /dev/null +++ b/201410_-_Sine_City/sine-city-packing-8-finalize.html @@ -0,0 +1,3 @@ +<body> +<script language="javascript" src="sine-city-packing-8-finalize.js"></script> + diff --git a/201410_-_Sine_City/sine-city-packing-8-finalize.js b/201410_-_Sine_City/sine-city-packing-8-finalize.js new file mode 100644 index 0000000..e0326c4 --- /dev/null +++ b/201410_-_Sine_City/sine-city-packing-8-finalize.js @@ -0,0 +1,80 @@ +f=function(a,b,c){return eval('(function('+a+'){'+b+(b?';':'')+(c?('return '+c):'')+'})')}, + +yz=f('a','','.003959503758*P(2,(a-128)/12)'),$=[f('a','','S(a*6.283184)'),f('a','','(a%1)<.5?1:-1'),f('a','','2*(a%1)-1'),f('a,b','b=(a%1)*4','(b<2)?(b-1):(3-b)')],e=f('a','','f(\'a,b,c\',\'for(var i=a.length;--i>=0;)\'+a,\'a\')'),zw=f('a,b,c','c=Math.sqrt(b[0]*b[0]+b[1]*b[1]+b[2]*b[2])','c?$f(a,b,1/c):yf(a,b)'),fw=f('a,b,c','','y(a,b[1]*c[2]-b[2]*c[1],b[2]*c[0]-b[0]*c[2],b[0]*c[1]-b[1]*c[0])'),y=e('a[i]=arguments[i+1]'),yf=e('a[i]=b[i]'),_f=e('a[i]=b[i]-c[i]'),$f=e('a[i]=b[i]*c'),e=f('a','','new Float32Array(a)'),R=f('a,b','','a-b+Math.random()*b*2'); + +with(Math)S=sin,C=cos,M=max,N=min,P=pow;with(document.body)style.background='black',innerHTML='<canvas id=C1 style=position:fixed;cursor:none></canvas><canvas id=C2 style=display:none>';for(i in zx=C1.getContext('webgl'))zx[i.match(/^..|[A-Z]|\d[fi]v?$/g).join('')]=zx[i];yx='precision highp float;varying vec2 zx;',w=f('a','','a+(a==(a|0)?\'.\':\'\')'),v=f('a','','a.map(w).join(\',\')'); + +for(h=[[35633,yx+'attribute vec2 i;void main(){gl_Position=vec4(i,.0,1.),zx=i;}']],zy=[],i=0;i<4;i++)h[i+1]=[35632,f('a,b,c,d,e','b=\'uniform \',d=5,c=yx+b+\'mat3 u0;\'+b+\'sampler2D u1;\'+b+\'vec3 u2,u3;\'+b+\'float u4[10];\';for(e in a[15])c+=b+\'vec3 u\'+d+++\';\'+b+\'float u\'+d+++\', u\'+d+++\';\';c+=\'const vec2 c=vec2(1.,-1.)*\'+a[5]+\';float p,z,w,u,o,zy,q,x,a,zz;vec2 e,h;vec3 l=vec3(zx,1.),m,r,s=u2,yx=vec3(1.),n=vec3(.0),b,v,xxx,xy,d,xx,xz,y;vec4 f;float g(float x){return fract(sin(x)*43758.5453);}float yy(vec3 x){vec3 m=floor(x),y=fract(x);y*=y*(3.-2.*y);float z=m.x+m.y*57.+m.z*113.;return mix(mix(mix(g(z),g(z+1.),y.x),mix(g(z+57.),g(z+58.),y.x),y.y),mix(mix(g(z+113.),g(z+114.),y.x),mix(g(z+170.),g(z+171.),y.x),y.y),y.z);}float yyx(vec2 x,float a){e=pow(abs(x),vec2(a));return pow(e.x+e.y,1./a);}mat2 t(float x){e=vec2(cos(x),sin(x));return mat2(-e.x,e.y,e.y,e.x);}float yz(vec3 x){return length(mod(x.xy,vec2(15.))-vec2(7.5))-.5+.05*sin(x.z*9.42477);}vec2 k(vec3 x,float a){\'+a[14]+\'}void main(){l.y+=mod(u4[4],1.)*2.2;if(l.y>1.){if(l.y<1.2)discard;l.y-=2.2;}l.x*=1.6,r=normalize(l*u0);for(int j=0;j<2;j++){v=r,xxx=s,xy=vec3(.0),x=.0,a=\'+a[1]+\';for(int i=0;i<\'+a[4]+\';i++){h=k(s+r*x,x);if(h.x<a||i>\'+a[4]+\'/(j+1)||x>\'+a[0]+\'.)break;x+=h.x*\'+a[3]+\',a*=\'+w(a[2])+\';}h.x=x;if(x<\'+a[0]+\'.){d=s+r*x,f=vec4(k(d+c.xyy,x).x,k(d+c.yyx,x).x,k(d+c.yxy,x).x,k(d+c.xxx,x).x),xx=normalize(f.x*c.xyy+f.y*c.yyx+f.z*c.yxy+f.w*c.xxx),a=.0,p=\'+a[12]+\';for(int i=1;i<=\'+a[10]+\';i++)x=(float(i)/\'+a[10]+\'.)*\'+w(a[11])+\',m=d+xx*x,q=max(.1,1.-clamp(pow(a+=p*(x-k(m,distance(m,s)).x),1.),.0,1.)),p*=.5;\';for(e in d=a[13])b=[[[.05],.7,.02,.01],[[.2],.7,.9,.01,5,[.1]],[[1],.5,.4,.02],[[2,0,0],.3,.1,.6,5,[.1,0,0]],[[0,2,0],.7,.9,.8,15,[0,.2,0]],[[3,1.5,0],.95,.6,.9,.3,[.3,.6,0]],[[.1],0,.04,.002,3,[3]],[[0,1.5,2],.5,.5,.7]][d[e]],c+=(e>0?\'else \':\'\')+\'if(h.y==\'+e+\'.)xz=\'+(b[4]?(\'mix(vec3(\'+v(b[0])+\'),vec3(\'+v(b[5])+\'),yy(d*\'+w(a[6]*b[4])+\'))\'):(\'vec3(\'+v(b[0])+\')\'))+\',w=\'+w(b[1])+\',u=\'+b[2]+\',o=\'+b[3]+\';\';d=5,c+=\'v=reflect(r,xx),z=\'+a[9]+\'*h.x,z=clamp(exp(-z*z*z*1.442695),.0,1.),x=clamp((1.+dot(normalize(v+r),r)),.0,1.),a=x*x,zz=o+(1.-o)*x*a*a*(u*.9+.1),y=mix(vec3(1.),xz/dot(vec3(.299,.587,.114),xz),w),m=vec3(.0),zy=exp2(4.+6.*u),\';for(e in b=a[15])c+=\'p=length(b=u\'+d+\'-d),b/=p,p=max(1.,p-u\'+(d+2)+\')*\'+b[e][0]+\',p=1./max(1.,p*p),m+=mix((1.-w)*xz*q,y*pow(max(dot(reflect(r,xx),b),.0),zy)*(zy+2.)/8.,zz)*p*max(dot(b,xx),.0)*vec3(u\'+(d+1)+\'),\',d+=3;d=5,c+=\'xy=yx*z*normalize(y)*o*(u*.9+.1)*zz,m=mix(vec3(\'+w(a[8])+\'),m,z),xxx+=normalize(v)*\'+a[7]+\';}else m=vec3(\'+w(a[8])+\');\';for(e in b=a[15])(j=b[e][1])?c+=\'b=s-u\'+d+\',p=dot(r,r),a=2.*dot(b,r),x=a*a-4.*p*(dot(b,b)-\'+(j*j)+\'),e=x>.0?(x=sqrt(x),-.5*vec2(a+x,a-x)/p):vec2(-1.),e=vec2(min(e.x,e.y),max(e.x,e.y));if(e.x>.0&&e.y<h.x)z=\'+a[9]+\'*e.x,m+=clamp(exp(-z*z*z*1.442695),.0,1.)*u\'+(d+2)+\'*vec3(u\'+(d+1)+\')*pow((e.y-e.x)/\'+w(j*2)+\',64.)*yy((u2+r*e.x)*3.);\':0,d+=3','c+=\'n+=m*yx;if(all(lessThan(xy,vec3(.01))))break;yx=xy,s=xxx,r=normalize(v);}h=vec2(zx.x,l.y)*.5+.5,h.y=(1.-h.y-u4[5])/u4[7],f=texture2D(u1,h),n=max(vec3(.0),mix(mix(mix(n,(n.x==n.y&&n.x==n.z)?n:vec3(dot(n,vec3(.299,.587,.114))),u4[1]),vec3(u4[3]),smoothstep(.05,.95,u4[2])),f.rgb*u3,f.a*u4[6])-vec3(.004)),x=(l.x+1.)*(l.y+1.)*(u4[0]*10.),gl_FragColor=vec4((1.-(smoothstep(.98,1.,yy(l*8.+u4[0]*20.))+smoothstep(.95,1.,yy(l*1.5+u4[0]*10.))))*smoothstep(1.042+.008*cos(u4[0]*40.),.8,yyx(zx,8.))*(1.-(mod((mod(x,13.)+1.)*(mod(x,47.)+1.),.01))*8.)*((.95+.05*cos(u4[0]*41.))*(n*(6.2*n+.5))/(n*(6.2*n+vec3(1.7))+vec3(.06))+vec3(smoothstep(.98,1.,yy(l*8.-u4[0]*40.)))),1.);}\';')(x=[[100,.025,1,.7,64,.0005,.5,.3,.4,.015,4,2,.75,[0,1,2,3],'y=x+.1*(sin(x.zxy*.17+u4[0]*.5)+sin(x.yzx*.7+u4[0]*1.5))*8.5*(1.+cos(sin(x.z*.1)+x.z*.3)),z=14.-length(y.xy),w=x.x==.0?1.570795*(x.y>.0?1.:-1.):atan(x.y,x.x),q=8.35-u4[8]*1.35,y=vec3(9.*(mod(w+x.z*.02,.628)-.314),length(x.xy)-9.,mod(x.z,12.56)-6.28),u=min(length(y.xy)-.25+.1*cos(x.z*8.+u4[0]*.1),length(y.yz)-.5),y=vec3(q*(mod(w+x.z*.02,1.256636)-.628318),y.y+9.-q,mod(x.z,62.8318)-31.4159),o=step(u,z)+1.,z=min(u,z),u=length(y)-1.3;if(u<z)z=u,o=3.;y.y+=q-9.,u=yyx(y.yz,8.)-2.;if(u<z)z=u,o=.0;return vec2(z,o);',[[.25,0],[.1,2.1]]],[6,.000125,1.08,.7,100,.000008,10,.03,2.1,.2,6,.4,5.1,[0,2,5],'z=1.,y=x;for(int i=0;i<7;i++)x=2.*clamp(x,-vec3(.58,.9,1.1),vec3(.58,.9,1.1))-x,w=max((1.3+u4[9]*.1*cos(u4[0]*.5))/dot(x,x),1.),x*=w,z*=w;w=length(x.xy),e=vec2(w-3.,-w*x.z/length(x)-2.*log(1.+.01*a))/abs(z),w=max(e.x,e.y),o=step(e.y,e.x),y+=vec3(.1,.3,-.4)*u0-u2+.25*sin(x*1.),e.x=length(y)-.1*u4[8];if(e.x<w)w=e.x,o=2.;return vec2(w,o);',[[.05]]],[100,.000025,1,.75,80,.0005,.5,.3,3,.01,4,.75,4.75,[6,0,4],'x.xy*=t(a*.009),w=min(min(yz(x.xzy),yz(x)),yz(x.yzx)),y=mod(x,vec3(15.))-vec3(7.5),o=step(z=max(length(max(abs(y)-vec3(2.5),vec3(.0)))-.25,3.5-length(y)),w),w=min(w,z),z=length(y+.1*sin(y*5.5+u4[0]))-2.;if(z<w)w=z,o=2.;return vec2(w,o);',[[.05]]],[20,.0005,1,.6,128,.0001,.5,.002,.01,.08,4,.5,1.75,[2,7],'y=x,y.xz=mod(x.xz,8.)-4.,y.yz*=t(u4[8]+.1*a),y.xy*=t(u4[8]*.5+.2*a),y.y*=.9+.1*sin(u4[8]*5.),w=max(length(y)-3.,-min(length(y)-2.8,max(mod(y.y,.8)-.4,-mod(y.y+.4,.8)+.4))),z=x.y+1.+sin(x.x*4.+u4[8]*2.)*sin(x.z+u4[8])*.1,o=clamp(.5+.5*(z-w)/1.,.0,1.),w=mix(z,w,o)-1.*o*(1.-o),y=x,y.xz=mod(y.xz,8.)-4.,y/=1.25+.25*sin(u4[8]*5.),y.xy*=t(u4[8]*5.),y.yz*=t(u4[8]*2.5),z=max(length(y)-1.,.04-length(max(abs(mod(y,.5)-.25)-vec3(.15),vec3(.0))));return vec2(min(w,z),step(z,w));',[[.02],[.05,1.5],[.05,1.5]]]][i])],zy[i]=[5+x[15].length*3,0,i+1]; + +with(zx){for(i in h)j=h[i],shS(i=h[i]=crS(j[0]),j[1]),coS(i),geSP(i,35713);for(i in zy){w=crP(),m=zy[i],x=m.shift();for(j in m)atS(w,h[m[j]]);liP(w),m=[];for(;x--;)m[x]=geUL(w,'u'+x);zy[i]=[w,m]}biB(i=34962,crB()),buD(i,e([1,4,1,-1,-4,-1]),35044),biT(i=3553,crT()),teP(i,j=10240,k=9728),teP(i,++j,k),teP(i,++j,k=33071),teP(i,++j,k),teID(i,0,j=6408,j,5121,C2)} + +w=f('a,b','','f(\'a\',\'yf(a[0],p),a[1]=\'+a+\',a[2]=\'+b)'),v=f('a','','f(\'\',\'x[4]=(\'+(a>0?a:\'\')+\'-xz*\'+a+\'/h[t][6])*R(.875,.125)\')'),q=f('a,b,c,d','c=v(c),d=f(\'a,b,c,d\',\'y(p,x[2]=x[8]=0,4,d=f*3),y(s,a,0,d+b),y(n,0,0,1),c()\')','function(){d(a,b,c)}'),u=f('a','','f(\'a\',\'y(a[0],\'+a+\'*C(\'+a+\'*f*2)*5,4.25,\'+a+\'*S(\'+a+\'*f*2.5)*5+D(44)*10),a[1]=1.5+S(f+\'+a+\'),a[2]=8+2*S(f+\'+a+\')\')'),r=f('a','a=v(a)','function(){r(),a()}'),o=f('a','_f(a[0],p,zw(a[0],s)),a[0][1]-=.5,a[1]=3,a[2]=30'),m=f('','v(\'Greetings to ... Mog, Sycop, Tim & Wullon ... Adinpsz ... Alcatraz ... ASD ... Bits\\\'n\\\'Bites ... Brain Control ... Cocoon ... Conspiracy ... Ctrl+Alt+Test ... Fairlight ... Farbrausch ... Kewlers ... LNX ... Loonies ... Mercury ... Popsy Team ... Razor 1911 ... RGBA ... 7th Cube ... Still ... TPOLM ... TRBL ... Umlaut Design ... X-Men ... Youth Uprising ... Everyone here at DemoJS 2014!\',yw*(1-D(35)/3)),x[5]=1-zf+R(.01,.01),y(fz,x[6]=1,1,1)'),g=f('a','','f(\'a,b\',\'b=D(\'+a+\'),y(a[0],4*S(b*.5)*C(b*.7),3*C(b*1.5),b*30*fx+14+16*S(b*3.3)*C(b*.77)),a[1]=3+3*(f%1),a[2]=16\')'), + +h = [ + [ 36 , 0 , f('','w(x[2]=1-z*z*z,_=5)') , a=[w(3,20)] ], + [ 18 , 0 , f('','w(x[2]=0,_=5-2.25*z)') , a ], + [ 36 , 0 , f('','w(x[2]=z,_=2.75-2.25*z)') , a ], + [ 18 , 3 , f('a','y(p,0,4,a=f*3),y(s,4,0,a),y(n,0,0,1),x[2]=1-z*z*z,_=2.5') , [ w(.75,8) ] ], + [ 22 , 3 , q(4,0,0) , a=[w(1,8)] ], + [ 22 , 3 , q(2,-2,0) , a ], + [ 3 , 3 , q( 6 , 0 , -.5 ) , b=[w(.5,4)] ], + [ 9 , 3 , q( 6 , 0 , .5 ) , b ], + [ 3 , 3 , q( 2 , 2 , -.2 ) , a ], + [ 9 , 3 , q( 2 , 2 , .2 ) , a ], + [ 3 , 3 , q( 2 , 5 , -.7 ) , a=[ w(1,2) ] ], + [ 7 , 3 , q( 2 , 5 , .7 ) , a ], + [ 9 , 3 , f('a','y(p,0,4+z*8,a=f*3),y(s,2,0,a+5),y(n,0,0,x[3]=1),x[2]=z') , a ], + [ 23 , 1 , f('','r(x[2]=1-z*z*z,x[3]=1)'), a=[f('a','yf(a[0],p),a[0][2]+=2,a[1]=1,a[2]=3')] ], + [ 3 , 1 , r(-.9) , a ], + [ 9 , 1 , r(.9) , a ], + [ 3 , 1 , r(-.3) , a ], + [ 9 , 1 , r(.3) , a ], + [ 3 , 1 , r(-.6) , a ], + [ 9 , 1 , r(.6) , a ], + [ 12 , 1 , f('','r(x[4]=(-(6*z)%1)*R(.875,.125))'), a ], + [ 22 , 1 , f('','r(x[4]=((30*z)%1)*R(.925,.075),x[2]=z,x[3]=.4),_=3-2.5*M(1,2*z)'), a ], + [ 3 , 1 , b=f('','r(x[4]=0,x[2]=1)'), a ], + [ 12 , 1 , b , a, f('','m(0,.08,1,1,1,1)') ], + [ 12 , 1 , b , a, f('','m(0,.08,1-z,1,1,1)') ], + [ 12 , 1 , b , a, f('','m(1,.08,1-z,1,1,1)') ], + [ 20 , 2 , f('','o(x[2]=1-z)') , b=[w(1,30)], f('','m(2,.04,z,1,1,1)') ], + [ 52 , 2 , f('','o(x[2]=0)'), b, f('','m(2,.04,1,1,1,1)') ], + [ 12 , 2 , f('','o(x[2]=1-M(0,z*2),x[3]=1)'), b, f('','m(2,.04,1,1-z,1-z/2,1-z)') ], + [ 12 , 2 , f('a','o(x[1]=1-z/2,x[4]=(1-z)*.7+R(a=.0125,a))') , b, f('','m(2,.04,1,0,.5,0)') ], + [ 9 , 2 , f('','g(30,x[1]=(1-z)/2,x[2]=1-M(0,z*1.5),x[4]+=x[1]*.6)'), b, f('','m(2,.04,1-z,0,.5,0)') ], + [ 69 , 2 , f('','g(30,x[1]=0)') , b ], + [ 11 , 2 , f('','g(30,x[2]=z,x[3]=.2)'), b ], + [ 11 , 0 , f('','e(33,x[2]=1-z)'), b=[ o ] ], + [ 17 , 0 , f('','e(33,x[2]=0,x[4]=(1-z)*1.2*R(1,.02))') , b ], + [ 18 , 0 , f('','e(33,x[4]=0,x[8]=z)') , b , m ], + [ 36 , 0 , f('','e(33,x[2]=1-N(x[8]=1,4*z))'), b = [ o , g(33) ], m ], + [ 33 , 0 , f('','e(33,x[2]=z,x[3]=.7,x[4]=-((4*z)%1)*R(1,.05))'), b , m ], + [ 9 , 1 , f('','u(x[4]=0,x[2]=1-z,x[3]=1)'), a, m ], + [ 20 , 1 , f('','u(z,x[2]=0)'), a, m ], + [ 31 , 1 , f('','u(1,x[2]=1-N(1,5*z))'), a, m ], + [ 5 , 1 , f('','u(1,x[2]=1-z)'), a, m ], + [ 18 , 1 , f('','u(1,x[2]=1-N(1,5*z),x[4]=M(0,1.6*z-.8)*R(1,.05))'), a, m ], + [ 12 , 1 , f('','u(1,x[2]=z,x[4]=(1-z)*.8*R(1,.05),x[3]=.1)'), a, m ], + [ 22 , 3 , f('','q(x[2]=1-z,x[4]=0)'), b = [ w(.6,30) , u(1),u(-1.5) ], m ], + [ 59 , 3 , f('','q(x[2]=1-N(1,(12*z)%4),x[3]=.8)'), b, m ], + [ 8 , 3 , f('','q(x[2]=z,x[4]=R(0,x[3]=.1))'), b ], + [ 7 , 0 , f('','x[fx=2]=1-z,e(46,x[4]=R(0,.1),x[8]=1)'), c = [ o , g(47) ] ], + [ 22 , 0 , f('','e(47,x[4]=R(0,.1))'), c ], + [ 10 , 0 , f('','e(47,x[4]=R(0,.1),x[2]=z,x[3]=1)'), c ], + [ 10 , 1 , f('','u(1,x[2]=1-z,x[4]=R(0,.1))'), a ] , + [ 4 , 1 , f('','u(1,x[2]=1-((z*4)%1),x[4]=R(0,.1))'), a ] , + [ 2 , 1 , f('','u(1,x[4]=R(x[2]=0,.1))'), a ] , + [ 36 , 1 , f('','u(1,x[2]=1-N(1,2*((z*3)%1)),x[4]=R(0,.1+.1*z)),_=3+2*z'), a ] , + [ 12 , 2 , f('','g(54,x[2]=1-((z*4)%1))'+(b=',x[4]=R(0,.2)+D(54)*2')), a=[ w(1,30) ] ], + [ 6 , 2 , f('','g(54,x[2]=1-((z*6)%1))'+b), a ], + [ 30 , 2 , f('','g(54,x[1]=N(1,z*2),x[2]=z,x[3]=0)'+b), a ], + [ 21 , 2 , f('','g(54,x[2]=1)'), a ] +]; + +fx=1,x=e(10),p=e(3),s=e(3),n=e(3),fz=e(3),ff=e(3),fy=e(3),yy=e(3),xf=e(9),xw=[[e(3),0,0],[e(3),0,0],[e(3),0,zz=0]],_=new Int32Array(xz=10717272),w=f('a','y(p,-6,0,a=f*6),y(s,x[1]=1,x[8]=0,a),y(n,0,1,0)'),q=f('a','a=D(44)*10,y(p,C(f)*12,9.5,S(f)*12+a),y(s,1,1,a),y(n,0,_=2.5,0),x[8]=D(44)'),r=f('','y(p,4,2.5+.025*f,6.7),y(s,x[8]=x[9]=0,2.5-.05*f,6.7),y(n,0,0,1),_=3'),u=f('a,b','b=fx*f,y(p,5*S(b*.2),9*C(b*.41),7.8),y(s,C(b*.2),S(b*.33),p[2]-2),y(n,0,0,x[9]=1),x[8]=a,_=3'),v=f('a,b,c','with(yx)shadowBlur=ww/5,fillText(a,b,c=ww/2),shadowBlur=0,strokeText(a,b,c)'),m=f('a,b,c,d,e,f','v([\'TheT(ourist)\',\'presents\',\'Sine City\'][a],yw/15),x[5]=1-zf+R(0,b),x[6]=c,y(fz,d,e,f)'),o=f('a,b','a=D(26),y(p,b=a*10-80,0,0),y(s,b+C(a*.5)*80,S(a*.25)*40,100),y(n,0,_=2.5,0)'),g=f('a,b','a=D(a)*fx,y(p,0,0,b=a*20-80),y(s,C(a*.5)*80,S(a*.25)*40,100+b),y(n,0,_=2,0),x[4]=R(a=.0125,a)'),e=f('a','a=D(a)*fx*30,y(p,1.1*C(a*.1),S(a*.02)-2,a),a+=5,y(s,-S(a*.05),-.7*C(a*.033)-2,a),y(n,0,_=2/fx,0)'),K=f('a,b','b=100/3,J(K),zz?0:(A.play(),zz=a,$=zz-b),yz=a-$,f=.001*(a-zz);if(yz>b){$=a-(yz%b),j=h[t];while(j&&j[7]<f)j=h[++t];if(j){x[0]=f,x[7]=zf,xz=f-j[5],z=xz/j[6];with(zx){j[4]?(yx.clearRect(0,0,yw,100),teID(3553,j[4](),k=6408,k,5121,C2)):0,j[2](),zw(yy,_f(yy,s,p)),zw(ff,fw(ff,n,yy)),zw(fy,fw(fy,yy,ff)),$f(yy,yy,_);for(i=0;i<3;i++)xf[i*3]=ff[i],xf[i*3+1]=fy[i],xf[i*3+2]=yy[i];for(i in j[3])j[3][i](xw[i]);f=zy[j[1]],usP(f[k=0]),f=f[1],veAP(enVAA(unM3fv(f[k++],un1i(f[k++],un3fv(f[k++],p)),xf)),2,5126,un3fv(f[k++],fz),8,un1fv(f[k++],x));for(i in j[3])un3fv(f[k++],xw[i][0]),un1f(f[k++],xw[i][1]),un1f(f[k++],xw[i][2]);drA(4,0,3)}}}'),L=f('','setTimeout(function(){(J=requestAnimationFrame)(K)},1500)'),D=f('a','','f-h[a][5]'); + +for(t=i=0;i<58;i++)h[i][5]=t,t+=(h[i][6]=h[i][0]/8),h[i][7]=t; + +t=0,yx=C2.getContext('2d'),(onresize=f('a,b,c,d,e','with(yx)a=innerWidth,b=innerHeight,c=(b*1.6)|0,d=(a*.625)|0,zx.vi(0,0,C2.style.width=C2.width=C1.width=yw=c>a?a:c,C1.height=e=c>a?d:b),ww=C2.style.height=C2.height=M(e/8,100),zf=ww/e,C1.style.left=((a-yw)/2)|0,C1.style.top=((b-e)/2)|0,shadowColor=\'#ccc\',font=\'normal small-caps bold \'+((ww/2)|0)+\'px monospace\',fillStyle=\'#111\',strokeStyle=\'#ddd\''))(), + +I=setInterval(f('a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,u,v,w','for(d=new Int32Array(xz),f=[[[0,198,128,0,3,192,128,1,0,0,96,128,28,0,0,0,0,2,63,61,13,16,44,8,0,0],[1,2,3,4,5,2,3,4,6,7,1,2,3,4,5,2,3,4,5,2,3,4,1,2,3,8,9],[[[b=115,,,,,,,,,,,,117,,,,,,,,,,,,113],[12,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,96]],[[b,,,,,,,,,,,,,,,110],[12,,,,,,,,,,,,,,,12,,,,,,,,,,,,,,,,,,,,,b,,,,,,,,,,,,,,,148]],[[b,,,,,,,,,,,,117,,,,,,,,,,,,118],[12,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,96]],[[122,,,,,,,,,,,,,,,123,,,,,b],[12,,,,,,,,,,,,,,,12,,,,,12,,,,,,,,,,,,,,,,b,,,,,,,,,,,,,,,8,,,,,128]],[[118,,,,,,,,,,,,117,,,,,,,,,,,,113],[12,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,96]],[[b],[12,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,255]],[[,,,,,,,,,,,,,,,,118,118,118],[,,,,,,,,,,,,,,,,12,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,128]],[[122,,,,,,,,,,,,,,,123,,,,,b],[12,,,,,,,,,,,,,,,12,,,,,13,12,,,,,,,,,,,,,,,b,,,,,,,,,,,,,,,8,,,,,95,61]],[[],[]]]],[[0,255,116,1,0,255,101,0,0,15,1,4,45,0,13,6,1,2,62,27,60,48,0,0,44,2],[,1,,2,,1,,2,,3,4,4,5,4,5,4,5,4,5,4,5,4,5,4,3,6],[[[,,,,,a=139,,,a,a,,,,,,a,,,,,,,,a,,,a,a,,,,,a,a,a],[]],[[,,a,a,,,,,a,a,,,,,a,a,,,,,,,,,,a,a,a,,,,,a,a,a],[]],[[,,,a,,,,,a,a,,,,,,a,,,,,a,a,,,,,,a,,,,a,a,a],[]],[[a,,,,a,,a,,,a,,,a,,,,a,,a,,,a,,,a,,,,a,,a,,,a],[]],[[a,,,a,a,,a,,,a,,,a,,,a,a,,a,,,a,,,a,,,a,a,,a,,,a],[]],[[a,,,a,a,,a,,,a,,,a,,,a,a,,a,,,a,a],[]]]],[[0,0,140,0,0,0,140,0,0,128,4,10,34,0,187,5,0,1,239,135,34,19,108,8,8,4],[,,1,,1,,3,,1,3,2,2,2,2,2,3,2,3,2,3,2,3,2,3,1],[[[,,,,,,,,,,127,,,,,,,,,,,,127,,,,,,,,,,,,127],[]],[[,,,a,,,,,,a,a,,,,,a,,,,,,a,a,,,,,a,,,,,a,,a],[]],[[,,127,,,,,,,,127,,,,127,,,,,,,,127,,,,127,,,,,,,,127],[]]]],[[1,192,128,0,3,201,128,0,0,93,5,6,58,3,195,6,1,3,35,63,14,17,11,10,61,6],[,,,,1,2,3,4,5,6,7,5,8,9,10,11,8,9,10,11,12,13,14,15,16],[[[,,,,,,,,147,146,145,,,,,,,,,,145,147,146,,,,,,,,,,149,148,147],[]],[[,,,,,,151,151,151,,,,,,,146,142,138,,,,,,,,,,,,,,,147,150,147],[]],[[,,146,,,146,,,,,,,,,147,146,145,,,,,,,,,,146,145,142,,,142,,,142],[]],[[,,141,,,,,,,,,,,,141,140,a,,,146,,,146,,,127],[]],[[,a,,151,,,,,,,,,,151,,a,,,,,,,,,,a,,151],[]],[[,a,,151,150,149,,,,,,,,a,,149,148,147,,,,,,,,a,,,146,,,145,,,144],[]],[[,a,,,a,142,,,142,144,146,,144,,,,146,147,,,147,146,141,,137,,,,142,141,,141,,137],[]],[[a,,127,,142,,,130,,,144,142,141,,129,,141,,,144,,,141,144,142,,,,149,,,146,,,151],[]],[[,149,,149,,146,144,142,,,141,,142,,,a,,,,151,147,,,,146,147,,144,146,,142,144,141,146],[]],[[,,,,,,,,147,146,145,,,,,141,144,147,146,,144,,137,,,144,146,142,144,,,142,144,141,146],[]],[[,146,,151,,146,,,,144,142,144,146,,,,142,,,,,a,,,,,151,146,a,144,a,142,141,142,151],[]],[[,,147,,,149,146,,,142,,142,141,,,144,,144,,,144,146,142,144,142,,,,151,150,149,,137,,149],[]],[[,151,,,147,151,,,146,151,,,,,144,151,,149,147,149,151,,146,,,144,143,142,,,a,,151,a],[]],[[,,134,,,134,,,134,,,146,144,,,141,144,,,146,147,146,,,144,,a,140,141,,,153,,,141],[]],[[,142,,151,,,142,143,144,,,,151,,,a,,,137,,149,,137,,,,125,,,141,142,141,,,146],[]],[[a,,127,a,,127,a,,127,a,127],[]]]],[[2,160,128,1,0,160,128,0,1,60,4,7,41,0,60,4,1,3,14,0,35,32,31,12,89,1],[,,,,,,,,,,,,1,2,1,2,1,2,1,2,1,2,1,2,1,3],[[[,,a,,,,,,,,,,,,a,,,,,,,,,,,,a,,,,,a,a,,,a],[]],[[,,a,,,151,,,a,,,151,,,a,,,151,,,a,,,151,,,a,,,151,,,146,146,146,146],[]],[[,,a,,,151,,,a,,,151,,,a,,a,a,a,a,127],[]]]],[[2,100,128,0,3,201,128,0,0,0,0,6,29,0,195,6,1,3,28,229,119,77,147,6,61,2],[,,,,,,,,,6,1,2,3,4,5,2,3,4,1,2,3,4,1,2,3,7],[[[b,b,b,b,b,b,b,b,b,b,b,b,117,117,117,117,117,117,117,117,117,117,117,117,113,113,113,113,113,113,113,113,113,113,113,113],[]],[[b,b,b,b,b,b,b,b,b,b,b,b,b,b,b,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110],[]],[[b,b,b,b,b,b,b,b,b,b,b,b,117,117,117,117,117,117,117,117,117,117,117,117,118,118,118,118,118,118,118,118,118,118,118,118],[]],[[110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,111,111,111,111,111,b,b,b,b,b,b,b,b,b,b,b,b,b,b,b,b],[]],[[118,118,118,118,118,118,118,118,118,118,118,118,117,117,117,117,117,117,117,117,117,117,117,117,113,113,113,113,113,113,113,113,113,113,113,113],[]],[[,,,,,,,,,,,,,,,,,,130,,130,,130,,130,,130,,130,118,130,118,130,118,130,118],[,,,,,,,,,,,,,,,,,,26,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2]],[[110,122,,122,134,,110,122,,122,134,,110,122,,111,123,,111,123,b,127,a,127,b],[,,,,,,,,,,,,,,,,,,,,26,25,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,8,147]]]],[[2,100,128,0,3,201,128,0,0,0,5,6,58,0,195,6,1,2,135,0,0,32,147,6,121,6],[],[]],[[2,100,128,0,3,201,128,0,0,0,5,6,58,0,195,6,1,2,135,0,0,32,147,6,121,6],[],[]]][t],o=[],g=h=m=p=0;p<=26;p++)for(b=f[1][p],a=0;a<36;a++){((e=b?f[2][b-1][1][a]:0)?((f[0][e-1]=f[2][b-1][1][a+36]||0),e<14?(o=[]):0):0),c=(p*36+a)*5513;for(j=0;j<4;j++)if(n=b?f[2][b-1][0][a+j*36]:0){if(!o[n])for(q=f[0][10],r=f[0][11],s=f[0][12],w=yz(n+f[0][2]-128),l=yz(n+f[0][6]-128)*(1+.0008*f[0][7]),u=v=0,q*=q*4,r*=r*4,s*=s*4,o[n]=new Int32Array(q+r+s),k=0;k<q+r+s;k++)e=k<q?(k/q):(1-(k<q+r?0:((k-q-r)/s))),o[n][k]=(80*($[f[0][0]](u+=w*(f[0][3]?(e*e):1))*f[0][1]+$[f[0][4]](v+=l*(f[0][8]?(e*e):1))*f[0][5]+R(0,1)*f[0][9])*e)|0;for(k=0,i=c*2;k<o[n].length;k++,i+=2)d[i]+=o[n][k]}q=f[0][20]*1e-5,r=f[0][24]/255,s=f[0][25]*5513;for(j=0;j<5513;j++)(((n=e=d[k=(c+j)*2])||m)?(w=1.5*S(f[0][18]*.00307999186353015873*(f[0][16]?($[f[0][13]](P(2,f[0][15]-9)*k/5513)*f[0][14]/512+.5):1)),g+=w*h,l=(1-f[0][19]/255)*(e-h)-g,h+=w*l,e=f[0][17]==3?h:f[0][17]==1?l:g,q?(e*=q,e=(e<1?e>-1?$[0](e*.25):-1:1)/q):0,e*=f[0][21]/32,m=e*e>1e-5,w=S(6.283184*P(2,f[0][23]-9)*k/5513)*f[0][22]/512+.5,n=e*(1-w),e*=w):0),(k>=s?(n+=d[k-s+1]*r,e+=d[k-s]*r):0),_[k]+=(d[k]=n|0),_[k+1]+=(d[k+1]=e|0)}if(++t==8)for(clearInterval(I),s=(f=String.fromCharCode).apply(String,[82,73,70,70,168,16,71,1,87,65,86,69,102,109,116,32,16,0,0,0,1,0,2,0,68,172,0,0,16,177,2,0,4,0,16,0,100,97,116,97,132,16,71,1]),t=i=0;i<xz||(((A=document.createElement(\'audio\')).src=\'data:audio/wav;base64,\'+btoa(s),A.oncanplaythrough=L)&&0);i++)e=_[i],e=e<-32767?-32767:(e>32767?32767:e),s+=f(e&255,(e>>8)&255)'),0);