diff --git a/README.md b/README.md index 7ffb802..6c68268 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,9 @@ -# +# Condition + +## `#define COMPROMISE 1` + +I'm so embarrassed that this project contains so many dumb strategies about size / performance optimization because deadline matters. +You totally shouldn't reference this project to do something by yourself. ## Build diff --git a/src/automaton.json b/src/automaton.json index e57b95a..ab6e5c9 100644 --- a/src/automaton.json +++ b/src/automaton.json @@ -1 +1 @@ -{"version":"4.1.1","resolution":400,"curves":[{"nodes":[[0,1,0,0,0.16140350877192983],[1,0,-0.47719298245614045]]},{"nodes":[[],[0.6666666666666666,1,-0.4560629631300563,-0.1852941176470587],[0.6666666666666666,0,0,0,0.26644908616188,0.1029411764705882],[2,1.1900000000000002,-0.1],[2,0.00686274509803933,0,0,0.10652741514360319],[2.6666666666666665,0.7000000000000001],[2.6666666666666665,0,0,0,0.1391644908616188,0.5215686274509802],[3.333333333333333,0.9,-0.5014360313315928,-0.22647058823529403],[3.333333333333333,0,0,0,0.3974946346535474,0.10043744264185422],[4.666666666666666,1.2000000000000002,0,0,0.1],[4.666666666666666],[5.333333333333333,0.7000000000000001,-0.24079400848586707,-0.49736814906842436],[5.333333333333333],[6,0.8,-0.4356422056174482,-0.17156862745098037],[6,0,0,0,0.32852235276081576,0.05490196078431372],[7.333333333333333,1.1441176470588237,-0.1,0,0.1],[7.333333333333333],[8,0.3333],[8,0,0,0,0.08806743643105143,0.4254901960784307],[8.666666666666666,0.9,-0.3995834676293276,-0.08230605476940031],[8.666666666666666],[9.4,1.1,-0.2785205844025618,-0.17156862745098012,0.2785205844025618,0.17156862745098012],[10,1.3],[10],[10.666666666666666,0.6000000000000001,-0.11225401796276425,-0.5783350570563074]],"fxs":[{"def":"repeat","params":{"interval":0.2299999999999996},"time":7.333333333333333,"length":0.6666666666666667}]},{"nodes":[[0,0,0,0,0.12284595300261082,0.061764705882352944],[0.6666666666666666,0.4,-0.1],[0.6666666666666666,0.06568627450980391],[2,0.2],[2.236344893790143,0.4,-0.1,0,0.1],[2.6666666666666665,0,-0.34575086532310695,0,0.04271204452939744],[2.769918291305192,0.1,-0.05130523784998782,0,0.09999999999999999],[3.333333333333333,0.1],[3.6666666666666665,0.32774323388394533],[4.666666666666666,0.30000000000000004],[4.666666666666666,0.023323265139934546],[5.333333333333333,0.1],[5.333333333333333],[6,0.30000000000000004],[6,0.02745098039215696,0,0,0.09974597868276715,-0.006845312262542842],[7.333333333333333,0.1,-0.1],[7.333333333333333,0.7000000000000001],[8.666666666666666,0.7000000000000001],[8.666666666666666,1],[10,0.1],[10.666666666666666]]},{"nodes":[[0,0,0,0,0.1],[0.3333333333333333,1,-0.1,0,0.1],[0.6666666666666666,0,-0.1],[1.9166666666666665,1,-1.0007832898172324,0,0.06],[2],[2.025071712633245,1,-0.044516971279373374,0,0.1],[2.1623944411350506,0.5,-0.07221383357420871,0.2738348538091391,0.07221383357420871,-0.2738348538091391],[2.6666666666666665,0,-0.1,0,0.1],[3,1,-0.2864316909347707,0,0.24406085208595923],[3.333333333333333,0,-0.036443741726782705,0.4106336078810942],[3.6666666666666665,0.7544057184393509,-0.08631141286229893,-0.07178801363349067,0.13346814639852406,0.11100980502520727],[4.666666666666666,1,-0.33942558746736295,-0.018347344929083464,0.09208797505724492,-0.3264027483296351],[4.851079899134173,0.30000000000000004,-0.07486057061026631,-0.013179150760383026,0.1],[5.0444017511428605,0.9656862745098039,-0.1,0,0.1],[5.333333333333333,0.044689231228471016,-0.1,0,0.1],[5.666666666666666,1,-0.1,0,0.1],[6,0,-0.1],[7.333333333333333,1,-1.0426547051383652,0,0.1],[7.6000000000000005,0.7000000000000001,-0.1,0,0.1],[8,1],[8,0,-0.1,0,0.1],[8.166666666666666,1,-0.099988538641853,-0.006965859231865531],[8.489362746562259,1,0,0,0.09998887794379856,-0.006861981819672439],[8.666666666666666,0,-0.11262160793957762,0.041182622607896624],[8.9,1,-0.11617352813418727,-0.020588235294117612,0.11617352813418727,0.020588235294117612],[9.04400609908224,0.15784313725490162,-0.0988340957186134,-0.027450980392156817,0.0988340957186134,0.027450980392156817],[9.3,1,-0.09200304954112025,-0.041176470588235224,0.09200304954112025,0.041176470588235224],[9.5,0.2,-0.09449923761471994,-0.06176470588235285,0.09449923761471994,0.06176470588235285],[9.666666666666666,1,-0.08899847522943988,-0.027450980392156817,0.08899847522943988,0.027450980392156817],[10,0.30000000000000004,-0.06149466330303955,-0.06176470588235285,0.06149466330303955,0.06176470588235285],[10,1,-0.1,0,0.1],[10.666666666666666,0.1,-0.1,0,0.1]],"fxs":[{"def":"repeat","params":{"interval":0.2490000000000001},"time":2,"length":0.6666666666666665},{"def":"sine","params":{"amp":0.26,"freq":8.590000000000002,"offset":0},"time":3.934411837854859,"length":0.7322548288118069},{"def":"sine","params":{"amp":0.4400000000000004,"freq":5.889999999999998,"offset":0},"time":10.234266741175261,"length":0.4323999254914046},{"def":"hermitePatch","params":{},"time":3.821100533282267,"length":0.12610951070520438,"row":1},{"def":"hermitePatch","params":{},"time":10.18270758125172,"length":0.09198590579094379,"row":1}]},{"nodes":[[0,0,0,0,0.1],[0.6666666666666666,1,-0.1],[0.6666666666666666,0.04000000000000001],[2,0.019999999999999997],[2,0.4],[2.6666666666666665],[3.333333333333333,0.2,-0.1],[3.333333333333333,0.5],[4.666666666666666,0.6000000000000001],[4.666666666666666,0.059594068084455554],[5.333333333333333],[6,0.1],[7.333333333333333,0,-1.3219093627620064,-0.061764705882352944],[8],[8,0.8],[10,0.8],[10,0.1],[10.666666666666666]]},{"nodes":[[0,0,0,0,0.11631853785900784,0.15784313725490196],[0.3333333333333333,0.2,-0.1,-0.06862745098039215],[0.3333333333333333,0,0,0,0.10652741514360313,0.034313725490196074],[0.6257615317667536,0.4,-0.035197899213743125,-0.1178437887562426,0.05762038784328031,0.19291505927163513],[1.5833333333333333,1.6588235294117648,-0.14423846823324632,-0.08235294117647059],[1.5833333333333333,0,0,0,0.0706266318537859,0.12352941176470589],[1.8333333333333333,0.6000000000000001,-0.07923141560987097,-0.16655319476142408,0.05223508415950609,0.10980392156862741],[2,0.8,-0.07118673688066018,-0.08235294117647059]]},{"nodes":[[0,0.7000000000000001,0,0,0.14895561357702347,-0.7343137254901958],[0.6666666666666666,0.01999999999999999,-0.07958650842810296,0.0005266470222471706,0.7602446192333546,-0.005030759268204068],[1.75,0.2,-0.175065274151436,-0.0480392156862745],[2,1,-0.1]]},{"nodes":[[0,0.264705882352941,0,0,0.2664490861618798,-0.3705882352941175],[1.75,0,-0.1,0,0.1],[2,1,-0.1]]},{"nodes":[[0,0,0,0,0.1],[0.3333333333333333,0.9460784313725474,-0.1,0,0.1],[1.3333333333333333,0.3627450980392144,-0.11276290315437737,0.31798356313506776,0.058202350589290165,-0.16412659044332573],[1.6666666666666665,1,-0.1,0,0.1],[1.7304177545691903,0.1,-0.1,0,0.1],[2,1.4000000000000001,-0.05099116999738633,-0.5930547707442783]],"fxs":[{"def":"sine","params":{"amp":0.3999999999999999,"freq":17.779999999999987,"offset":0},"time":0.6103133159268926,"length":0.7230200174064406},{"def":"hermitePatch","params":{},"time":0.5580939947780674,"length":0.08289817232376029,"row":1},{"def":"hermitePatch","params":{},"time":1.2836814621409922,"length":0.11631853785900792,"row":1}]},{"nodes":[[0,1,0,0,0.06843643544269563,-0.8715686274509801],[0.6666666666666666,0,-0.47719298245614045]]},{"nodes":[[],[2,2]]},{"nodes":[[0,0.1],[1.3333333333333333,0.30000000000000004]]},{"nodes":[[],[1.3333333333333333]]},{"nodes":[[0,0,0,0,0.07564543093234954,0.8647058823529409],[1.3333333333333333,1]]},{"nodes":[[],[0.3333333333333333,0.333],[0.3333333333333333,0,0,0,0.04050107306929012,0.096078431372549],[0.5833333333333333,0.30000000000000004,-0.10502788587794674,-0.054901960784313704],[1.3333333333333333]],"fxs":[{"def":"repeat","params":{"interval":0.2499999999999999},"time":0.3333333333333333,"length":1}]},{"nodes":[[0,0,0,0,0.041253263707571805],[0.1,0.472549019607836,-0.044516971279373374,-0.2333333333333331,0.037233176309202774,0.19515571003904697],[1.3333333333333333,1,-1.2945169712793734]]},{"nodes":[[0,0,0,0,0.1],[0.8,0.9,-0.10634811016391839,-0.09574850838471399,0.10634811016391839,0.09574850838471399],[1,1,-0.034837955875665044,-0.008249475331448328]]},{"nodes":[[0,1,0,0,0.08905168734696595,-0.6204705716763121],[0.8,0.1,-0.3657976094933656,0.05238364149449456,0.3657976094933656,-0.05238364149449456],[4,0,-0.5779474714155504]]},{"nodes":[[0,0,0,0,0.33333333333333337],[0.5833333333333333,0.13137254901960788,-0.06553651288762144,-0.14663596634864273,0.06553651288762144,0.14663596634864273],[0.6673629242819844,0.7480392156862745,-0.06736292428198434,-0.16470588235294117,0.06736292428198434,0.16470588235294117],[1.563751087902524,0.9519607843137257,-0.20443864229765013,-0.02745098039215686,0.20443864229765013,0.02745098039215686],[4,1,-0.5779474714155504]]},{"nodes":[[0,0,0,0,0.3154046997389034],[1.3333333333333333,1,-0.29908616187989556]]},{"nodes":[[],[1.3333333333333333,1]]},{"nodes":[[0,1,0,0,0.08905168734696595,-0.6204705716763121],[4,0,-3.146485330423383]]},{"nodes":[[0,1,0,0,0.15000000000000002],[0.25,1,-0.1,0,0.047780678851174936],[0.3333333333333333,0,-0.006527415143603133,0.3068670573880632,0.04083550913838122,0.1415436161688415],[0.4601827676240209,0,-0.031462140992167105,0.14076447719138005,0.031462140992167105,0.08154620354285587],[0.5515665796344648,0,-0.024934725848563967,0.05959145643516391,0.03472584856396867,0.040773101771427935],[0.6364229765013054,0,-0.024934725848563963,0.02509113955164797],[1,0,0,0,0.35333333333333333],[2.333333333333333,1,-0.3643603133159269,0,0.1]]},{"nodes":[[0,0,0,0,0.3317232375979112],[2,1,-1.3746781892076712]]},{"nodes":[[0,0,0,0,0.28276762402088773],[2.6666666666666665,1,-0.4673674842468357]]},{"nodes":[[0,0,0,0,0.429634464751958],[2.6666666666666665,0.99,-1.447911227154047]]},{"nodes":[[0,1,0,0,0.03472584856396867,-0.3705882352941176],[0.6666666666666666,0,-0.6417754569190601]]},{"nodes":[[0,0.4166666666666666,0,0,0.1],[0.6666666666666666,0,-0.664621409921671]]},{"nodes":[[0,0,0,0,0.1],[1.0065274151436032,0.9480392156862747,-0.791906005221932,-0.19215686274509805,0.17102946263472904,0.04150048712872081],[1.3333333333333333,1,-0.1]]},{"nodes":[[0,0,0,0,0.09780980358890974,0.020588235294117938],[0.3333333333333333,1,-0.04311987540653206,-0.9333333333333332]]},{"nodes":[[0,0.2],[1.3333333333333333,1.8,-1.0186386106576615,-0.609915244226372]]},{"nodes":[[0,0,0,0,0.011879895561357705,0.5490196078431372],[1.3333333333333333,1,-1.2292428198433418]]},{"nodes":[[0,0,0,0,0.1],[1,0,-0.1]]},{"nodes":[[0,0,0,0,0.9453002610966057],[4,1]]},{"nodes":[[0,0.9539215686274509,0,0,0.11305483028720623,-0.5970588235294118],[0.3333333333333333,0.1294117647058824,-0.07715404699738904,0.05490196078431372,0.07715404699738904,-0.05490196078431372],[1.3333333333333333,0,-1.133333333333333]]},{"nodes":[[0,0,0,0,3.415926892950391],[4,1]]},{"nodes":[[0,0.9539215686274509,0,0,0.15548302872062658,-0.6039215686274509],[1.3333333333333333,0,-0.6862053959965185]]}],"channels":[["EnvironmentMap/accumulate",{"items":[{},{"time":5.333333333333333,"length":1,"value":0.1,"curve":26,"amp":0.9},{"time":48,"length":1,"value":0.1,"curve":26,"amp":0.9},{"time":110.66666666666666,"length":1,"value":0.1,"curve":26,"amp":0.9},{"time":121.33333333333333,"length":1,"value":0.1,"curve":26,"amp":0.9},{"time":122.66666666666666,"length":1,"value":0.1,"curve":26,"amp":0.9}]}],["Glitch/amp",{"items":[{},{"time":48,"length":1,"curve":0},{"time":50.666666666666664,"length":1,"curve":0},{"time":53.333333333333336,"length":1,"curve":0},{"time":56,"length":1,"curve":0},{"time":58.666666666666664,"length":1,"curve":0},{"time":61.333333333333336,"length":1,"curve":0},{"time":64,"length":1,"curve":0},{"time":66.66666666666666,"length":1,"curve":0},{"time":69.33333333333333,"length":1,"curve":0},{"time":71.99999999999999,"length":1,"curve":0},{"time":74.66666666666666,"length":1,"curve":0},{"time":77.33333333333333,"length":1,"curve":0},{"time":79.99999999999999,"length":1,"curve":0},{"time":82.66666666666666,"length":1,"curve":0},{"time":85.33333333333333,"length":1,"curve":0},{"time":88,"length":1,"curve":0},{"time":149.33333333333331,"length":4,"curve":33,"amp":0.5000000000000002},{"time":153.33333333333331,"length":0.6666666666666856,"value":0.53,"reset":true},{"time":261.3333333333333}]}],["PixelSorter/amp",{"items":[{},{"time":48,"length":1.3333333333333357,"curve":9,"speed":0.4999999999999975},{"time":50.666666666666664,"length":1.3333333333333357,"curve":9,"speed":0.4999999999999975},{"time":53.333333333333336,"length":1.3333333333333357,"curve":9,"speed":0.4999999999999975},{"time":56,"length":1.3333333333333357,"curve":9,"speed":0.4999999999999975},{"time":58.666666666666664,"length":1.3333333333333357,"curve":9,"speed":0.4999999999999975},{"time":61.333333333333336,"length":1.3333333333333357,"curve":9,"speed":0.4999999999999975},{"time":64,"length":1.3333333333333357,"curve":9,"speed":0.4999999999999975},{"time":66.66666666666666,"length":1.3333333333333357,"curve":9,"speed":0.4999999999999975},{"time":69.33333333333333,"length":1.3333333333333357,"curve":9,"speed":0.4999999999999975},{"time":71.99999999999999,"length":1.3333333333333357,"curve":9,"speed":0.4999999999999975},{"time":74.66666666666666,"length":1.3333333333333357,"curve":9,"speed":0.4999999999999975},{"time":77.33333333333333,"length":1.3333333333333357,"curve":9,"speed":0.4999999999999975},{"time":79.99999999999999,"length":1.3333333333333357,"curve":9,"speed":0.4999999999999975},{"time":82.66666666666666,"length":1.3333333333333357,"curve":9,"speed":0.4999999999999975},{"time":85.33333333333333,"length":1.3333333333333357,"curve":9,"speed":0.4999999999999975},{"time":87.99999999999999,"length":1.3333333333333357,"curve":9,"speed":0.4999999999999975},{"time":90.33333333333333,"length":0.3333333333333286,"curve":29,"speed":1.0000000000000153,"amp":-0.4},{"time":90.66666666666666},{"time":91.99999999999999,"length":1.3333333333333428,"value":0.2,"reset":true},{"time":94.66666666666666,"length":1.3333333333333428,"value":0.2,"reset":true},{"time":97.33333333333333,"length":1.3333333333333428,"value":0.2,"reset":true},{"time":99.99999999999999,"length":1.3333333333333428,"value":0.2,"reset":true},{"time":102.66666666666666,"length":1.3333333333333428,"value":0.2,"reset":true},{"time":105.33333333333333,"length":1.3333333333333428,"value":0.2,"reset":true},{"time":107.99999999999999,"length":1.3333333333333428,"value":0.2,"reset":true},{"time":110.66666666666666,"length":1.3333333333333428,"value":0.2,"reset":true},{"time":153.33333333333331,"length":0.6666666666666856,"value":0.53,"reset":true}]}],["Serial/enable",{"items":[{},{"time":91.99999999999999,"length":1.3333333333333428},{"time":94.66666666666666,"length":1.3333333333333428},{"time":97.33333333333333,"length":1.3333333333333428},{"time":99.99999999999999,"length":1.3333333333333428},{"time":102.66666666666666,"length":1.3333333333333428},{"time":105.33333333333333,"length":1.3333333333333428},{"time":107.99999999999999,"length":1.3333333333333428},{"time":110.66666666666666,"length":1.3333333333333428},{"time":153.33333333333331,"length":1.3333333333333428}]}],["SceneBegin/active",{"items":[{},{"time":5.333333333333333,"length":42.666666666666664}]}],["Sync/first/clap",{"items":[{},{"time":27.666666666666664,"length":1.3333333333333321,"curve":15},{"time":28.999999999999996,"length":1.3333333333333321,"value":1,"curve":15},{"time":30.33333333333333,"length":1.3333333333333321,"value":2,"curve":15},{"time":31.66666666666666,"length":1.3333333333333321,"value":3,"curve":15},{"time":32.99999999999999,"length":1.3333333333333321,"value":4,"curve":15},{"time":34.33333333333333,"length":1.3333333333333321,"value":5,"curve":15},{"time":35.66666666666666,"length":1.3333333333333321,"value":6,"curve":15},{"time":36.99999999999999,"length":1.3333333333333321,"value":7,"curve":15},{"time":38.33333333333332,"length":1.3333333333333321,"value":8,"curve":15},{"time":39.66666666666665,"length":1.3333333333333321,"value":9,"curve":15},{"time":40.99999999999998,"length":1.3333333333333321,"value":10,"curve":15},{"time":42.33333333333331,"length":1.3333333333333321,"value":11,"curve":15}]}],["Condition/hahaRatio",{"items":[{},{"time":42.666666666666664,"length":4,"curve":25}]}],["Condition/phaseWidth",{"items":[{"value":0.1},{"time":27.666666666666664,"length":20.333333333333332,"value":0.1,"curve":16,"speed":0.049180327868852465,"amp":0.5888750576601328}]}],["SceneNeuro/active",{"items":[{},{"time":48,"length":42.666666666666664}]}],["sufferText/push",{"items":[{"time":48},{"time":50.666666666666664,"value":1},{"time":53.333333333333336,"value":2},{"time":56,"value":3},{"time":58.666666666666664,"value":4},{"time":61.333333333333336,"value":5},{"time":64,"value":6},{"time":66.66666666666666,"value":7},{"time":69.33333333333333,"value":8},{"time":71.99999999999999,"value":9},{"time":74.66666666666666,"value":10},{"time":77.33333333333333,"value":11},{"time":79.99999999999999,"value":12},{"time":82.66666666666666,"value":13},{"time":85.33333333333333,"value":14},{"time":87.99999999999999,"value":15}]}],["IFSPistons/group0/rot",{"items":[{},{"time":48.666666666666664,"length":2,"curve":23},{"time":54,"length":2,"value":1,"curve":23},{"time":59.333333333333336,"length":2,"value":2,"curve":23},{"time":64.66666666666666,"length":2,"value":3,"curve":23},{"time":69.99999999999999,"length":2,"value":4,"curve":23},{"time":75.33333333333333,"length":2,"value":5,"curve":23},{"time":80.66666666666666,"length":2,"value":6,"curve":23},{"time":85.99999999999999,"length":2,"value":7,"curve":23}]}],["IFSPistons/group1/rot",{"items":[{},{"time":51.333333333333336,"length":2,"curve":23},{"time":56.666666666666664,"length":2,"value":1,"curve":23},{"time":62,"length":2,"value":2,"curve":23},{"time":67.33333333333333,"length":2,"value":3,"curve":23},{"time":72.66666666666666,"length":2,"value":4,"curve":23},{"time":77.99999999999999,"length":2,"value":5,"curve":23},{"time":83.33333333333333,"length":2,"value":6,"curve":23},{"time":88.66666666666666,"length":2,"value":7,"curve":23}]}],["IFSPistons/group0/pos",{"items":[{"value":3},{"time":47.666666666666664,"length":2.3333333333333357,"value":1.2000000000000002,"curve":22,"amp":1.7999999999999998},{"time":53,"length":2.3333333333333357,"value":1.2000000000000002,"curve":22,"amp":1.7999999999999998},{"time":58.333333333333336,"length":2.3333333333333357,"value":1.2000000000000002,"curve":22,"amp":1.7999999999999998},{"time":63.666666666666664,"length":2.3333333333333357,"value":1.2000000000000002,"curve":22,"amp":1.7999999999999998},{"time":69.03333333333333,"length":2.3333333333333357,"value":1.2000000000000002,"curve":22,"amp":1.7999999999999998},{"time":74.33333333333333,"length":2.3333333333333357,"value":1.2000000000000002,"curve":22,"amp":1.7999999999999998},{"time":79.66666666666666,"length":2.3333333333333357,"value":1.2000000000000002,"curve":22,"amp":1.7999999999999998},{"time":84.99999999999999,"length":2.3333333333333357,"value":1.2000000000000002,"curve":22,"amp":1.7999999999999998}]}],["IFSPistons/group1/pos",{"items":[{"value":3},{"time":50.333333333333336,"length":2.3333333333333357,"value":1.2000000000000002,"curve":22,"amp":1.7999999999999998},{"time":55.666666666666664,"length":2.3333333333333357,"value":1.2000000000000002,"curve":22,"amp":1.7999999999999998},{"time":61,"length":2.3333333333333357,"value":1.2000000000000002,"curve":22,"amp":1.7999999999999998},{"time":66.33333333333333,"length":2.3333333333333357,"value":1.2000000000000002,"curve":22,"amp":1.7999999999999998},{"time":71.66666666666666,"length":2.3333333333333357,"value":1.2000000000000002,"curve":22,"amp":1.7999999999999998},{"time":76.99999999999999,"length":2.3333333333333357,"value":1.2000000000000002,"curve":22,"amp":1.7999999999999998},{"time":82.33333333333333,"length":2.3333333333333357,"value":1.2000000000000002,"curve":22,"amp":1.7999999999999998},{"time":87.66666666666666,"length":2.3333333333333357,"value":1.2000000000000002,"curve":22,"amp":1.7999999999999998}]}],["Music/NEURO_TIME",{"items":[{},{"time":48,"length":10.666666666666664,"curve":1},{"time":58.666666666666664,"length":8.666666666666671,"curve":1},{"time":67.33333333333333,"length":1.999999999999993,"curve":5},{"time":69.33333333333333,"length":10.666666666666664,"curve":1},{"time":79.99999999999999,"length":8.666666666666671,"curve":1},{"time":88.66666666666666,"length":0.6666666666666714,"curve":5},{"time":89.33333333333333,"length":1.3333333333333286,"curve":30},{"time":90.66666666666666,"length":1.3333333333333286,"curve":10,"offset":1.4210854715202004e-14},{"time":91.99999999999999,"length":1.3333333333333286,"curve":14},{"time":93.33333333333331,"length":1.3333333333333428,"curve":10},{"time":95.99999999999999,"length":1.3333333333333428,"curve":10},{"time":97.33333333333333,"length":1.3333333333333286,"curve":14},{"time":98.66666666666666,"length":1.3333333333333428,"curve":10},{"time":101.33333333333333,"length":1.3333333333333428,"curve":10},{"time":102.66666666666667,"length":1.3333333333333144,"curve":14},{"time":103.99999999999999,"length":1.3333333333333428,"curve":10},{"time":106.66666666666666,"length":1.3333333333333428,"curve":10},{"time":108,"length":1.3333333333333286,"curve":14},{"time":109.33333333333333,"length":1.3333333333333428,"curve":10}]}],["Music/NEURO_DETUNE",{"items":[{},{"time":48,"length":10.666666666666664,"curve":2},{"time":58.666666666666664,"length":8.666666666666671,"curve":2},{"time":67.33333333333333,"length":1.999999999999993,"curve":6},{"time":69.33333333333333,"length":10.666666666666664,"curve":2},{"time":79.99999999999999,"length":8.666666666666671,"curve":2},{"time":88.66666666666666,"length":2,"curve":6,"speed":0.8333333333333358},{"time":90.66666666666666,"length":1.3333333333333286,"curve":11},{"time":93.33333333333333,"length":1.3333333333333286,"curve":11},{"time":95.99999999999999,"length":1.3333333333333286,"curve":11},{"time":97.33333333333331,"length":1.3333333333333428,"value":0.77},{"time":98.66666666666666,"length":1.3333333333333286,"curve":11},{"time":101.33333333333333,"length":1.3333333333333286,"curve":11},{"time":103.99999999999999,"length":1.3333333333333286,"curve":11},{"time":106.66666666666666,"length":1.3333333333333286,"curve":11},{"time":107.99999999999999,"length":1.3333333333333428,"value":0.77},{"time":109.33333333333333,"length":1.3333333333333286,"curve":11}]}],["Music/NEURO_DETUNE_PHASE",{"items":[{},{"time":48,"length":10.666666666666664,"curve":4},{"time":58.666666666666664,"length":8.666666666666671,"curve":4},{"time":67.33333333333333,"length":1.999999999999993,"curve":7},{"time":69.33333333333333,"length":10.666666666666664,"curve":4},{"time":79.99999999999999,"length":8.666666666666671,"curve":4},{"time":88.66666666666666,"length":2,"curve":7,"speed":0.8333333333333358},{"time":90.66666666666666,"length":1.3333333333333428,"curve":12},{"time":93.33333333333333,"length":1.3333333333333428,"curve":12},{"time":95.99999999999999,"length":1.3333333333333428,"curve":12},{"time":98.66666666666666,"length":1.3333333333333428,"curve":12},{"time":101.33333333333333,"length":1.3333333333333428,"curve":12},{"time":103.99999999999999,"length":1.3333333333333428,"curve":12},{"time":106.66666666666666,"length":1.3333333333333428,"curve":12},{"time":109.33333333333333,"length":1.3333333333333428,"curve":12}]}],["Music/NEURO_WUB_AMP",{"items":[{},{"time":48,"length":10.668578038364203,"curve":3},{"time":58.6685780383642,"length":8.664755294969133,"curve":3},{"time":67.33333333333333,"length":2.0038227433950624,"curve":8},{"time":69.33715607672839,"length":10.668578038364203,"curve":3},{"time":80.0057341150926,"length":8.660932551574064,"curve":3},{"time":88.66666666666666,"length":2,"curve":8,"speed":0.8028871529270708},{"time":90.66666666666666,"length":1.3333333333333333,"curve":13},{"time":93.33333333333333,"length":1.3333333333333333,"curve":13},{"time":95.99999999999999,"length":1.3333333333333333,"curve":13},{"time":98.66666666666666,"length":1.3333333333333333,"curve":13},{"time":101.33333333333333,"length":1.3333333333333333,"curve":13},{"time":103.99999999999999,"length":1.3333333333333333,"curve":13},{"time":106.66666666666666,"length":1.3333333333333333,"curve":13},{"time":109.33333333333333,"length":1.3333333333333333,"curve":13}]}],["Music/NEURO_WUB_FREQ",{"items":[{},{"time":48,"length":2,"value":1},{"time":50,"length":0.6666666666666643,"value":0.49999999999999967},{"time":50.666666666666664,"length":0.6666666666666714,"value":1},{"time":51.333333333333336,"length":1.3333333333333286,"value":2},{"time":52.666666666666664,"length":0.6666666666666714,"value":2.5},{"time":53.333333333333336,"length":0.6666666666666643,"value":1},{"time":54,"length":1.3333333333333357,"value":1},{"time":55.333333333333336,"length":0.6666666666666643,"value":2},{"time":56,"length":2,"value":1},{"time":58,"length":0.6666666666666643,"value":2},{"time":58.666666666666664,"length":0.6666666666666714,"value":1},{"time":59.333333333333336,"length":1.3333333333333286,"value":2.1000000000000014},{"time":60.666666666666664,"length":0.6666666666666714,"value":0.5},{"time":61.333333333333336,"length":0.6666666666666643,"value":7},{"time":62,"length":1.3333333333333357,"value":3},{"time":63.333333333333336,"length":0.6666666666666714,"value":1},{"time":64,"length":0.6666666666666714,"value":0.9600000000000006},{"time":64.66666666666667,"length":1.3333333333333215,"value":6},{"time":66,"length":0.6666666666666785,"value":10.840000000000003},{"time":66.66666666666667,"length":0.6666666666666572,"value":1},{"time":67.33333333333333,"length":1.3333333333333428,"value":3.989999999999996},{"time":68.66666666666667,"length":0.6666666666666572,"value":4.109999999999999},{"time":69.33333333333333,"length":2,"value":1},{"time":71.33333333333333,"length":0.6666666666666643,"value":0.49999999999999967},{"time":71.99999999999999,"length":0.6666666666666714,"value":1},{"time":72.66666666666666,"length":1.3333333333333286,"value":2},{"time":73.99999999999999,"length":0.6666666666666714,"value":2.5},{"time":74.66666666666666,"length":0.6666666666666643,"value":1},{"time":75.33333333333333,"length":1.3333333333333357,"value":1},{"time":76.66666666666667,"length":0.6666666666666643,"value":2},{"time":77.33333333333333,"length":2,"value":1},{"time":79.33333333333333,"length":0.6666666666666643,"value":2},{"time":79.99999999999999,"length":0.6666666666666714,"value":1},{"time":80.66666666666666,"length":1.3333333333333286,"value":2.1000000000000014},{"time":81.99999999999999,"length":0.6666666666666714,"value":0.5},{"time":82.66666666666666,"length":0.6666666666666643,"value":7},{"time":83.33333333333333,"length":1.3333333333333357,"value":3},{"time":84.66666666666667,"length":0.6666666666666714,"value":1},{"time":85.33333333333334,"length":0.6666666666666714,"value":0.9600000000000006},{"time":86.00000000000001,"length":1.3333333333333144,"value":6},{"time":87.33333333333333,"length":0.6666666666666856,"value":10.840000000000003},{"time":88.00000000000001,"length":0.6666666666666572,"value":1},{"time":88.66666666666667,"length":1.3333333333333428,"value":3.9899999999999993},{"time":90.00000000000001,"length":0.6666666666666572,"value":4.109999999999999},{"time":90.66666666666667,"length":1.3333333333333144,"value":1},{"time":93.33333333333333,"length":1.3333333333333144,"value":1},{"time":95.99999999999999,"length":1.3333333333333144,"value":1},{"time":98.66666666666666,"length":1.3333333333333144,"value":1},{"time":101.33333333333333,"length":1.3333333333333144,"value":1},{"time":103.99999999999999,"length":1.3333333333333144,"value":1},{"time":106.66666666666666,"length":1.3333333333333144,"value":1},{"time":109.33333333333333,"length":1.3333333333333144,"value":1}]}],["Trails/active",{"items":[{}]}],["SceneCrystals/active",{"items":[{},{"time":111.33333333333333,"length":42.66666666666667}]}],["FlickyParticles/active",{"items":[{},{"time":48,"length":42.666666666666664},{"time":90.66666666666666,"length":1.3333333333333286},{"time":93.33333333333333,"length":1.3333333333333286},{"time":95.99999999999999,"length":1.3333333333333286},{"time":98.66666666666666,"length":1.3333333333333286},{"time":101.33333333333333,"length":1.3333333333333286},{"time":103.99999999999999,"length":1.3333333333333286},{"time":106.66666666666666,"length":1.3333333333333286},{"time":109.33333333333333,"length":1.3333333333333286},{"time":111.33333333333333,"length":42.66666666666667}]}],["SphereParticles/active",{"items":[{},{"time":90.66666666666666,"length":1.3333333333333286},{"time":93.33333333333333,"length":1.3333333333333286},{"time":95.99999999999999,"length":1.3333333333333286},{"time":98.66666666666666,"length":1.3333333333333286},{"time":101.33333333333333,"length":1.3333333333333286},{"time":103.99999999999999,"length":1.3333333333333286},{"time":106.66666666666666,"length":1.3333333333333286},{"time":109.33333333333333,"length":1.3333333333333286},{"time":111.33333333333333,"length":41.999999999999986}]}],["SceneCrystals/ChaosTorus/active",{"items":[{"time":-8.200000000000001},{"time":121.33333333333333,"length":1.3333333333333286}]}],["FlashyTerrain/active",{"items":[{},{"time":91.99999999999999,"length":1.3333333333333428},{"time":102.66666666666666,"length":1.3333333333333428}]}],["Camera/pos/x",{"items":[{},{"time":48,"value":0.029999999999999923},{"time":50.666666666666664,"value":0.22},{"time":53.333333333333336,"value":-0.3300000000000002},{"time":58.666666666666664,"value":0.030000000000000478},{"time":61.333333333333336,"value":0.4300000000000005},{"time":64,"value":-0.3099999999999998},{"time":66.66666666666666,"value":0.04000000000000473},{"time":69.33333333333333,"value":0.2500000000000004},{"time":71.99999999999999,"value":0.22},{"time":74.66666666666666,"value":0.18999999999999975},{"time":77.33333333333333,"value":-0.33000000000000024},{"time":79.99999999999999,"value":0.030000000000000478},{"time":82.66666666666666,"value":-0.32999999999999946},{"time":85.33333333333333,"value":6.349087922075114e-16},{"time":88},{"time":90.66666666666666},{"time":117.33333333333333,"value":0.2599999999999958},{"time":122.66666666666666,"value":-0.25000000000000006},{"time":128}]}],["Camera/pos/y",{"items":[{},{"time":48},{"time":53.333333333333336,"value":0.18999999999999986},{"time":58.666666666666664},{"time":69.33333333333333},{"time":74.66666666666666,"value":-0.2599999999999998},{"time":79.99999999999999},{"time":87.99999999999999},{"time":90.66666666666666},{"time":102.66666666666666,"value":0.8799999999999999},{"time":104},{"time":117.33333333333333,"value":0.009999999999995882},{"time":122.66666666666666},{"time":128},{"time":149.33333333333331,"value":1.3599999999999999}]}],["Camera/pos/z",{"items":[{},{"time":48},{"time":64,"value":-0.12999999999999998},{"time":66.66666666666666,"value":0.04000000000000473},{"time":69.33333333333333},{"time":85.33333333333333,"value":-0.019999999999999588},{"time":87.99999999999999},{"time":90.66666666666666}]}],["Camera/rot/r",{"items":[{},{"time":5.333333333333333,"length":4,"value":5,"curve":17,"amp":10},{"time":26.033333333333335,"length":4,"value":5,"curve":18,"amp":-2},{"time":42,"length":4,"value":3,"curve":18,"amp":4},{"time":48,"value":3.316984746376379},{"time":50.666666666666664,"value":4.160000000000001},{"time":53.33333333333333,"value":2.9236224967058},{"time":56,"value":4.760000000000006},{"time":58.666666666666664,"value":3.490000000000002},{"time":61.333333333333336,"value":3.289999999999999},{"time":64,"value":2.519999999999998},{"time":66.66666666666666,"value":5.050000000000004},{"time":69.33333333333333,"value":4.170000000000001},{"time":71.99999999999999,"value":4.399999999999997},{"time":74.66666666666666,"value":2.699999999999999},{"time":77.33333333333333,"value":5.470000000000008},{"time":79.99999999999999,"value":3.4499999999999997},{"time":82.66666666666666,"value":4.43},{"time":85.33333333333333,"value":2.9000000000000017},{"time":88,"value":6.6},{"time":89.33333333333331,"length":1.3333333333333428,"value":6.6,"curve":28,"speed":0.4999999999999974,"amp":4.4999999999999964},{"time":90.66666666666666,"length":1.3333333333333286,"value":5,"curve":17,"speed":3.000000000000011,"amp":5},{"time":93.33333333333333,"length":1.3333333333333286,"value":5,"curve":17,"speed":3.000000000000011,"amp":5},{"time":96,"length":1.3333333333333286,"value":5,"curve":17,"speed":3.000000000000011,"amp":5},{"time":98.66666666666667,"length":1.3333333333333144,"value":5,"curve":17,"speed":3.000000000000011,"amp":5},{"time":101.33333333333334,"length":1.3333333333333144,"value":5,"curve":17,"speed":3.000000000000011,"amp":5},{"time":104.00000000000001,"length":1.3333333333333144,"value":5,"curve":17,"speed":3.000000000000011,"amp":5},{"time":106.66666666666669,"length":1.3333333333333002,"value":5,"curve":17,"speed":3.000000000000011,"amp":5},{"time":109.33333333333336,"length":1.3333333333333002,"value":5,"curve":17,"speed":3.000000000000011,"amp":5},{"time":111.33333333333333,"length":4,"value":5.589999999999992,"curve":18,"speed":1.0000000000000002,"amp":-2},{"time":117.33333333333333,"value":2.939999999999995},{"time":121.33333333333333,"length":1.3333333333333286,"value":6.110000000000004,"curve":31,"amp":-0.99},{"time":122.66666666666666,"length":5.333333333333329,"value":3.4599999999999933,"curve":24,"speed":0.5000000000000013,"amp":-1.2000000000000026},{"time":127.99999999999999,"length":2.6666666666666714,"value":4.969999999999989,"curve":24,"speed":0.9999999999999999,"amp":-1.2000000000000026},{"time":133.33333333333331,"value":2.6600000000000015},{"time":144,"value":2.05},{"time":149.33333333333331,"value":1.8299999999999976},{"time":152,"length":2,"value":1.8299999999999996,"curve":18,"speed":0.5,"amp":1.7899999999999974}]}],["Camera/rot/t",{"items":[{},{"time":26.666666666666664,"length":5.333333333333332,"curve":19,"speed":0.2499999999999999,"amp":0.30000000000000004},{"time":31.999999999999996,"length":5.333333333333332,"value":1.2000000000000002,"curve":19,"speed":0.2499999999999999,"amp":-0.9},{"time":37.333333333333336,"length":5.333333333333329,"value":-0.3,"curve":19,"speed":0.2499999999999999,"amp":0.30000000000000004},{"time":48,"value":0.12000000000000001},{"time":50.666666666666664,"value":-0.30999999999999495},{"time":53.333333333333336,"value":0.5200000000000048},{"time":56,"value":-0.029999999999995274},{"time":58.666666666666664,"value":0.2600000000000046},{"time":61.333333333333336,"value":-0.2899999999999953},{"time":64,"value":-0.06999999999999539},{"time":66.66666666666666,"value":0.2600000000000049},{"time":69.33333333333333,"value":0.12000000000000001},{"time":71.99999999999999,"value":0.7500000000000049},{"time":74.66666666666666,"value":-0.3599999999999952},{"time":77.33333333333333,"value":-1.1999999999999946},{"time":79.99999999999999,"value":0.2600000000000046},{"time":82.65764496093742,"value":-0.2899999999999953},{"time":85.33333333333333,"value":0.39000000000000457},{"time":87.99999999999999,"value":-0.029999999999995274},{"time":90.66666666666666},{"time":91.99999999999999,"value":0.5700000000000002},{"time":93.33333333333333},{"time":95.99999999999999},{"time":98.66666666666666},{"time":101.33333333333333},{"time":102.66666666666666,"value":-0.32},{"time":103.99999999999999},{"time":106.66666666666666},{"time":109.33333333333333},{"time":111.33333333333333,"value":0.14999999999999633},{"time":117.33333333333333,"value":0.5699999999999952},{"time":121.33333333333331,"length":1.3333333333333428,"value":0.37000000000000166,"curve":24,"speed":1.9999999999999891,"amp":-0.08000000000000007},{"time":122.66666666666666,"value":0.09999999999999977},{"time":128,"value":0.2},{"time":133.33333333333331,"value":0.4699999999999978},{"time":144,"value":-0.3700000000000031},{"time":149.33333333333331,"value":0.18000000000000063},{"time":151.86425044104683,"length":2.066666666666663,"value":0.18,"curve":18,"speed":0.5,"amp":-1.160000000000004}]}],["Camera/rot/p",{"items":[{},{"time":26.666666666666664,"length":5.333333333333332,"curve":19,"speed":0.2499999999999999,"amp":0.30000000000000004},{"time":32,"value":-2.3500000000000125},{"time":37.333333333333336,"length":5.333333333333329,"value":-0.3,"curve":19,"speed":0.2499999999999999,"amp":0.30000000000000004},{"time":48,"length":2.6666666666666643,"curve":24},{"time":50.666666666666664,"length":2.6666666666666714,"value":-0.9690196078431373,"curve":24},{"time":53.333333333333336,"length":2.6666666666666714,"value":-0.33999999999999997,"curve":24},{"time":56.00000000000001,"length":2.6666666666666714,"value":-0.39117647058823524,"curve":24},{"time":58.66666666666668,"length":2.6666666666666714,"value":-0.12117647058823516,"curve":24},{"time":61.33333333333335,"length":2.6666666666666714,"value":-1.4311764705882353,"curve":24},{"time":64.00000000000003,"length":2.6666666666666714,"value":-0.29117647058823515,"curve":24},{"time":66.66666666666669,"length":2.6666666666666714,"value":-0.7811764705882349,"curve":24},{"time":69.33333333333336,"length":2.6666666666666643,"curve":24},{"time":72.00000000000001,"length":2.6666666666666714,"value":-0.9690196078431373,"curve":24},{"time":74.66666666666669,"length":2.6666666666666714,"value":-0.51,"curve":24},{"time":77.33333333333336,"length":2.6666666666666714,"value":-0.5111764705882352,"curve":24},{"time":80.00000000000003,"length":2.6666666666666714,"value":-0.6411764705882351,"curve":24},{"time":82.6666666666667,"length":2.6666666666666714,"value":-1.3611764705882354,"curve":24},{"time":85.33333333333337,"length":2.6666666666666714,"value":-0.4911764705882345,"curve":24},{"time":88.00000000000004,"length":1.3333333333333286,"value":-1.5411764705882351,"curve":24},{"time":89.33333333333337,"length":1.333333333333286,"value":-1.016,"curve":28,"speed":0.5000000000000079,"amp":3},{"time":90.66666666666666},{"time":91.99999999999999,"length":1.3333333333333428,"curve":20,"amp":6},{"time":93.33333333333333},{"time":95.99999999999999},{"time":98.66666666666666},{"time":101.33333333333333},{"time":102.66666666666666,"length":1.3333333333333428,"curve":20,"amp":6},{"time":104},{"time":106.66666666666666},{"time":109.33333333333333},{"time":111.33333333333333,"value":0.56},{"time":112,"length":5.333333333333329,"value":0.56,"curve":24,"speed":0.5000000000000013,"amp":-1.0400000000000003},{"time":117.33333333333333,"length":3.999999999999986,"value":0.6199999999999997,"curve":24,"speed":0.5000000000000012,"amp":-1.0400000000000003},{"time":121.33333333333331,"length":1.3333333333333428,"value":-0.3799999999999981,"curve":24,"speed":1.9999999999999891,"amp":0.56},{"time":122.66666666666666,"length":5.333333333333329,"value":0.37000000000000166,"curve":24,"speed":0.5000000000000013,"amp":-0.7100000000000002},{"time":127.99999999999999,"length":2.6666666666666714,"value":-0.71,"curve":24,"speed":0.9999999999999998,"amp":0.71},{"time":133.33333333333331,"length":10.666666666666686,"curve":20,"speed":0.12499999999999978,"amp":-14.000000000000476},{"time":144,"length":10.666666666666657,"curve":20,"speed":0.1093749999999997,"amp":-14.000000000000476}]}],["Camera/roll",{"items":[{"time":5.333333333333334,"length":21.333333333333332,"value":-0.2500000000000003,"curve":21,"speed":0.1875},{"time":32,"value":-1.190000000000011},{"time":37.33333333333333,"length":5.333333333333329,"value":-0.3,"curve":19,"speed":0.2499999999999999,"amp":0.30000000000000004},{"time":48},{"time":53.333333333333336,"value":0.25},{"time":56},{"time":58.666666666666664,"value":-0.14},{"time":61.333333333333336,"value":-0.460000000000002},{"time":64},{"time":66.66666666666666},{"time":69.33333333333333,"value":0.54},{"time":71.99999999999999,"value":0.15},{"time":74.66666666666666,"value":-0.25},{"time":77.33333333333333,"value":0.5000000000000004},{"time":79.99999999999999,"value":0.33000000000000007},{"time":82.66666666666666,"value":0.23000000000000007},{"time":85.33333333333333,"value":2.380000000000001},{"time":88},{"time":89.33333333333331,"length":1.3333333333333428,"curve":28,"speed":0.4999999999999974,"amp":3},{"time":90.66666666666666},{"time":101.33333333333333},{"time":102.66666666666666,"value":-0.26000000000000006},{"time":104.00158889323498},{"time":112,"length":5.333333333333329,"curve":24,"speed":0.5000000000000013,"amp":-0.2700000000000004},{"time":117.33333333333333,"value":0.32999999999999585},{"time":121.33333333333333,"value":-0.10000000000000413},{"time":122.66666666666666,"length":5.333333333333329,"value":0.10999999999999989,"curve":24,"speed":0.5000000000000013,"amp":0.049999999999999524},{"time":127.99999999999999},{"time":133.33333333333331,"value":0.4699999999999978},{"time":144,"value":-0.3300000000000022}]}],["Camera/shake",{"items":[{},{"time":48,"length":1,"curve":27},{"time":50.666666666666664,"length":1,"curve":27},{"time":53.333333333333336,"length":1,"curve":27},{"time":56,"length":1,"curve":27},{"time":58.666666666666664,"length":1,"curve":27},{"time":61.333333333333336,"length":1,"curve":27},{"time":64,"length":1,"curve":27},{"time":66.66666666666666,"length":1,"curve":27},{"time":69.33333333333333,"length":1,"curve":27},{"time":71.99999999999999,"length":1,"curve":27},{"time":74.66666666666666,"length":1,"curve":27},{"time":77.33333333333333,"length":1,"curve":27},{"time":79.99999999999999,"length":1,"curve":27},{"time":82.66666666666666,"length":1,"curve":27},{"time":85.33333333333333,"length":1,"curve":27},{"time":88,"length":1,"curve":27},{"time":121.33333333333333,"length":1.3333333333333286,"value":0.01999999999999999,"reset":true},{"time":149.33333333333331,"length":4,"curve":33,"amp":0.020000000000000004},{"time":153.33333333333331,"length":1.3333333333333428,"curve":34,"amp":0.5499999999999999}]}],["Camera/fov",{"items":[{"value":0.5},{"time":48,"value":0.8},{"time":152.1,"length":2.066666666666663,"value":0.8,"curve":18,"speed":0.5,"amp":0.3599999999999957}]}],["DVi/amp",{"items":[{},{"time":133.33333333333331,"length":1.3333333333333286,"curve":31},{"time":149.33333333333331}]}],["DVi/offset",{"items":[{"time":133.33333333333331,"length":1.3333333333333286,"curve":31,"amp":8}]}],["Post/colorPreset",{"items":[{},{"time":48,"value":1},{"time":112,"value":2}]}],["Greetings/active",{"items":[{},{"time":133.33333333333331,"length":16}]}],["Post/mixInvert",{"items":[{},{"time":121.33333333333333,"length":1.3333333333333286,"value":1,"reset":true}]}],["Phantom/active",{"items":[{},{"time":111.33333333333333,"length":42.66666666666667}]}],["Crystal/beam/charge",{"items":[{},{"time":149.33333333333331,"length":4,"curve":35,"amp":0.36000000000000004},{"time":153.33333333333331,"length":1.3333333333333428,"curve":34,"amp":0.9599999999999995}]}],["Crystal/beam/shot",{"items":[{},{"time":153.33333333333331,"length":1.3333333333333428,"curve":34,"amp":0.9599999999999995}]}],["Crystal/beam/ring",{"items":[{"time":151.9,"length":2.666666666666657,"curve":36,"speed":0.7614331254621488,"amp":10.469999999999992}]}]],"labels":{"zero":0,"begin":5.333333333333333,"neuro":48,"porterfuckingrobinson":112,"fuckingcamellia":90.66666666666666,"psy":154.66666666666666},"guiSettings":{"snapTimeActive":true,"snapTimeInterval":0.1,"snapValueActive":true,"snapValueInterval":1,"snapBeatActive":true,"bpm":180,"beatOffset":0,"useBeatInGUI":true,"minimizedPrecisionTime":3,"minimizedPrecisionValue":3}} \ No newline at end of file +{"version":"4.1.1","resolution":400,"curves":[{"nodes":[[0,1,0,0,0.16140350877192983],[1,0,-0.47719298245614045]]},{"nodes":[[],[0.6666666666666666,1,-0.4560629631300563,-0.1852941176470587],[0.6666666666666666,0,0,0,0.26644908616188,0.1029411764705882],[2,1.1900000000000002,-0.1],[2,0.00686274509803933,0,0,0.10652741514360319],[2.6666666666666665,0.7000000000000001],[2.6666666666666665,0,0,0,0.1391644908616188,0.5215686274509802],[3.333333333333333,0.9,-0.5014360313315928,-0.22647058823529403],[3.333333333333333,0,0,0,0.3974946346535474,0.10043744264185422],[4.666666666666666,1.2000000000000002,0,0,0.1],[4.666666666666666],[5.333333333333333,0.7000000000000001,-0.24079400848586707,-0.49736814906842436],[5.333333333333333],[6,0.8,-0.4356422056174482,-0.17156862745098037],[6,0,0,0,0.32852235276081576,0.05490196078431372],[7.333333333333333,1.1441176470588237,-0.1,0,0.1],[7.333333333333333],[8,0.3333],[8,0,0,0,0.08806743643105143,0.4254901960784307],[8.666666666666666,0.9,-0.3995834676293276,-0.08230605476940031],[8.666666666666666],[9.4,1.1,-0.2785205844025618,-0.17156862745098012,0.2785205844025618,0.17156862745098012],[10,1.3],[10],[10.666666666666666,0.6000000000000001,-0.11225401796276425,-0.5783350570563074]],"fxs":[{"def":"repeat","params":{"interval":0.2299999999999996},"time":7.333333333333333,"length":0.6666666666666667}]},{"nodes":[[0,0,0,0,0.12284595300261082,0.061764705882352944],[0.6666666666666666,0.4,-0.1],[0.6666666666666666,0.06568627450980391],[2,0.2],[2.236344893790143,0.4,-0.1,0,0.1],[2.6666666666666665,0,-0.34575086532310695,0,0.04271204452939744],[2.769918291305192,0.1,-0.05130523784998782,0,0.09999999999999999],[3.333333333333333,0.1],[3.6666666666666665,0.32774323388394533],[4.666666666666666,0.30000000000000004],[4.666666666666666,0.023323265139934546],[5.333333333333333,0.1],[5.333333333333333],[6,0.30000000000000004],[6,0.02745098039215696,0,0,0.09974597868276715,-0.006845312262542842],[7.333333333333333,0.1,-0.1],[7.333333333333333,0.7000000000000001],[8.666666666666666,0.7000000000000001],[8.666666666666666,1],[10,0.1],[10.666666666666666]]},{"nodes":[[0,0,0,0,0.1],[0.3333333333333333,1,-0.1,0,0.1],[0.6666666666666666,0,-0.1],[1.9166666666666665,1,-1.0007832898172324,0,0.06],[2],[2.025071712633245,1,-0.044516971279373374,0,0.1],[2.1623944411350506,0.5,-0.07221383357420871,0.2738348538091391,0.07221383357420871,-0.2738348538091391],[2.6666666666666665,0,-0.1,0,0.1],[3,1,-0.2864316909347707,0,0.24406085208595923],[3.333333333333333,0,-0.036443741726782705,0.4106336078810942],[3.6666666666666665,0.7544057184393509,-0.08631141286229893,-0.07178801363349067,0.13346814639852406,0.11100980502520727],[4.666666666666666,1,-0.33942558746736295,-0.018347344929083464,0.09208797505724492,-0.3264027483296351],[4.851079899134173,0.30000000000000004,-0.07486057061026631,-0.013179150760383026,0.1],[5.0444017511428605,0.9656862745098039,-0.1,0,0.1],[5.333333333333333,0.044689231228471016,-0.1,0,0.1],[5.666666666666666,1,-0.1,0,0.1],[6,0,-0.1],[7.333333333333333,1,-1.0426547051383652,0,0.1],[7.6000000000000005,0.7000000000000001,-0.1,0,0.1],[8,1],[8,0,-0.1,0,0.1],[8.166666666666666,1,-0.099988538641853,-0.006965859231865531],[8.489362746562259,1,0,0,0.09998887794379856,-0.006861981819672439],[8.666666666666666,0,-0.11262160793957762,0.041182622607896624],[8.9,1,-0.11617352813418727,-0.020588235294117612,0.11617352813418727,0.020588235294117612],[9.04400609908224,0.15784313725490162,-0.0988340957186134,-0.027450980392156817,0.0988340957186134,0.027450980392156817],[9.3,1,-0.09200304954112025,-0.041176470588235224,0.09200304954112025,0.041176470588235224],[9.5,0.2,-0.09449923761471994,-0.06176470588235285,0.09449923761471994,0.06176470588235285],[9.666666666666666,1,-0.08899847522943988,-0.027450980392156817,0.08899847522943988,0.027450980392156817],[10,0.30000000000000004,-0.06149466330303955,-0.06176470588235285,0.06149466330303955,0.06176470588235285],[10,1,-0.1,0,0.1],[10.666666666666666,0.1,-0.1,0,0.1]],"fxs":[{"def":"repeat","params":{"interval":0.2490000000000001},"time":2,"length":0.6666666666666665},{"def":"sine","params":{"amp":0.26,"freq":8.590000000000002,"offset":0},"time":3.934411837854859,"length":0.7322548288118069},{"def":"sine","params":{"amp":0.4400000000000004,"freq":5.889999999999998,"offset":0},"time":10.234266741175261,"length":0.4323999254914046},{"def":"hermitePatch","params":{},"time":3.821100533282267,"length":0.12610951070520438,"row":1},{"def":"hermitePatch","params":{},"time":10.18270758125172,"length":0.09198590579094379,"row":1}]},{"nodes":[[0,0,0,0,0.1],[0.6666666666666666,1,-0.1],[0.6666666666666666,0.04000000000000001],[2,0.019999999999999997],[2,0.4],[2.6666666666666665],[3.333333333333333,0.2,-0.1],[3.333333333333333,0.5],[4.666666666666666,0.6000000000000001],[4.666666666666666,0.059594068084455554],[5.333333333333333],[6,0.1],[7.333333333333333,0,-1.3219093627620064,-0.061764705882352944],[8],[8,0.8],[10,0.8],[10,0.1],[10.666666666666666]]},{"nodes":[[0,0,0,0,0.11631853785900784,0.15784313725490196],[0.3333333333333333,0.2,-0.1,-0.06862745098039215],[0.3333333333333333,0,0,0,0.10652741514360313,0.034313725490196074],[0.6257615317667536,0.4,-0.035197899213743125,-0.1178437887562426,0.05762038784328031,0.19291505927163513],[1.5833333333333333,1.6588235294117648,-0.14423846823324632,-0.08235294117647059],[1.5833333333333333,0,0,0,0.0706266318537859,0.12352941176470589],[1.8333333333333333,0.6000000000000001,-0.07923141560987097,-0.16655319476142408,0.05223508415950609,0.10980392156862741],[2,0.8,-0.07118673688066018,-0.08235294117647059]]},{"nodes":[[0,0.7000000000000001,0,0,0.14895561357702347,-0.7343137254901958],[0.6666666666666666,0.01999999999999999,-0.07958650842810296,0.0005266470222471706,0.7602446192333546,-0.005030759268204068],[1.75,0.2,-0.175065274151436,-0.0480392156862745],[2,1,-0.1]]},{"nodes":[[0,0.264705882352941,0,0,0.2664490861618798,-0.3705882352941175],[1.75,0,-0.1,0,0.1],[2,1,-0.1]]},{"nodes":[[0,0,0,0,0.1],[0.3333333333333333,0.9460784313725474,-0.1,0,0.1],[1.3333333333333333,0.3627450980392144,-0.11276290315437737,0.31798356313506776,0.058202350589290165,-0.16412659044332573],[1.6666666666666665,1,-0.1,0,0.1],[1.7304177545691903,0.1,-0.1,0,0.1],[2,1.4000000000000001,-0.05099116999738633,-0.5930547707442783]],"fxs":[{"def":"sine","params":{"amp":0.3999999999999999,"freq":17.779999999999987,"offset":0},"time":0.6103133159268926,"length":0.7230200174064406},{"def":"hermitePatch","params":{},"time":0.5580939947780674,"length":0.08289817232376029,"row":1},{"def":"hermitePatch","params":{},"time":1.2836814621409922,"length":0.11631853785900792,"row":1}]},{"nodes":[[0,1,0,0,0.06843643544269563,-0.8715686274509801],[0.6666666666666666,0,-0.47719298245614045]]},{"nodes":[[],[2,2]]},{"nodes":[[0,0.1],[1.3333333333333333,0.30000000000000004]]},{"nodes":[[],[1.3333333333333333]]},{"nodes":[[0,0,0,0,0.07564543093234954,0.8647058823529409],[1.3333333333333333,1]]},{"nodes":[[],[0.3333333333333333,0.333],[0.3333333333333333,0,0,0,0.04050107306929012,0.096078431372549],[0.5833333333333333,0.30000000000000004,-0.10502788587794674,-0.054901960784313704],[1.3333333333333333]],"fxs":[{"def":"repeat","params":{"interval":0.2499999999999999},"time":0.3333333333333333,"length":1}]},{"nodes":[[0,0,0,0,0.041253263707571805],[0.1,0.472549019607836,-0.044516971279373374,-0.2333333333333331,0.037233176309202774,0.19515571003904697],[1.3333333333333333,1,-1.2945169712793734]]},{"nodes":[[0,0,0,0,0.1],[0.8,0.9,-0.10634811016391839,-0.09574850838471399,0.10634811016391839,0.09574850838471399],[1,1,-0.034837955875665044,-0.008249475331448328]]},{"nodes":[[0,1,0,0,0.08905168734696595,-0.6204705716763121],[0.8,0.1,-0.3657976094933656,0.05238364149449456,0.3657976094933656,-0.05238364149449456],[4,0,-0.5779474714155504]]},{"nodes":[[0,0,0,0,0.33333333333333337],[0.5833333333333333,0.13137254901960788,-0.06553651288762144,-0.14663596634864273,0.06553651288762144,0.14663596634864273],[0.6673629242819844,0.7480392156862745,-0.06736292428198434,-0.16470588235294117,0.06736292428198434,0.16470588235294117],[1.563751087902524,0.9519607843137257,-0.20443864229765013,-0.02745098039215686,0.20443864229765013,0.02745098039215686],[4,1,-0.5779474714155504]]},{"nodes":[[0,0,0,0,0.3154046997389034],[1.3333333333333333,1,-0.29908616187989556]]},{"nodes":[[],[1.3333333333333333,1]]},{"nodes":[[0,1,0,0,0.08905168734696595,-0.6204705716763121],[4,0,-3.146485330423383]]},{"nodes":[[0,1,0,0,0.15000000000000002],[0.25,1,-0.1,0,0.047780678851174936],[0.3333333333333333,0,-0.006527415143603133,0.3068670573880632,0.04083550913838122,0.1415436161688415],[0.4601827676240209,0,-0.031462140992167105,0.14076447719138005,0.031462140992167105,0.08154620354285587],[0.5515665796344648,0,-0.024934725848563967,0.05959145643516391,0.03472584856396867,0.040773101771427935],[0.6364229765013054,0,-0.024934725848563963,0.02509113955164797],[1,0,0,0,0.35333333333333333],[2.333333333333333,1,-0.3643603133159269,0,0.1]]},{"nodes":[[0,0,0,0,0.3317232375979112],[2,1,-1.3746781892076712]]},{"nodes":[[0,0,0,0,0.28276762402088773],[2.6666666666666665,1,-0.4673674842468357]]},{"nodes":[[0,0,0,0,0.429634464751958],[2.6666666666666665,0.99,-1.447911227154047]]},{"nodes":[[0,1,0,0,0.03472584856396867,-0.3705882352941176],[0.6666666666666666,0,-0.6417754569190601]]},{"nodes":[[0,0.4166666666666666,0,0,0.1],[0.6666666666666666,0,-0.664621409921671]]},{"nodes":[[0,0,0,0,0.1],[1.0065274151436032,0.9480392156862747,-0.791906005221932,-0.19215686274509805,0.17102946263472904,0.04150048712872081],[1.3333333333333333,1,-0.1]]},{"nodes":[[0,0,0,0,0.09780980358890974,0.020588235294117938],[0.3333333333333333,1,-0.04311987540653206,-0.9333333333333332]]},{"nodes":[[0,0.2],[1.3333333333333333,1.8,-1.0186386106576615,-0.609915244226372]]},{"nodes":[[0,0,0,0,0.011879895561357705,0.5490196078431372],[1.3333333333333333,1,-1.2292428198433418]]},{"nodes":[[0,0,0,0,0.1],[1,0,-0.1]]},{"nodes":[[0,0,0,0,0.9453002610966057],[4,1]]},{"nodes":[[0,0.9539215686274509,0,0,0.11305483028720623,-0.5970588235294118],[0.3333333333333333,0.1294117647058824,-0.07715404699738904,0.05490196078431372,0.07715404699738904,-0.05490196078431372],[1.3333333333333333,0,-1.133333333333333]]},{"nodes":[[0,0,0,0,3.415926892950391],[4,1]]},{"nodes":[[0,0.9539215686274509,0,0,0.15548302872062658,-0.6039215686274509],[1.3333333333333333,0,-0.6862053959965185]]},{"nodes":[[0,0.9539215686274509,0,0,0.06736292428198429,-0.6862745098039215],[1.3333333333333333,0,-1.208398607484769]]},{"nodes":[[],[0.16666666666666666,0.16642898215255936],[0.16666666666666666],[0.3333333333333333,0.1728044353004796],[0.3333333333333333,0,0,0,0.04050107306929012,0.096078431372549],[0.5833333333333333,0.30000000000000004,-0.10502788587794674,-0.054901960784313704],[1.3333333333333333]],"fxs":[{"def":"repeat","params":{"interval":0.2499999999999999},"time":0.3333333333333333,"length":1}]},{"nodes":[[],[0.16666666666666666,0.16642898215255936],[0.16666666666666666],[0.3333333333333333,0.1728044353004796],[0.3333333333333333,0,0,0,0.3126188615546539,0.15175152819068202],[1.1666666666666665,1,-0.1572879554706029,-0.28764433356035396],[1.1666666666666665,0.3653790156299723],[1.3333333333333333]]},{"nodes":[[],[0.16666666666666666,0.333],[0.16666666666666666],[0.3333333333333333,0.659941132909589],[0.3333333333333333,0,0,0,0.04050107306929012,0.096078431372549],[0.5833333333333333,0.30000000000000004,-0.10502788587794674,-0.054901960784313704],[1],[1.0833333333333333,0.10984958946310308,-0.05834560450044708,-0.037115397878755355],[1.3333333333333333]],"fxs":[{"def":"repeat","params":{"interval":0.2499999999999999},"time":0.3333333333333333,"length":0.6624660750216953},{"def":"repeat","params":{"interval":0.08199999999999981},"time":1,"length":0.33333333333333326},{"def":"repeat","params":{"interval":0.040999999999999204},"time":1.1666666666666665,"length":0.16666666666666674,"row":1}]},{"nodes":[[0,0.1],[0.3333333333333333,1.2904533929940294],[1.3333333333333333,0.053457044213489124,-0.8632620739919382,0.12473310316480792]]},{"nodes":[[0,1],[0.3333333333333333,0.43235294117647044],[0.3333333333333333,1,0,0,0.04376478064109168,-0.28137254901960784],[0.5833333333333333,0.44607843137254904,-0.11808271616515305,0.10980392156862744],[1.3333333333333333]],"fxs":[{"def":"repeat","params":{"interval":0.2499999999999999},"time":0.3333333333333333,"length":1}]}],"channels":[["EnvironmentMap/accumulate",{"items":[{},{"time":5.333333333333333,"length":1,"value":0.1,"curve":26,"amp":0.9},{"time":48,"length":1,"value":0.1,"curve":26,"amp":0.9},{"time":90.66666666666666,"length":1,"value":0.1,"curve":26,"amp":0.9},{"time":110.66666666666666,"length":1,"value":0.1,"curve":26,"amp":0.9},{"time":121.33333333333333,"length":1,"value":0.1,"curve":26,"amp":0.9},{"time":122.66666666666666,"length":1,"value":0.1,"curve":26,"amp":0.9}]}],["Glitch/amp",{"items":[{},{"time":48,"length":1,"curve":0},{"time":50.666666666666664,"length":1,"curve":0},{"time":53.333333333333336,"length":1,"curve":0},{"time":56,"length":1,"curve":0},{"time":58.666666666666664,"length":1,"curve":0},{"time":61.333333333333336,"length":1,"curve":0},{"time":64,"length":1,"curve":0},{"time":66.66666666666666,"length":1,"curve":0},{"time":69.33333333333333,"length":1,"curve":0},{"time":71.99999999999999,"length":1,"curve":0},{"time":74.66666666666666,"length":1,"curve":0},{"time":77.33333333333333,"length":1,"curve":0},{"time":79.99999999999999,"length":1,"curve":0},{"time":82.66666666666666,"length":1,"curve":0},{"time":85.33333333333333,"length":1,"curve":0},{"time":88,"length":1,"curve":0},{"time":149.33333333333331,"length":4,"curve":33,"amp":0.5000000000000002},{"time":153.33333333333331,"length":0.6666666666666856,"value":0.53,"reset":true},{"time":261.3333333333333}]}],["PixelSorter/amp",{"items":[{},{"time":48,"length":1.3333333333333357,"curve":9,"speed":0.4999999999999975},{"time":50.666666666666664,"length":1.3333333333333357,"curve":9,"speed":0.4999999999999975},{"time":53.333333333333336,"length":1.3333333333333357,"curve":9,"speed":0.4999999999999975},{"time":56,"length":1.3333333333333357,"curve":9,"speed":0.4999999999999975},{"time":58.666666666666664,"length":1.3333333333333357,"curve":9,"speed":0.4999999999999975},{"time":61.333333333333336,"length":1.3333333333333357,"curve":9,"speed":0.4999999999999975},{"time":64,"length":1.3333333333333357,"curve":9,"speed":0.4999999999999975},{"time":66.66666666666666,"length":1.3333333333333357,"curve":9,"speed":0.4999999999999975},{"time":69.33333333333333,"length":1.3333333333333357,"curve":9,"speed":0.4999999999999975},{"time":71.99999999999999,"length":1.3333333333333357,"curve":9,"speed":0.4999999999999975},{"time":74.66666666666666,"length":1.3333333333333357,"curve":9,"speed":0.4999999999999975},{"time":77.33333333333333,"length":1.3333333333333357,"curve":9,"speed":0.4999999999999975},{"time":79.99999999999999,"length":1.3333333333333357,"curve":9,"speed":0.4999999999999975},{"time":82.66666666666666,"length":1.3333333333333357,"curve":9,"speed":0.4999999999999975},{"time":85.33333333333333,"length":1.3333333333333357,"curve":9,"speed":0.4999999999999975},{"time":87.99999999999999,"length":1.3333333333333357,"curve":9,"speed":0.4999999999999975},{"time":90.30000000000001,"length":0.3333333333333286,"curve":29,"speed":1.0000000000000153,"amp":-0.4},{"time":90.66666666666666,"length":0.3333333333333428,"curve":9,"speed":1.999999999999927},{"time":93.33333333333333,"length":0.3333333333333428,"curve":9,"speed":1.999999999999927},{"time":96,"length":0.3333333333333428,"curve":9,"speed":1.999999999999927},{"time":97.33333333333333},{"time":98.66666666666667,"length":0.3333333333333428,"curve":9,"speed":1.999999999999927},{"time":101.33333333333333,"length":0.3333333333333428,"curve":9,"speed":1.999999999999927},{"time":104,"length":0.3333333333333428,"curve":9,"speed":1.999999999999927},{"time":106.66666666666667,"length":0.3333333333333428,"curve":9,"speed":1.999999999999927},{"time":109.33333333333333,"length":0.3333333333333428,"curve":9,"speed":1.999999999999927},{"time":153.33333333333331,"length":0.6666666666666856,"value":0.53,"reset":true}]}],["Serial/enable",{"items":[{},{"time":91.99999999999999,"length":1.3333333333333428},{"time":94.66666666666666,"length":1.3333333333333428},{"time":97.33333333333333,"length":1.3333333333333428},{"time":99.99999999999999,"length":1.3333333333333428},{"time":102.66666666666666,"length":1.3333333333333428},{"time":105.33333333333333,"length":1.3333333333333428},{"time":107.99999999999999,"length":1.3333333333333428},{"time":110.66666666666666,"length":1.3333333333333428},{"time":153.33333333333331,"length":1.3333333333333428}]}],["SceneBegin/active",{"items":[{},{"time":5.333333333333333,"length":42.666666666666664}]}],["Sync/first/clap",{"items":[{},{"time":27.666666666666664,"length":1.3333333333333321,"curve":15},{"time":28.999999999999996,"length":1.3333333333333321,"value":1,"curve":15},{"time":30.33333333333333,"length":1.3333333333333321,"value":2,"curve":15},{"time":31.66666666666666,"length":1.3333333333333321,"value":3,"curve":15},{"time":32.99999999999999,"length":1.3333333333333321,"value":4,"curve":15},{"time":34.33333333333333,"length":1.3333333333333321,"value":5,"curve":15},{"time":35.66666666666666,"length":1.3333333333333321,"value":6,"curve":15},{"time":36.99999999999999,"length":1.3333333333333321,"value":7,"curve":15},{"time":38.33333333333332,"length":1.3333333333333321,"value":8,"curve":15},{"time":39.66666666666665,"length":1.3333333333333321,"value":9,"curve":15},{"time":40.99999999999998,"length":1.3333333333333321,"value":10,"curve":15},{"time":42.33333333333331,"length":1.3333333333333321,"value":11,"curve":15}]}],["Condition/hahaRatio",{"items":[{},{"time":42.666666666666664,"length":4,"curve":25}]}],["Condition/phaseWidth",{"items":[{"value":0.1},{"time":27.666666666666664,"length":20.333333333333332,"value":0.1,"curve":16,"speed":0.049180327868852465,"amp":0.5888750576601328}]}],["SceneNeuro/active",{"items":[{},{"time":48,"length":42.666666666666664}]}],["sufferText/push",{"items":[{"time":48},{"time":50.666666666666664,"value":1},{"time":53.333333333333336,"value":2},{"time":56,"value":3},{"time":58.666666666666664,"value":4},{"time":61.333333333333336,"value":5},{"time":64,"value":6},{"time":66.66666666666666,"value":7},{"time":69.33333333333333,"value":8},{"time":71.99999999999999,"value":9},{"time":74.66666666666666,"value":10},{"time":77.33333333333333,"value":11},{"time":79.99999999999999,"value":12},{"time":82.66666666666666,"value":13},{"time":85.33333333333333,"value":14},{"time":87.99999999999999,"value":15}]}],["IFSPistons/group0/rot",{"items":[{},{"time":48.666666666666664,"length":2,"curve":23},{"time":54,"length":2,"value":1,"curve":23},{"time":59.333333333333336,"length":2,"value":2,"curve":23},{"time":64.66666666666666,"length":2,"value":3,"curve":23},{"time":69.99999999999999,"length":2,"value":4,"curve":23},{"time":75.33333333333333,"length":2,"value":5,"curve":23},{"time":80.66666666666666,"length":2,"value":6,"curve":23},{"time":85.99999999999999,"length":2,"value":7,"curve":23}]}],["IFSPistons/group1/rot",{"items":[{},{"time":51.333333333333336,"length":2,"curve":23},{"time":56.666666666666664,"length":2,"value":1,"curve":23},{"time":62,"length":2,"value":2,"curve":23},{"time":67.33333333333333,"length":2,"value":3,"curve":23},{"time":72.66666666666666,"length":2,"value":4,"curve":23},{"time":77.99999999999999,"length":2,"value":5,"curve":23},{"time":83.33333333333333,"length":2,"value":6,"curve":23},{"time":88.66666666666666,"length":2,"value":7,"curve":23}]}],["IFSPistons/group0/pos",{"items":[{"value":3},{"time":47.666666666666664,"length":2.3333333333333357,"value":1.2000000000000002,"curve":22,"amp":1.7999999999999998},{"time":53,"length":2.3333333333333357,"value":1.2000000000000002,"curve":22,"amp":1.7999999999999998},{"time":58.333333333333336,"length":2.3333333333333357,"value":1.2000000000000002,"curve":22,"amp":1.7999999999999998},{"time":63.666666666666664,"length":2.3333333333333357,"value":1.2000000000000002,"curve":22,"amp":1.7999999999999998},{"time":69.03333333333333,"length":2.3333333333333357,"value":1.2000000000000002,"curve":22,"amp":1.7999999999999998},{"time":74.33333333333333,"length":2.3333333333333357,"value":1.2000000000000002,"curve":22,"amp":1.7999999999999998},{"time":79.66666666666666,"length":2.3333333333333357,"value":1.2000000000000002,"curve":22,"amp":1.7999999999999998},{"time":84.99999999999999,"length":2.3333333333333357,"value":1.2000000000000002,"curve":22,"amp":1.7999999999999998}]}],["IFSPistons/group1/pos",{"items":[{"value":3},{"time":50.333333333333336,"length":2.3333333333333357,"value":1.2000000000000002,"curve":22,"amp":1.7999999999999998},{"time":55.666666666666664,"length":2.3333333333333357,"value":1.2000000000000002,"curve":22,"amp":1.7999999999999998},{"time":61,"length":2.3333333333333357,"value":1.2000000000000002,"curve":22,"amp":1.7999999999999998},{"time":66.33333333333333,"length":2.3333333333333357,"value":1.2000000000000002,"curve":22,"amp":1.7999999999999998},{"time":71.66666666666666,"length":2.3333333333333357,"value":1.2000000000000002,"curve":22,"amp":1.7999999999999998},{"time":76.99999999999999,"length":2.3333333333333357,"value":1.2000000000000002,"curve":22,"amp":1.7999999999999998},{"time":82.33333333333333,"length":2.3333333333333357,"value":1.2000000000000002,"curve":22,"amp":1.7999999999999998},{"time":87.66666666666666,"length":2.3333333333333357,"value":1.2000000000000002,"curve":22,"amp":1.7999999999999998}]}],["Music/NEURO_TIME",{"items":[{},{"time":48,"length":10.666666666666664,"curve":1},{"time":58.666666666666664,"length":8.666666666666671,"curve":1},{"time":67.33333333333333,"length":1.999999999999993,"curve":5},{"time":69.33333333333333,"length":10.666666666666664,"curve":1},{"time":79.99999999999999,"length":8.666666666666671,"curve":1},{"time":88.66666666666666,"length":0.6666666666666714,"curve":5},{"time":89.33333333333333,"length":1.3333333333333286,"curve":30},{"time":90.66666666666666,"length":1.3333333333333286,"curve":10,"offset":1.4210854715202004e-14},{"time":91.99999999999999,"length":1.3333333333333286,"curve":14},{"time":93.33333333333331,"length":1.3333333333333428,"curve":10},{"time":94.66666666666666,"length":1.3333333333333286,"curve":39},{"time":95.99999999999999,"length":1.3333333333333428,"curve":10},{"time":97.33333333333333,"length":1.3333333333333286,"curve":14},{"time":98.66666666666666,"length":1.3333333333333428,"curve":10},{"time":100,"length":1.3333333333333286,"curve":40},{"time":101.33333333333333,"length":1.3333333333333428,"curve":10},{"time":102.66666666666667,"length":1.3333333333333144,"curve":14},{"time":103.99999999999999,"length":1.3333333333333428,"curve":10},{"time":105.33333333333333,"length":1.3333333333333286,"curve":39},{"time":106.66666666666666,"length":1.3333333333333428,"curve":10},{"time":108,"length":1.3333333333333286,"curve":14},{"time":109.33333333333333,"length":1.3333333333333428,"curve":10}]}],["Music/NEURO_DETUNE",{"items":[{},{"time":48,"length":10.666666666666664,"curve":2},{"time":58.666666666666664,"length":8.666666666666671,"curve":2},{"time":67.33333333333333,"length":1.999999999999993,"curve":6},{"time":69.33333333333333,"length":10.666666666666664,"curve":2},{"time":79.99999999999999,"length":8.666666666666671,"curve":2},{"time":88.66666666666666,"length":2,"curve":6,"speed":0.8333333333333358},{"time":90.66666666666666,"length":1.3333333333333286,"curve":11},{"time":93.33333333333333,"length":1.3333333333333286,"curve":11},{"time":95,"length":0.9999999999999858,"curve":2,"offset":2},{"time":95.99999999999999,"length":1.3333333333333286,"curve":11},{"time":97.33333333333331,"length":1.3333333333333428,"value":0.77},{"time":98.66666666666666,"length":1.3333333333333286,"curve":11},{"time":99.99999999999999,"length":1.3333333333333428,"curve":41},{"time":101.33333333333333,"length":1.3333333333333286,"curve":11},{"time":103.99999999999999,"length":1.3333333333333286,"curve":11},{"time":105.66666666666667,"length":0.9999999999999858,"curve":2,"offset":2},{"time":106.66666666666666,"length":1.3333333333333286,"curve":11},{"time":107.99999999999999,"length":1.3333333333333428,"value":0.77},{"time":109.33333333333333,"length":1.3333333333333286,"curve":11}]}],["Music/NEURO_DETUNE_PHASE",{"items":[{},{"time":48,"length":10.666666666666664,"curve":4},{"time":58.666666666666664,"length":8.666666666666671,"curve":4},{"time":67.33333333333333,"length":1.999999999999993,"curve":7},{"time":69.33333333333333,"length":10.666666666666664,"curve":4},{"time":79.99999999999999,"length":8.666666666666671,"curve":4},{"time":88.66666666666666,"length":2,"curve":7,"speed":0.8333333333333358},{"time":90.66666666666666,"length":1.3333333333333428,"curve":12},{"time":93.33333333333333,"length":1.3333333333333428,"curve":12},{"time":95,"length":0.9999999999999858,"curve":4,"offset":1.9999999999999858},{"time":95.99999999999999,"length":1.3333333333333428,"curve":12},{"time":98.66666666666666,"length":1.3333333333333428,"curve":12},{"time":101.33333333333333,"length":1.3333333333333428,"curve":12},{"time":103.99999999999999,"length":1.3333333333333428,"curve":12},{"time":105.66666666666667,"length":0.9999999999999858,"curve":4,"offset":1.9999999999999858},{"time":106.66666666666666,"length":1.3333333333333428,"curve":12},{"time":109.33333333333333,"length":1.3333333333333428,"curve":12}]}],["Music/NEURO_WUB_AMP",{"items":[{},{"time":48,"length":10.668578038364203,"curve":3},{"time":58.6685780383642,"length":8.664755294969133,"curve":3},{"time":67.33333333333333,"length":2.0038227433950624,"curve":8},{"time":69.33715607672839,"length":10.668578038364203,"curve":3},{"time":80.0057341150926,"length":8.660932551574064,"curve":3},{"time":88.66666666666666,"length":2,"curve":8,"speed":0.8028871529270708},{"time":90.66666666666666,"length":1.3333333333333333,"curve":13},{"time":93.33333333333333,"length":1.3333333333333333,"curve":13},{"time":94.66666666666666,"length":1.3333333333333286,"curve":3,"offset":1.6666666666666856},{"time":95.99999999999999,"length":1.3333333333333333,"curve":13},{"time":98.66666666666666,"length":1.3333333333333333,"curve":13},{"time":101.33333333333333,"length":1.3333333333333333,"curve":13},{"time":103.99999999999999,"length":1.3333333333333333,"curve":13},{"time":105.33333333333331,"length":1.0000000000000142,"curve":8,"offset":0.26762905097568646,"speed":0.8028871529270708},{"time":106.66666666666666,"length":1.3333333333333333,"curve":13},{"time":109.33333333333333,"length":1.3333333333333333,"curve":13}]}],["Music/NEURO_WUB_FREQ",{"items":[{},{"time":48,"length":2,"value":1},{"time":50,"length":0.6666666666666643,"value":0.49999999999999967},{"time":50.666666666666664,"length":0.6666666666666714,"value":1},{"time":51.333333333333336,"length":1.3333333333333286,"value":2},{"time":52.666666666666664,"length":0.6666666666666714,"value":2.5},{"time":53.333333333333336,"length":0.6666666666666643,"value":1},{"time":54,"length":1.3333333333333357,"value":1},{"time":55.333333333333336,"length":0.6666666666666643,"value":2},{"time":56,"length":2,"value":1},{"time":58,"length":0.6666666666666643,"value":2},{"time":58.666666666666664,"length":0.6666666666666714,"value":1},{"time":59.333333333333336,"length":1.3333333333333286,"value":2.1000000000000014},{"time":60.666666666666664,"length":0.6666666666666714,"value":0.5},{"time":61.333333333333336,"length":0.6666666666666643,"value":7},{"time":62,"length":1.3333333333333357,"value":3},{"time":63.333333333333336,"length":0.6666666666666714,"value":1},{"time":64,"length":0.6666666666666714,"value":0.9600000000000006},{"time":64.66666666666667,"length":1.3333333333333215,"value":6},{"time":66,"length":0.6666666666666785,"value":10.840000000000003},{"time":66.66666666666667,"length":0.6666666666666572,"value":1},{"time":67.33333333333333,"length":1.3333333333333428,"value":3.989999999999996},{"time":68.66666666666667,"length":0.6666666666666572,"value":4.109999999999999},{"time":69.33333333333333,"length":2,"value":1},{"time":71.33333333333333,"length":0.6666666666666643,"value":0.49999999999999967},{"time":71.99999999999999,"length":0.6666666666666714,"value":1},{"time":72.66666666666666,"length":1.3333333333333286,"value":2},{"time":73.99999999999999,"length":0.6666666666666714,"value":2.5},{"time":74.66666666666666,"length":0.6666666666666643,"value":1},{"time":75.33333333333333,"length":1.3333333333333357,"value":1},{"time":76.66666666666667,"length":0.6666666666666643,"value":2},{"time":77.33333333333333,"length":2,"value":1},{"time":79.33333333333333,"length":0.6666666666666643,"value":2},{"time":79.99999999999999,"length":0.6666666666666714,"value":1},{"time":80.66666666666666,"length":1.3333333333333286,"value":2.1000000000000014},{"time":81.99999999999999,"length":0.6666666666666714,"value":0.5},{"time":82.66666666666666,"length":0.6666666666666643,"value":7},{"time":83.33333333333333,"length":1.3333333333333357,"value":3},{"time":84.66666666666667,"length":0.6666666666666714,"value":1},{"time":85.33333333333334,"length":0.6666666666666714,"value":0.9600000000000006},{"time":86.00000000000001,"length":1.3333333333333144,"value":6},{"time":87.33333333333333,"length":0.6666666666666856,"value":10.840000000000003},{"time":88.00000000000001,"length":0.6666666666666572,"value":1},{"time":88.66666666666667,"length":1.3333333333333428,"value":3.9899999999999993},{"time":90.00000000000001,"length":0.6666666666666572,"value":4.109999999999999},{"time":90.66666666666667,"length":1.3333333333333144,"value":1},{"time":93.33333333333333,"length":1.3333333333333144,"value":1},{"time":94.83333333333333,"length":0.1666666666666714,"value":7.320000000000001},{"time":95,"length":0.8333333333333286,"value":0.3800000000000011},{"time":95.83333333333333,"length":1.4999999999999716,"value":1},{"time":97.3333333333333,"length":1.059777391433414,"value":2},{"time":98.66666666666666,"length":1.3333333333333144,"value":1},{"time":99.99999999999997,"length":1.333333333333357,"value":0.7099999999999999},{"time":101.33333333333333,"length":1.3333333333333144,"value":1},{"time":103.99999999999999,"length":1.3333333333333144,"value":1},{"time":105.5,"length":0.1666666666666572,"value":9.219999999999999},{"time":105.66666666666666,"length":1,"value":3.6300000000000145},{"time":106.66666666666666,"length":1.3333333333333144,"value":1},{"time":107.99999999999997,"length":1.333333333333357,"value":6.199999999999992},{"time":109.33333333333333,"length":1.3333333333333144,"value":1}]}],["Trails/active",{"items":[{}]}],["SceneDynamic/active",{"items":[{},{"time":90.66666666666666,"length":20}]}],["SceneCrystals/active",{"items":[{},{"time":109.33333333333333,"length":44.66666666666667}]}],["FlickyParticles/active",{"items":[{},{"time":48,"length":62.66666666666666},{"time":112,"length":42}]}],["SphereParticles/active",{"items":[{},{"time":112,"length":41.333333333333314}]}],["SceneCrystals/ChaosTorus/active",{"items":[{"time":-8.200000000000001},{},{"time":121.33333333333333,"length":1.3333333333333286}]}],["Phantom/amp",{"items":[{},{"time":112,"length":1.3333333333333286,"curve":31}]}],["SceneCrystals/light/amp",{"items":[{},{"time":112,"length":1.3333333333333286,"curve":31}]}],["IFSAsUsual/active",{"items":[{},{"time":98.66666666666666,"length":2.6666666666666856}]}],["IFSAsUsual/ifsSeed",{"items":[{"time":98.66666666666666,"value":3.850000000002135},{"time":100,"value":6.374792659378448},{"time":100.16666666666666,"length":0.1666666666666572,"value":6.379868935734952,"curve":15,"speed":4.000000000000053,"amp":0.6201310642650482},{"time":100.33333333333331,"length":0.2500000000000142,"value":7,"curve":15,"speed":4.000000000000053,"amp":0.5},{"time":100.58333333333333,"length":0.2500000000000142,"value":7.5,"curve":15,"speed":4.000000000000053,"amp":0.5},{"time":100.83333333333334,"length":0.1666666666666572,"value":8,"curve":15,"speed":4.000000000000053,"amp":0.5},{"time":101,"length":0.0833333333333286,"value":-0.07450980392156825,"curve":15,"speed":4.000000000000053,"amp":0.07450980392156825},{"time":101.08333333333333,"length":0.0833333333333286,"value":-0.07450980392156825,"curve":15,"speed":4.000000000000053,"amp":0.07450980392156825},{"time":101.16666666666666,"length":0.041666666666671404,"value":-0.07450980392156825,"curve":15,"speed":4.000000000000053,"amp":0.07450980392156825},{"time":101.20833333333333,"length":0.041666666666671404,"value":-0.07450980392156825,"curve":15,"speed":4.000000000000053,"amp":0.07450980392156825},{"time":101.25,"length":0.041666666666671404,"value":-0.07450980392156825,"curve":15,"speed":4.000000000000053,"amp":0.07450980392156825},{"time":101.29166666666667,"length":0.041666666666671404,"value":-0.07450980392156825,"curve":15,"speed":4.000000000000053,"amp":0.07450980392156825}]}],["FlashyBall/active",{"items":[{},{"time":96,"length":2.6666666666666856},{"time":106.66666666666666,"length":2.6666666666666856}]}],["FlashyBall/distortAmp",{"items":[{"time":96},{"time":97.33333333333333,"length":1.3333333333333286,"curve":42,"amp":2.1099999999999985},{"time":106.66666666666666},{"time":108,"length":1.3333333333333286,"curve":42,"amp":2.1199999999999983}]}],["Tetrahedron/active",{"items":[{},{"time":93.33333333333333,"length":2.6666666666666856},{"time":104,"length":2.6666666666666856}]}],["Tetrahedron/distortAmp",{"items":[{"time":93.33333333333333},{"time":94.66666666666666,"length":1.3333333333333286,"curve":3,"offset":1.6666666666666856},{"time":104},{"time":105.33333333333333,"length":1.0000000000000142,"curve":8,"offset":0.26762905097568646,"speed":0.8028871529270708}]}],["NoiseVoxels/active",{"items":[{},{"time":90.66666666666666,"length":2.6666666666666856},{"time":101.33333333333333,"length":2.6666666666666856}]}],["NoiseVoxels/phase",{"items":[{"time":90.66666666666666,"length":1.3333333333333333,"curve":20},{"time":91.99999999999999,"length":1.3333333333333333,"curve":20,"amp":3},{"time":101.33333333333333,"length":1.3333333333333333,"curve":20},{"time":102.66666666666666,"length":1.3333333333333333,"curve":20,"amp":3}]}],["Camera/pos/x",{"items":[{},{"time":48,"value":0.029999999999999923},{"time":50.666666666666664,"value":0.22},{"time":53.333333333333336,"value":-0.3300000000000002},{"time":58.666666666666664,"value":0.030000000000000478},{"time":61.333333333333336,"value":0.4300000000000005},{"time":64,"value":-0.3099999999999998},{"time":66.66666666666666,"value":0.04000000000000473},{"time":69.33333333333333,"value":0.2500000000000004},{"time":71.99999999999999,"value":0.22},{"time":74.66666666666666,"value":0.18999999999999975},{"time":77.33333333333333,"value":-0.33000000000000024},{"time":79.99999999999999,"value":0.030000000000000478},{"time":82.66666666666666,"value":-0.32999999999999946},{"time":85.33333333333333,"value":6.349087922075114e-16},{"time":88},{"time":90.66666666666666},{"time":117.33333333333333,"value":0.2599999999999958},{"time":122.66666666666666,"value":-0.25000000000000006},{"time":128}]}],["Camera/pos/y",{"items":[{},{"time":48},{"time":53.333333333333336,"value":0.18999999999999986},{"time":58.666666666666664},{"time":69.33333333333333},{"time":74.66666666666666,"value":-0.2599999999999998},{"time":79.99999999999999},{"time":87.99999999999999},{"time":90.66666666666666},{"time":104},{"time":117.33333333333333,"value":0.009999999999995882},{"time":122.66666666666666},{"time":128},{"time":149.33333333333331,"value":1.3599999999999999}]}],["Camera/pos/z",{"items":[{},{"time":48},{"time":64,"value":-0.12999999999999998},{"time":66.66666666666666,"value":0.04000000000000473},{"time":69.33333333333333},{"time":85.33333333333333,"value":-0.019999999999999588},{"time":87.99999999999999},{"time":90.66666666666666}]}],["Camera/rot/r",{"items":[{},{"time":5.333333333333333,"length":4,"value":5,"curve":17,"amp":10},{"time":26.033333333333335,"length":4,"value":5,"curve":18,"amp":-2},{"time":42,"length":4,"value":3,"curve":18,"amp":4},{"time":48,"value":3.316984746376379},{"time":50.666666666666664,"value":4.160000000000001},{"time":53.33333333333333,"value":2.9236224967058},{"time":56,"value":4.760000000000006},{"time":58.666666666666664,"value":3.490000000000002},{"time":61.333333333333336,"value":3.289999999999999},{"time":64,"value":2.519999999999998},{"time":66.66666666666666,"value":5.050000000000004},{"time":69.33333333333333,"value":4.170000000000001},{"time":71.99999999999999,"value":4.399999999999997},{"time":74.66666666666666,"value":2.699999999999999},{"time":77.33333333333333,"value":5.470000000000008},{"time":79.99999999999999,"value":3.4499999999999997},{"time":82.66666666666666,"value":4.43},{"time":85.33333333333333,"value":2.9000000000000017},{"time":88,"value":4.900000000000005},{"time":89.33333333333331,"length":1.3333333333333428,"value":4.9,"curve":28,"speed":0.4999999999999974,"amp":4.4999999999999964},{"time":90.66666666666666,"length":1.3333333333333286,"value":6,"curve":17,"speed":3.000000000000011,"amp":5},{"time":91.99999999999999,"value":5.88},{"time":93.33333333333333,"length":1.3333333333333286,"value":6,"curve":17,"speed":3.000000000000011,"amp":5},{"time":94.66666666666666,"value":2.4699999999999975},{"time":96,"length":1.3333333333333286,"value":6,"curve":17,"speed":3.000000000000011,"amp":5},{"time":97.33333333333333,"value":7.749999999999996},{"time":98.66666666666666,"length":1.3333333333333286,"value":6,"curve":17,"speed":3.000000000000011,"amp":5},{"time":99.99999999999999,"value":5},{"time":101.33333333333333,"length":1.3333333333333286,"value":6,"curve":17,"speed":3.000000000000011,"amp":5},{"time":104,"length":1.3333333333333286,"value":6,"curve":17,"speed":3.000000000000011,"amp":5},{"time":105.33333333333333,"value":2.4699999999999984},{"time":106.66666666666666,"length":1.3333333333333286,"value":6,"curve":17,"speed":3.000000000000011,"amp":5},{"time":107.99999999999999,"value":7.589999999999998},{"time":109.33333333333333,"length":1.3333333333333286,"value":6,"curve":17,"speed":3.000000000000011,"amp":5},{"time":110.66666666666666,"value":6.369999999999991},{"time":111.33333333333333,"length":4,"value":6.369999999999991,"curve":18,"speed":1.0000000000000002,"amp":-2.5399999999999983},{"time":117.33333333333333,"value":2.939999999999995},{"time":121.33333333333333,"length":1.3333333333333286,"value":6.110000000000004,"curve":31,"amp":-0.99},{"time":122.66666666666666,"length":5.333333333333329,"value":3.4599999999999933,"curve":24,"speed":0.5000000000000013,"amp":-1.2000000000000026},{"time":127.99999999999999,"value":5.5899999999999945},{"time":130,"length":3.3333333333333144,"value":5.589999999999992,"curve":18,"speed":1.0000000000000002,"amp":-2},{"time":133.33333333333331,"value":2.6600000000000015},{"time":144,"value":2.05},{"time":149.33333333333331,"value":1.8299999999999976},{"time":152,"length":2,"value":1.8299999999999996,"curve":18,"speed":0.5,"amp":1.7899999999999974}]}],["Camera/rot/t",{"items":[{},{"time":26.666666666666664,"length":5.333333333333332,"curve":19,"speed":0.2499999999999999,"amp":0.30000000000000004},{"time":31.999999999999996,"length":5.333333333333332,"value":1.2000000000000002,"curve":19,"speed":0.2499999999999999,"amp":-0.9},{"time":37.333333333333336,"length":5.333333333333329,"value":-0.3,"curve":19,"speed":0.2499999999999999,"amp":0.30000000000000004},{"time":48,"value":0.12000000000000001},{"time":50.666666666666664,"value":-0.30999999999999495},{"time":53.333333333333336,"value":0.5200000000000048},{"time":56,"value":-0.029999999999995274},{"time":58.666666666666664,"value":0.2600000000000046},{"time":61.333333333333336,"value":-0.2899999999999953},{"time":64,"value":-0.06999999999999539},{"time":66.66666666666666,"value":0.2600000000000049},{"time":69.33333333333333,"value":0.12000000000000001},{"time":71.99999999999999,"value":0.7500000000000049},{"time":74.66666666666666,"value":-0.3599999999999952},{"time":77.33333333333333,"value":-1.1999999999999946},{"time":79.99999999999999,"value":0.2600000000000046},{"time":82.65764496093742,"value":-0.2899999999999953},{"time":85.33333333333333,"value":0.39000000000000457},{"time":87.99999999999999,"value":-0.029999999999995274},{"time":90.66666666666666},{"time":91.99999999999999,"value":0.5700000000000002},{"time":93.33333333333333},{"time":94.66666666666666,"value":0.10000000000000003},{"time":95.99999999999999},{"time":98.66666666666666},{"time":100,"value":-0.2799999999999997},{"time":101.33333333333333},{"time":102.66666666666666,"value":0.52},{"time":103.99999999999999},{"time":105.33333333333333,"value":-0.4100000000000001},{"time":106.66666666666666},{"time":108,"value":-0.1399999999999995},{"time":109.33333333333333},{"time":110.66666666666666,"value":0.14999999999999633},{"time":117.33333333333333,"value":0.5699999999999952},{"time":121.33333333333331,"length":1.3333333333333428,"value":0.37000000000000166,"curve":24,"speed":1.9999999999999891,"amp":-0.08000000000000007},{"time":122.66666666666666,"value":0.09999999999999977},{"time":128,"value":0.2},{"time":133.33333333333331,"value":0.4699999999999978},{"time":144,"value":-0.3700000000000031},{"time":149.33333333333331,"value":0.18000000000000063},{"time":151.86425044104683,"length":2.066666666666663,"value":0.18,"curve":18,"speed":0.5,"amp":-1.160000000000004}]}],["Camera/rot/p",{"items":[{},{"time":26.666666666666664,"length":5.333333333333332,"curve":19,"speed":0.2499999999999999,"amp":0.30000000000000004},{"time":32,"value":-2.3500000000000125},{"time":37.333333333333336,"length":5.333333333333329,"value":-0.3,"curve":19,"speed":0.2499999999999999,"amp":0.30000000000000004},{"time":48,"length":2.6666666666666643,"curve":24},{"time":50.666666666666664,"length":2.6666666666666714,"value":-0.9690196078431373,"curve":24},{"time":53.333333333333336,"length":2.6666666666666714,"value":-0.33999999999999997,"curve":24},{"time":56.00000000000001,"length":2.6666666666666714,"value":-0.39117647058823524,"curve":24},{"time":58.66666666666668,"length":2.6666666666666714,"value":-0.12117647058823516,"curve":24},{"time":61.33333333333335,"length":2.6666666666666714,"value":-1.4311764705882353,"curve":24},{"time":64.00000000000003,"length":2.6666666666666714,"value":-0.29117647058823515,"curve":24},{"time":66.66666666666669,"length":2.6666666666666714,"value":-0.7811764705882349,"curve":24},{"time":69.33333333333336,"length":2.6666666666666643,"curve":24},{"time":72.00000000000001,"length":2.6666666666666714,"value":-0.9690196078431373,"curve":24},{"time":74.66666666666669,"length":2.6666666666666714,"value":-0.51,"curve":24},{"time":77.33333333333336,"length":2.6666666666666714,"value":-0.5111764705882352,"curve":24},{"time":80.00000000000003,"length":2.6666666666666714,"value":-0.6411764705882351,"curve":24},{"time":82.6666666666667,"length":2.6666666666666714,"value":-1.3611764705882354,"curve":24},{"time":85.33333333333337,"length":2.6666666666666714,"value":-0.4911764705882345,"curve":24},{"time":88.00000000000004,"length":1.3333333333333286,"value":-1.5411764705882351,"curve":24},{"time":89.33333333333337,"length":1.333333333333286,"value":-1.016,"curve":28,"speed":0.5000000000000079,"amp":3},{"time":90.66666666666666},{"time":91.99999999999999,"length":1.3333333333333428,"curve":20,"amp":6},{"time":93.33333333333333},{"time":94.66666666666664,"length":1.3333333333333428,"curve":20,"amp":0.21000000000000407},{"time":95.99999999999999},{"time":97.33333333333331,"length":1.3333333333333428,"curve":20,"amp":6},{"time":98.66666666666666},{"time":100,"length":1.3333333333333286,"value":-0.51,"curve":20,"amp":0.6200000000000041},{"time":101.33333333333333},{"time":102.66666666666666,"length":1.3333333333333428,"value":-1.0699999999999998,"curve":20,"amp":6},{"time":104},{"time":105.33333333333331,"length":1.3333333333333428,"value":7.999999999999989,"curve":20,"amp":-0.582999999999996},{"time":106.66666666666666},{"time":107.99999999999999,"length":1.3333333333333428,"curve":20,"amp":6},{"time":109.33333333333333},{"time":110.66666666666666,"value":0.56},{"time":112,"length":5.333333333333329,"value":0.56,"curve":24,"speed":0.5000000000000013,"amp":-1.0400000000000003},{"time":117.33333333333333,"length":3.999999999999986,"value":0.6199999999999997,"curve":24,"speed":0.5000000000000012,"amp":-1.0400000000000003},{"time":121.33333333333331,"length":1.3333333333333428,"value":-0.3799999999999981,"curve":24,"speed":1.9999999999999891,"amp":0.56},{"time":122.66666666666666,"length":5.333333333333329,"value":0.37000000000000166,"curve":24,"speed":0.5000000000000013,"amp":-0.7100000000000002},{"time":127.99999999999999,"length":2.6666666666666714,"value":-0.71,"curve":24,"speed":0.9999999999999998,"amp":0.71},{"time":133.33333333333331,"length":10.666666666666686,"curve":20,"speed":0.12499999999999978,"amp":-14.000000000000476},{"time":144,"length":10.666666666666657,"curve":20,"speed":0.1093749999999997,"amp":-14.000000000000476}]}],["Camera/roll",{"items":[{"time":5.333333333333334,"length":21.333333333333332,"value":-0.2500000000000003,"curve":21,"speed":0.1875},{"time":32,"value":-1.190000000000011},{"time":37.33333333333333,"length":5.333333333333329,"value":-0.3,"curve":19,"speed":0.2499999999999999,"amp":0.30000000000000004},{"time":48},{"time":53.333333333333336,"value":0.25},{"time":56},{"time":58.666666666666664,"value":-0.14},{"time":61.333333333333336,"value":-0.460000000000002},{"time":64},{"time":66.66666666666666},{"time":69.33333333333333,"value":0.54},{"time":71.99999999999999,"value":0.15},{"time":74.66666666666666,"value":-0.25},{"time":77.33333333333333,"value":0.5000000000000004},{"time":79.99999999999999,"value":0.33000000000000007},{"time":82.66666666666666,"value":0.23000000000000007},{"time":85.33333333333333,"value":2.380000000000001},{"time":88},{"time":89.33333333333331,"length":1.3333333333333428,"curve":28,"speed":0.4999999999999974,"amp":3},{"time":90.66666666666666},{"time":94.66666666666666,"value":0.06999999999999995},{"time":96},{"time":101.33333333333333},{"time":102.66666666666666,"value":-0.26000000000000006},{"time":104.00158889323498},{"time":105.33333333333333,"value":0.2599999999999987},{"time":106.66666666666666},{"time":108,"value":-0.33000000000000124},{"time":109.33333333333333},{"time":112,"length":5.333333333333329,"curve":24,"speed":0.5000000000000013,"amp":-0.2700000000000004},{"time":117.33333333333333,"value":0.32999999999999585},{"time":121.33333333333333,"value":-0.10000000000000413},{"time":122.66666666666666,"length":5.333333333333329,"value":0.10999999999999989,"curve":24,"speed":0.5000000000000013,"amp":0.049999999999999524},{"time":127.99999999999999},{"time":133.33333333333331,"value":0.4699999999999978},{"time":144,"value":-0.3300000000000022}]}],["Rings/begin",{"items":[{},{"time":110.66666666666666,"length":1.3333333333333428,"curve":20}]}],["Camera/shake",{"items":[{},{"time":48,"length":1,"curve":27},{"time":50.666666666666664,"length":1,"curve":27},{"time":53.333333333333336,"length":1,"curve":27},{"time":56,"length":1,"curve":27},{"time":58.666666666666664,"length":1,"curve":27},{"time":61.333333333333336,"length":1,"curve":27},{"time":64,"length":1,"curve":27},{"time":66.66666666666666,"length":1,"curve":27},{"time":69.33333333333333,"length":1,"curve":27},{"time":71.99999999999999,"length":1,"curve":27},{"time":74.66666666666666,"length":1,"curve":27},{"time":77.33333333333333,"length":1,"curve":27},{"time":79.99999999999999,"length":1,"curve":27},{"time":82.66666666666666,"length":1,"curve":27},{"time":85.33333333333333,"length":1,"curve":27},{"time":88,"length":1,"curve":27},{"time":121.33333333333333,"length":1.3333333333333286,"value":0.01999999999999999,"reset":true},{"time":149.33333333333331,"length":4,"curve":33,"amp":0.020000000000000004},{"time":153.33333333333331,"length":1.3333333333333428,"curve":34,"amp":0.5499999999999999}]}],["Camera/fov",{"items":[{"value":0.5},{"time":48,"value":0.8},{"time":90.66666666666666,"value":0.5},{"time":110.66666666666666,"value":0.8},{"time":152.1,"length":2.066666666666663,"value":0.8,"curve":18,"speed":0.5,"amp":0.3599999999999957}]}],["DVi/amp",{"items":[{},{"time":112,"length":1.3333333333333286,"curve":31},{"time":149.33333333333331}]}],["DVi/offset",{"items":[{"time":112,"length":2.6666666666666856,"curve":31,"speed":0.4999999999999947,"amp":19.999999999999993}]}],["Post/colorPreset",{"items":[{},{"time":48,"value":1},{"time":112,"value":2}]}],["Greetings/active",{"items":[{},{"time":133.33333333333331,"length":16}]}],["Post/mixInvert",{"items":[{},{"time":121.33333333333333,"length":1.3333333333333286,"value":1,"reset":true}]}],["Phantom/active",{"items":[{},{"time":111.33333333333333,"length":42.66666666666667}]}],["Crystal/beam/charge",{"items":[{},{"time":149.33333333333331,"length":4,"curve":35,"amp":0.36000000000000004},{"time":153.33333333333331,"length":1.3333333333333428,"curve":34,"amp":0.9599999999999995}]}],["Crystal/beam/shot",{"items":[{},{"time":153.33333333333331,"length":1.3333333333333428,"curve":34,"amp":0.9599999999999995}]}],["Crystal/beam/ring",{"items":[{},{"time":152,"length":2.666666666666657,"curve":36,"speed":0.7614331254621488,"amp":10.469999999999992}]}],["Post/mosaicAmp",{"items":[{},{"time":117.33333333333333,"length":2.666666666666657,"curve":37,"speed":0.7614331254621488,"amp":0.07},{"time":121.33333333333333,"length":1.3333333333333286,"curve":37,"speed":0.7614331254621488,"amp":0.07},{"time":122.66666666666666,"length":2.666666666666657,"curve":37,"speed":0.7614331254621488,"amp":0.07},{"time":128,"length":2.666666666666657,"curve":37,"speed":0.7614331254621488,"amp":0.07},{"time":133.33333333333331,"length":2.666666666666657,"curve":37,"speed":0.7614331254621488,"amp":0.07},{"time":144,"length":2.666666666666657,"curve":37,"speed":0.7614331254621488,"amp":0.07},{"time":149.33333333333331,"length":2.666666666666657,"curve":37,"speed":0.7614331254621488,"amp":0.07}]}],["IFSAsUsual/distortAmp",{"items":[]}]],"labels":{"zero":0,"begin":5.333333333333333,"neuro":48,"porterfuckingrobinson":112,"fuckingcamellia":90.66666666666666,"psy":154.66666666666666,"greetings":133.33333333333331},"guiSettings":{"snapTimeActive":true,"snapTimeInterval":0.1,"snapValueActive":true,"snapValueInterval":0.5,"snapBeatActive":true,"bpm":180,"beatOffset":0,"useBeatInGUI":true,"minimizedPrecisionTime":3,"minimizedPrecisionValue":3}} \ No newline at end of file diff --git a/src/config-hot.ts b/src/config-hot.ts index db2d33e..14564fc 100644 --- a/src/config-hot.ts +++ b/src/config-hot.ts @@ -5,8 +5,10 @@ export const // RTINSPECTOR_CAPTURE_NAME: string | null = 'PixelSorter/index', // RTINSPECTOR_CAPTURE_NAME: string | null = 'Greetings/intermediate0', // RTINSPECTOR_CAPTURE_NAME: string | null = 'main/postSwap0', + // RTINSPECTOR_CAPTURE_NAME: string | null = 'EnvironmentMap/swap0', // RTINSPECTOR_CAPTURE_NAME: string | null = 'DeferredCamera/cameraTarget', RTINSPECTOR_CAPTURE_INDEX = 0, COMPONENT_UPDATE_BREAKPOINT: string | null = null, // COMPONENT_UPDATE_BREAKPOINT: string | null = 'ForwardCamera/camera', + // COMPONENT_UPDATE_BREAKPOINT: string | null = 'lightDynamic1/shadowMapCamera', COMPONENT_DRAW_BREAKPOINT: string | null = null; diff --git a/src/entities/Crystal.ts b/src/entities/Crystal.ts index e6b380f..fb4ab26 100644 --- a/src/entities/Crystal.ts +++ b/src/entities/Crystal.ts @@ -8,10 +8,9 @@ import { Material } from '../heck/Material'; import { Mesh, MeshCull } from '../heck/components/Mesh'; import { Vector3 } from '@fms-cat/experimental'; import { auto } from '../globals/automaton'; -import { dummyRenderTarget, dummyRenderTargetFourDrawBuffers } from '../globals/dummyRenderTarget'; +import { dummyRenderTargetFourDrawBuffers } from '../globals/dummyRenderTarget'; import { genCube } from '../geometries/genCube'; import { objectValuesMap } from '../utils/objectEntriesMap'; -import { randomTexture, randomTextureStatic } from '../globals/randomTexture'; import crystalFrag from '../shaders/crystal.frag'; import raymarchObjectVert from '../shaders/raymarch-object.vert'; @@ -50,22 +49,23 @@ export class Crystal extends Entity { }, ); - const depth = new Material( - raymarchObjectVert, - crystalFrag, - { - defines: [ 'SHADOW 1' ], - initOptions: { geometry, target: dummyRenderTarget } - }, - ); + // I don't think we need this + // const depth = new Material( + // raymarchObjectVert, + // crystalFrag, + // { + // defines: [ 'DEPTH 1' ], + // initOptions: { geometry, target: dummyRenderTarget } + // }, + // ); - const materials = { deferred, depth }; + const materials = { deferred }; if ( process.env.DEV ) { if ( module.hot ) { module.hot.accept( '../shaders/crystal.frag', () => { deferred.replaceShader( raymarchObjectVert, crystalFrag ); - depth.replaceShader( raymarchObjectVert, crystalFrag ); + // depth.replaceShader( raymarchObjectVert, crystalFrag ); } ); } } @@ -73,9 +73,6 @@ export class Crystal extends Entity { objectValuesMap( materials, ( material ) => { material.addUniform( 'size', '2f', width, height ); material.addUniform( 'noiseOffset', '1f', noiseOffset ); - - material.addUniformTexture( 'samplerRandom', randomTexture.texture ); - material.addUniformTexture( 'samplerRandomStatic', randomTextureStatic.texture ); } ); // -- updater ---------------------------------------------------------------------------------- @@ -98,10 +95,6 @@ export class Crystal extends Entity { .inverse! .elements ); - - material.addUniform( 'deformAmp', '1f', auto( 'Music/NEURO_WUB_AMP' ) ); - material.addUniform( 'deformFreq', '1f', auto( 'Music/NEURO_WUB_FREQ' ) + auto( 'Music/NEURO_DETUNE' ) ); - material.addUniform( 'deformTime', '1f', auto( 'Music/NEURO_TIME' ) ); } ); }, name: process.env.DEV && 'Crystal/updater', diff --git a/src/entities/Cube.ts b/src/entities/Cube.ts index c2310b0..ef6759d 100644 --- a/src/entities/Cube.ts +++ b/src/entities/Cube.ts @@ -30,7 +30,6 @@ export class Cube extends Entity { 0.4, ) ); - this.transform.position = new Vector3( [ 0.0, 0.0, 0.0 ] ); this.transform.rotation = rot0; this.transform.scale = this.transform.scale.scale( 0.3 ); diff --git a/src/entities/CyclicBoard.ts b/src/entities/CyclicBoard.ts new file mode 100644 index 0000000..3f482e8 --- /dev/null +++ b/src/entities/CyclicBoard.ts @@ -0,0 +1,119 @@ +import { Entity } from '../heck/Entity'; +import { Geometry } from '../heck/Geometry'; +import { Lambda } from '../heck/components/Lambda'; +import { LightEntity } from './LightEntity'; +import { Material } from '../heck/Material'; +import { Mesh, MeshCull } from '../heck/components/Mesh'; +import { Vector3 } from '@fms-cat/experimental'; +import { dummyRenderTarget, dummyRenderTargetFourDrawBuffers } from '../globals/dummyRenderTarget'; +import { genCube } from '../geometries/genCube'; +import { objectValuesMap } from '../utils/objectEntriesMap'; +import { setLightUniforms } from '../utils/setLightUniforms'; +import cyclicBoardFrag from '../shaders/cyclic-board.frag'; +import raymarchObjectVert from '../shaders/raymarch-object.vert'; + +export class CyclicBoard extends Entity { + public lights: LightEntity[] = []; + + public constructor() { + super(); + + this.transform.position = new Vector3( [ 0.0, 0.0, 0.0 ] ); + this.transform.scale = new Vector3( [ 1.0, 1.0, 1.0 ] ); + + // -- geometry --------------------------------------------------------------------------------- + const cube = genCube( { dimension: [ 100.0, 1.0, 100.0 ] } ); + + const geometry = new Geometry(); + + geometry.vao.bindVertexbuffer( cube.position, 0, 3 ); + geometry.vao.bindIndexbuffer( cube.index ); + + geometry.count = cube.count; + geometry.mode = cube.mode; + geometry.indexType = cube.indexType; + + // -- materials -------------------------------------------------------------------------------- + const forward = new Material( + raymarchObjectVert, + cyclicBoardFrag, + { + defines: [ 'FORWARD 1' ], + initOptions: { geometry, target: dummyRenderTarget }, + }, + ); + + const deferred = new Material( + raymarchObjectVert, + cyclicBoardFrag, + { + defines: [ 'DEFERRED 1' ], + initOptions: { geometry, target: dummyRenderTargetFourDrawBuffers }, + }, + ); + + // it was way too expensive,,, + // const depth = new Material( + // raymarchObjectVert, + // cyclicBoardFrag, + // { + // defines: [ 'DEPTH 1' ], + // initOptions: { geometry, target: dummyRenderTarget } + // }, + // ); + + const materials = { cubemap: forward, deferred }; + + if ( process.env.DEV ) { + if ( module.hot ) { + module.hot.accept( '../shaders/cyclic-board.frag', () => { + forward.replaceShader( raymarchObjectVert, cyclicBoardFrag ); + deferred.replaceShader( raymarchObjectVert, cyclicBoardFrag ); + // depth.replaceShader( raymarchObjectVert, cyclicBoardFrag ); + } ); + } + } + + // -- forward lights --------------------------------------------------------------------------- + this.components.push( new Lambda( { + onDraw: ( { frameCount } ) => { + setLightUniforms( forward, this.lights, frameCount ); + }, + name: process.env.DEV && 'CyclicBoard/setLightUniforms', + } ) ); + + // -- updater ---------------------------------------------------------------------------------- + this.components.push( new Lambda( { + onDraw: ( event ) => { + objectValuesMap( materials, ( material ) => { + material.addUniform( + 'cameraNearFar', + '2f', + event.camera.near, + event.camera.far + ); + + material.addUniformMatrixVector( + 'inversePVM', + 'Matrix4fv', + event.projectionMatrix + .multiply( event.viewMatrix ) + .multiply( event.globalTransform.matrix ) + .inverse! + .elements + ); + } ); + }, + name: process.env.DEV && 'CyclicBoard/updater', + } ) ); + + // -- mesh ------------------------------------------------------------------------------------- + const mesh = new Mesh( { + geometry, + materials, + name: process.env.DEV && 'CyclicBoard/mesh', + } ); + mesh.cull = MeshCull.None; + this.components.push( mesh ); + } +} diff --git a/src/entities/DeferredCamera.ts b/src/entities/DeferredCamera.ts index acf6aad..0ca6827 100644 --- a/src/entities/DeferredCamera.ts +++ b/src/entities/DeferredCamera.ts @@ -12,6 +12,7 @@ import { dummyRenderTarget } from '../globals/dummyRenderTarget'; import { gl } from '../globals/canvas'; import { quadGeometry } from '../globals/quadGeometry'; import { randomTexture } from '../globals/randomTexture'; +import { setLightUniforms } from '../utils/setLightUniforms'; import aoFrag from '../shaders/ao.frag'; import quadVert from '../shaders/quad.vert'; import shadingFrag from '../shaders/shading.frag'; @@ -111,18 +112,8 @@ export class DeferredCamera extends Entity { const lambda = new Lambda( { onUpdate: ( { frameCount } ) => { - const lights = options.lights.filter( ( light ) => ( - frameCount === light.lastUpdateFrame - ) ); - const cameraView = this.transform.matrix.inverse!; - shadingMaterial.addUniform( - 'lightCount', - '1i', - lights.length, - ); - shadingMaterial.addUniformMatrixVector( 'cameraView', 'Matrix4fv', @@ -150,44 +141,7 @@ export class DeferredCamera extends Entity { ...this.transform.position.elements ); - shadingMaterial.addUniformVector( - 'lightNearFar', - '2fv', - lights.map( ( light ) => [ light.camera.near, light.camera.far ] ).flat(), - ); - - shadingMaterial.addUniformVector( - 'lightPos', - '3fv', - lights.map( ( light ) => light.globalTransformCache.position.elements ).flat(), - ); - - shadingMaterial.addUniformVector( - 'lightColor', - '3fv', - lights.map( ( light ) => light.color ).flat(), - ); - - shadingMaterial.addUniformVector( - 'lightParams', - '4fv', - lights.map( ( light ) => [ light.spotness, 0.0, 0.0, 0.0 ] ).flat(), - ); - - shadingMaterial.addUniformMatrixVector( - 'lightPV', - 'Matrix4fv', - lights.map( ( light ) => ( - light.camera.projectionMatrix.multiply( - light.globalTransformCache.matrix.inverse! - ).elements - ) ).flat(), - ); - - shadingMaterial.addUniformTextureArray( - 'samplerShadow', - lights.map( ( light ) => light.shadowMap.texture ), - ); + setLightUniforms( shadingMaterial, options.lights, frameCount ); }, name: process.env.DEV && 'DeferredCamera/shading/setCameraUniforms', } ); diff --git a/src/entities/FlashyBall.ts b/src/entities/FlashyBall.ts new file mode 100644 index 0000000..e1d483d --- /dev/null +++ b/src/entities/FlashyBall.ts @@ -0,0 +1,92 @@ +import { Entity } from '../heck/Entity'; +import { Geometry } from '../heck/Geometry'; +import { Lambda } from '../heck/components/Lambda'; +import { Material } from '../heck/Material'; +import { Mesh } from '../heck/components/Mesh'; +import { Quaternion, Vector3 } from '@fms-cat/experimental'; +import { auto } from '../globals/automaton'; +import { dummyRenderTarget, dummyRenderTargetFourDrawBuffers } from '../globals/dummyRenderTarget'; +import { genOctahedron } from '../geometries/genOctahedron'; +import { objectValuesMap } from '../utils/objectEntriesMap'; +import { quadGeometry } from '../globals/quadGeometry'; +import depthFrag from '../shaders/depth.frag'; +import flashyBallFrag from '../shaders/flashy-ball.frag'; +import flashyBallVert from '../shaders/flashy-ball.vert'; + +export class FlashyBall extends Entity { + public mesh: Mesh; + + public constructor() { + super(); + + // -- geometry --------------------------------------------------------------------------------- + const octahedron = genOctahedron( { div: 5 } ); + + const geometry = new Geometry(); + + geometry.vao.bindVertexbuffer( octahedron.position, 0, 3 ); + geometry.vao.bindVertexbuffer( octahedron.normal, 1, 3 ); + geometry.vao.bindIndexbuffer( octahedron.index ); + + geometry.count = octahedron.count; + geometry.mode = octahedron.mode; + geometry.indexType = octahedron.indexType; + + // -- materials -------------------------------------------------------------------------------- + const deferred = new Material( + flashyBallVert, + flashyBallFrag, + { + defines: [ 'DEFERRED 1' ], + initOptions: { geometry: quadGeometry, target: dummyRenderTargetFourDrawBuffers }, + }, + ); + + const depth = new Material( + flashyBallVert, + depthFrag, + { initOptions: { geometry: quadGeometry, target: dummyRenderTarget } }, + ); + + const materials = { deferred, depth }; + + if ( process.env.DEV ) { + if ( module.hot ) { + module.hot.accept( + [ + '../shaders/flashy-ball.vert', + '../shaders/flashy-ball.frag', + ], + () => { + deferred.replaceShader( flashyBallVert, flashyBallFrag ); + depth.replaceShader( flashyBallVert, depthFrag ); + }, + ); + } + } + + // -- mesh ------------------------------------------------------------------------------------- + this.mesh = new Mesh( { + geometry, + materials, + name: process.env.DEV && 'FlashyBall/mesh', + } ); + this.components.push( this.mesh ); + + // -- speen ------------------------------------------------------------------------------------ + const axis = new Vector3( [ 1.0, -1.0, 1.0 ] ).normalized; + this.components.push( new Lambda( { + onUpdate: ( { time } ) => { + this.transform.rotation = Quaternion.fromAxisAngle( axis, time ); + objectValuesMap( materials, ( material ) => { + material.addUniform( + 'distort', + '1f', + auto( 'FlashyBall/distortAmp' ) + ); + } ); + }, + name: process.env.DEV && 'FlashyBall/update', + } ) ); + } +} diff --git a/src/entities/Greetings.ts b/src/entities/Greetings.ts index af3644e..eef3436 100644 --- a/src/entities/Greetings.ts +++ b/src/entities/Greetings.ts @@ -66,7 +66,7 @@ const styles = [ }, { font: '96px Arial', - spacing: 2.0, + spacing: 1.3, }, { font: 'Bold 96px Arial', @@ -89,7 +89,8 @@ const styles = [ }, { font: 'Bold 96px Arial', - spacing: 1.5, + scaleY: 1.2, + spacing: 1.4, }, { font: 'Bold 96px Arial', @@ -157,30 +158,40 @@ const charPosList = [ '0x4015', 'Alcatraz', 'Altair', + 'ASD', 'Astronomena', 'CNCD', 'Cocoon', 'Conspiracy', + 'Ctrl+Alt+Test', + 'doxas', 'Fairlight', 'Flopine', 'FRONTL1NE', 'holon', 'gam0022', + 'gaz', 'jetlag', 'Jugem-T', 'kaneta', 'Limp Ninja', 'LJ', 'Logicoma', + 'marcan', 'Mercury', + 'mrdoob', 'nikq::cube', 'Ninjadev', 'NuSan', + 'orange', 'Poo-Brain', + 'Primitive', 'Prismbeings', 'Radium Software', + 'quite', 'rgba', 'Satori', + 'setchi', 'sp4ghet', 'Still', 'Suricrasia Online', @@ -281,7 +292,7 @@ export class Greetings extends Entity { const lambda = new Lambda( { onUpdate: ( { time, deltaTime } ) => { - if ( Math.floor( 6.0 * time ) === Math.floor( 6.0 * ( time - deltaTime ) ) ) { + if ( Math.floor( 8.0 * time ) === Math.floor( 8.0 * ( time - deltaTime ) ) ) { return; } diff --git a/src/entities/IFSAsUsual.ts b/src/entities/IFSAsUsual.ts new file mode 100644 index 0000000..461f397 --- /dev/null +++ b/src/entities/IFSAsUsual.ts @@ -0,0 +1,112 @@ +import { Entity } from '../heck/Entity'; +import { Geometry } from '../heck/Geometry'; +import { Lambda } from '../heck/components/Lambda'; +import { Material } from '../heck/Material'; +import { Mesh, MeshCull } from '../heck/components/Mesh'; +import { Quaternion, Vector3 } from '@fms-cat/experimental'; +import { auto } from '../globals/automaton'; +import { dummyRenderTarget, dummyRenderTargetFourDrawBuffers } from '../globals/dummyRenderTarget'; +import { genCube } from '../geometries/genCube'; +import { objectValuesMap } from '../utils/objectEntriesMap'; +import { randomTexture, randomTextureStatic } from '../globals/randomTexture'; +import ifsAsUsualFrag from '../shaders/ifs-as-usual.frag'; +import raymarchObjectVert from '../shaders/raymarch-object.vert'; + +export class IFSAsUsual extends Entity { + public constructor() { + super(); + + // -- geometry --------------------------------------------------------------------------------- + const cube = genCube( { dimension: [ 1.1, 1.1, 1.1 ] } ); + + const geometry = new Geometry(); + + geometry.vao.bindVertexbuffer( cube.position, 0, 3 ); + geometry.vao.bindIndexbuffer( cube.index ); + + geometry.count = cube.count; + geometry.mode = cube.mode; + geometry.indexType = cube.indexType; + + // -- materials -------------------------------------------------------------------------------- + const deferred = new Material( + raymarchObjectVert, + ifsAsUsualFrag, + { + defines: [ 'DEFERRED 1' ], + initOptions: { geometry, target: dummyRenderTargetFourDrawBuffers }, + }, + ); + + const depth = new Material( + raymarchObjectVert, + ifsAsUsualFrag, + { + defines: [ 'DEPTH 1' ], + initOptions: { geometry, target: dummyRenderTarget } + }, + ); + + const materials = { deferred, depth }; + + if ( process.env.DEV ) { + if ( module.hot ) { + module.hot.accept( '../shaders/ifs-as-usual.frag', () => { + deferred.replaceShader( raymarchObjectVert, ifsAsUsualFrag ); + depth.replaceShader( raymarchObjectVert, ifsAsUsualFrag ); + } ); + } + } + + objectValuesMap( materials, ( material ) => { + material.addUniformTexture( 'samplerRandom', randomTexture.texture ); + material.addUniformTexture( 'samplerRandomStatic', randomTextureStatic.texture ); + } ); + + // -- updater ---------------------------------------------------------------------------------- + this.components.push( new Lambda( { + onDraw: ( event ) => { + objectValuesMap( materials, ( material ) => { + material.addUniform( + 'cameraNearFar', + '2f', + event.camera.near, + event.camera.far + ); + + material.addUniformMatrixVector( + 'inversePVM', + 'Matrix4fv', + event.projectionMatrix + .multiply( event.viewMatrix ) + .multiply( event.globalTransform.matrix ) + .inverse! + .elements + ); + } ); + }, + name: process.env.DEV && 'IFSAsUsual/updater', + } ) ); + + // -- mesh ------------------------------------------------------------------------------------- + const mesh = new Mesh( { + geometry, + materials, + name: process.env.DEV && 'IFSAsUsual/mesh', + } ); + mesh.cull = MeshCull.None; + this.components.push( mesh ); + + // -- speen ------------------------------------------------------------------------------------ + const axis = new Vector3( [ 1.0, -1.0, 1.0 ] ).normalized; + this.components.push( new Lambda( { + onUpdate: ( { time } ) => { + this.transform.rotation = Quaternion.fromAxisAngle( axis, time ); + objectValuesMap( materials, ( material ) => { + material.addUniform( 'ifsSeed', '1f', auto( 'IFSAsUsual/ifsSeed' ) ); + } ); + }, + name: process.env.DEV && 'IFSAsUsual/update', + } ) ); + } +} diff --git a/src/entities/IFSPistons.ts b/src/entities/IFSPistons.ts index da43366..961b2a0 100644 --- a/src/entities/IFSPistons.ts +++ b/src/entities/IFSPistons.ts @@ -41,7 +41,7 @@ export class IFSPistons extends Entity { raymarchObjectVert, ifsPistonFrag, { - defines: [ 'SHADOW 1' ], + defines: [ 'DEPTH 1' ], initOptions: { geometry, target: dummyRenderTarget } }, ); diff --git a/src/entities/LightCube.ts b/src/entities/LightCube.ts new file mode 100644 index 0000000..0280683 --- /dev/null +++ b/src/entities/LightCube.ts @@ -0,0 +1,61 @@ +import { Entity } from '../heck/Entity'; +import { Geometry } from '../heck/Geometry'; +import { Lambda } from '../heck/components/Lambda'; +import { Material } from '../heck/Material'; +import { Mesh } from '../heck/components/Mesh'; +import { dummyRenderTarget } from '../globals/dummyRenderTarget'; +import { genCube } from '../geometries/genCube'; +import { gl } from '../globals/canvas'; +import colorFrag from '../shaders/color.frag'; +import objectVert from '../shaders/object.vert'; + +export class LightCube extends Entity { + public mesh: Mesh; + public color = [ 1.0, 1.0, 1.0 ]; + private __forward: Material; + + public constructor() { + super(); + + // -- geometry --------------------------------------------------------------------------------- + const cube = genCube( { dimension: [ 1.0, 1.0, 1.0 ] } ); + + const geometry = new Geometry(); + + geometry.vao.bindVertexbuffer( cube.position, 0, 3 ); + geometry.vao.bindVertexbuffer( cube.normal, 1, 3 ); + geometry.vao.bindIndexbuffer( cube.index ); + + geometry.count = cube.count; + geometry.mode = cube.mode; + geometry.indexType = cube.indexType; + + // -- materials -------------------------------------------------------------------------------- + const forward = this.__forward = new Material( + objectVert, + colorFrag, + { + blend: [ gl.ONE, gl.ONE ], + initOptions: { geometry, target: dummyRenderTarget }, + }, + ); + + const materials = { forward, cubemap: forward }; + + // -- updater ---------------------------------------------------------------------------------- + this.components.push( new Lambda( { + onUpdate: () => { + this.__forward.addUniform( 'color', '4f', ...this.color, 1.0 ); + }, + name: 'LightBar/updater', + } ) ); + + // -- mesh ------------------------------------------------------------------------------------- + this.mesh = new Mesh( { + geometry, + materials, + name: process.env.DEV && 'LightBar/mesh', + } ); + this.components.push( this.mesh ); + } +} diff --git a/src/entities/NoiseVoxels.ts b/src/entities/NoiseVoxels.ts new file mode 100644 index 0000000..9e0b4d0 --- /dev/null +++ b/src/entities/NoiseVoxels.ts @@ -0,0 +1,108 @@ +import { Entity } from '../heck/Entity'; +import { InstancedGeometry } from '../heck/InstancedGeometry'; +import { Lambda } from '../heck/components/Lambda'; +import { Material } from '../heck/Material'; +import { Mesh } from '../heck/components/Mesh'; +import { Quaternion, Vector3, matrix3d } from '@fms-cat/experimental'; +import { auto } from '../globals/automaton'; +import { dummyRenderTarget, dummyRenderTargetFourDrawBuffers } from '../globals/dummyRenderTarget'; +import { genCube } from '../geometries/genCube'; +import { glCat } from '../globals/canvas'; +import { objectValuesMap } from '../utils/objectEntriesMap'; +import { quadGeometry } from '../globals/quadGeometry'; +import depthFrag from '../shaders/depth.frag'; +import noiseVoxelsFrag from '../shaders/noise-voxels.frag'; +import noiseVoxelsVert from '../shaders/noise-voxels.vert'; + +const CUBE_PER_AXIS = 8; +const PRIMCOUNT = CUBE_PER_AXIS * CUBE_PER_AXIS * CUBE_PER_AXIS; + +export class NoiseVoxels extends Entity { + public mesh: Mesh; + + public constructor() { + super(); + + this.transform.scale = Vector3.one.scale( 0.7 ); + + // -- updater ---------------------------------------------------------------------------------- + this.components.push( new Lambda( { + onUpdate: ( { time } ) => { + this.transform.rotation = Quaternion.fromAxisAngle( + new Vector3( [ 1.0, 0.5, -2.0 ] ).normalized, + 0.4 * time, + ).multiply( Quaternion.fromAxisAngle( + new Vector3( [ 0.0, 1.0, 0.2 ] ).normalized, + time, + ) ); + }, + } ) ); + + // -- geometry --------------------------------------------------------------------------------- + const cube = genCube(); + + const geometry = new InstancedGeometry(); + + geometry.vao.bindVertexbuffer( cube.position, 0, 3 ); + geometry.vao.bindVertexbuffer( cube.normal, 1, 3 ); + geometry.vao.bindIndexbuffer( cube.index ); + + const arrayInstancePos = matrix3d( CUBE_PER_AXIS, CUBE_PER_AXIS, CUBE_PER_AXIS ); + const bufferInstancePos = glCat.createBuffer(); + bufferInstancePos.setVertexbuffer( new Float32Array( arrayInstancePos ) ); + geometry.vao.bindVertexbuffer( bufferInstancePos, 2, 3, 1 ); + + geometry.count = cube.count; + geometry.mode = cube.mode; + geometry.indexType = cube.indexType; + geometry.primcount = PRIMCOUNT; + + // -- materials -------------------------------------------------------------------------------- + const deferred = new Material( + noiseVoxelsVert, + noiseVoxelsFrag, + { + defines: [ 'DEFERRED 1' ], + initOptions: { geometry: quadGeometry, target: dummyRenderTargetFourDrawBuffers }, + }, + ); + + const depth = new Material( + noiseVoxelsVert, + depthFrag, + { initOptions: { geometry: quadGeometry, target: dummyRenderTarget } }, + ); + + const materials = { deferred, depth }; + + if ( process.env.DEV ) { + if ( module.hot ) { + module.hot.accept( + [ + '../shaders/noise-voxels.vert', + '../shaders/noise-voxels.frag', + ], + () => { + deferred.replaceShader( noiseVoxelsVert, noiseVoxelsFrag ); + depth.replaceShader( noiseVoxelsVert, depthFrag ); + }, + ); + } + } + + // -- auto ------------------------------------------------------------------------------------- + auto( 'NoiseVoxels/phase', ( { value } ) => { + objectValuesMap( materials, ( material ) => { + material.addUniform( 'phase', '1f', value ); + } ); + } ); + + // -- mesh ------------------------------------------------------------------------------------- + this.mesh = new Mesh( { + geometry: geometry, + materials, + name: process.env.DEV && 'NoiseVoxels/mesh', + } ); + this.components.push( this.mesh ); + } +} diff --git a/src/entities/Phantom.ts b/src/entities/Phantom.ts index d900e79..bceb7da 100644 --- a/src/entities/Phantom.ts +++ b/src/entities/Phantom.ts @@ -3,13 +3,13 @@ import { Entity } from '../heck/Entity'; import { Lambda } from '../heck/components/Lambda'; import { Material } from '../heck/Material'; import { Mesh } from '../heck/components/Mesh'; +import { auto } from '../globals/automaton'; import { dummyRenderTarget } from '../globals/dummyRenderTarget'; import { gl } from '../globals/canvas'; import { quadGeometry } from '../globals/quadGeometry'; import { randomTexture } from '../globals/randomTexture'; import phantomFrag from '../shaders/phantom.frag'; import quadVert from '../shaders/quad.vert'; -import { auto } from '../globals/automaton'; export class Phantom extends Entity { private __forward: Material; @@ -65,9 +65,11 @@ export class Phantom extends Entity { this.components.push( mesh ); // -- auto ------------------------------------------------------------------------------------- - auto( 'Phantom/active', ( { uninit } ) => { - mesh.active = !uninit; - mesh.visible = !uninit; + auto( 'Phantom/amp', ( { value } ) => { + forward.addUniform( 'amp', '1f', value ); + + mesh.active = value > 0.0; + mesh.visible = mesh.active; } ); } diff --git a/src/entities/FlashyTerrain.ts b/src/entities/RectTorus.ts similarity index 51% rename from src/entities/FlashyTerrain.ts rename to src/entities/RectTorus.ts index b71b44a..fb550b3 100644 --- a/src/entities/FlashyTerrain.ts +++ b/src/entities/RectTorus.ts @@ -1,44 +1,44 @@ import { Entity } from '../heck/Entity'; -import { Geometry } from '../heck/Geometry'; +import { InstancedGeometry } from '../heck/InstancedGeometry'; import { Material } from '../heck/Material'; import { Mesh } from '../heck/components/Mesh'; -import { Quaternion, Vector3 } from '@fms-cat/experimental'; import { dummyRenderTarget, dummyRenderTargetFourDrawBuffers } from '../globals/dummyRenderTarget'; -import { genPlane } from '../geometries/genPlane'; +import { genCube } from '../geometries/genCube'; +import { glCat } from '../globals/canvas'; import { quadGeometry } from '../globals/quadGeometry'; import depthFrag from '../shaders/depth.frag'; -import flashyTerrainFrag from '../shaders/flashy-terrain.frag'; -import flashyTerrainVert from '../shaders/flashy-terrain.vert'; +import rectTorusFrag from '../shaders/rect-torus.frag'; +import rectTorusVert from '../shaders/rect-torus.vert'; -export class FlashyTerrain extends Entity { +export class RectTorus extends Entity { public mesh: Mesh; public constructor() { super(); - this.transform.position = new Vector3( [ 0.0, -4.0, 0.0 ] ); - this.transform.rotation = Quaternion.fromAxisAngle( - new Vector3( [ 1.0, 0.0, 0.0 ] ), - -0.5 * Math.PI, - ); - this.transform.scale = this.transform.scale.scale( 8.0 ); - // -- geometry --------------------------------------------------------------------------------- - const plane = genPlane(); + const cube = genCube(); - const geometry = new Geometry(); + const geometry = new InstancedGeometry(); - geometry.vao.bindVertexbuffer( plane.position, 0, 3 ); - geometry.vao.bindIndexbuffer( plane.index ); + geometry.vao.bindVertexbuffer( cube.position, 0, 3 ); + geometry.vao.bindVertexbuffer( cube.normal, 1, 3 ); + geometry.vao.bindIndexbuffer( cube.index ); - geometry.count = plane.count; - geometry.mode = plane.mode; - geometry.indexType = plane.indexType; + const arrayInstanceId = [ ...Array( 4 ).keys() ]; + const bufferInstanceId = glCat.createBuffer(); + bufferInstanceId.setVertexbuffer( new Float32Array( arrayInstanceId ) ); + geometry.vao.bindVertexbuffer( bufferInstanceId, 2, 1, 1 ); + + geometry.count = cube.count; + geometry.mode = cube.mode; + geometry.indexType = cube.indexType; + geometry.primcount = 4; // -- materials -------------------------------------------------------------------------------- const deferred = new Material( - flashyTerrainVert, - flashyTerrainFrag, + rectTorusVert, + rectTorusFrag, { defines: [ 'DEFERRED 1' ], initOptions: { geometry: quadGeometry, target: dummyRenderTargetFourDrawBuffers }, @@ -46,7 +46,7 @@ export class FlashyTerrain extends Entity { ); const depth = new Material( - flashyTerrainVert, + rectTorusVert, depthFrag, { initOptions: { geometry: quadGeometry, target: dummyRenderTarget } }, ); @@ -57,12 +57,12 @@ export class FlashyTerrain extends Entity { if ( module.hot ) { module.hot.accept( [ - '../shaders/flashy-terrain.vert', - '../shaders/flashy-terrain.frag', + '../shaders/rect-torus.vert', + '../shaders/rect-torus.frag', ], () => { - deferred.replaceShader( flashyTerrainVert, flashyTerrainFrag ); - depth.replaceShader( flashyTerrainVert, depthFrag ); + deferred.replaceShader( rectTorusVert, rectTorusFrag ); + depth.replaceShader( rectTorusVert, depthFrag ); }, ); } @@ -70,9 +70,9 @@ export class FlashyTerrain extends Entity { // -- mesh ------------------------------------------------------------------------------------- this.mesh = new Mesh( { - geometry, + geometry: geometry, materials, - name: process.env.DEV && 'FlashyTerrain/mesh', + name: process.env.DEV && 'Cube/mesh', } ); this.components.push( this.mesh ); } diff --git a/src/entities/Rings.ts b/src/entities/Rings.ts index b798c2c..c19a959 100644 --- a/src/entities/Rings.ts +++ b/src/entities/Rings.ts @@ -2,9 +2,11 @@ import { Entity } from '../heck/Entity'; import { InstancedGeometry } from '../heck/InstancedGeometry'; import { Material } from '../heck/Material'; import { Mesh } from '../heck/components/Mesh'; +import { auto } from '../globals/automaton'; import { dummyRenderTarget } from '../globals/dummyRenderTarget'; import { genTorus } from '../geometries/genTorus'; import { glCat } from '../globals/canvas'; +import { objectValuesMap } from '../utils/objectEntriesMap'; import depthFrag from '../shaders/depth.frag'; import ringsFrag from '../shaders/rings.frag'; import ringsVert from '../shaders/rings.vert'; @@ -82,6 +84,13 @@ export class Rings extends Entity { } } + // -- begin ------------------------------------------------------------------------------------ + auto( 'Rings/begin', ( { value } ) => { + objectValuesMap( materials, ( material ) => { + material.addUniform( 'begin', '1f', value ); + } ); + } ); + // -- mesh ------------------------------------------------------------------------------------- const mesh = new Mesh( { geometry, diff --git a/src/entities/SceneBegin.ts b/src/entities/SceneBegin.ts index 3a311f2..0e94a2b 100644 --- a/src/entities/SceneBegin.ts +++ b/src/entities/SceneBegin.ts @@ -4,15 +4,20 @@ import { Entity } from '../heck/Entity'; import { LightEntity } from './LightEntity'; import { Vector3 } from '@fms-cat/experimental'; + +interface SceneBeginOptions { + scenes: Entity[]; +} + export class SceneBegin extends Entity { public readonly lights: LightEntity[]; - public constructor() { + public constructor( { scenes }: SceneBeginOptions ) { super(); // -- lights ----------------------------------------------------------------------------------- const light1 = new LightEntity( { - scenes: [ this ], + scenes, shadowMapFov: 30.0, shadowMapNear: 1.0, shadowMapFar: 20.0, @@ -22,7 +27,7 @@ export class SceneBegin extends Entity { light1.transform.lookAt( new Vector3( [ 4.0, 4.0, 4.0 ] ) ); const light2 = new LightEntity( { - scenes: [ this ], + scenes, shadowMapFov: 30.0, shadowMapNear: 1.0, shadowMapFar: 20.0, diff --git a/src/entities/SceneCrystals.ts b/src/entities/SceneCrystals.ts index 088bea8..eee380f 100644 --- a/src/entities/SceneCrystals.ts +++ b/src/entities/SceneCrystals.ts @@ -10,11 +10,15 @@ import { Quaternion, Vector3, Xorshift } from '@fms-cat/experimental'; import { Rings } from './Rings'; import { auto } from '../globals/automaton'; +interface SceneCrystalsOptions { + scenes: Entity[]; +} + export class SceneCrystals extends Entity { public readonly lights: LightEntity[]; private __phantom: Phantom; - public constructor() { + public constructor( { scenes }: SceneCrystalsOptions ) { super(); // -- crystals --------------------------------------------------------------------------------- @@ -79,15 +83,19 @@ export class SceneCrystals extends Entity { // -- lights ----------------------------------------------------------------------------------- const light1 = new LightEntity( { - scenes: [ this ], + scenes, shadowMapFov: 30.0, shadowMapNear: 1.0, shadowMapFar: 20.0, - namePrefix: process.env.DEV && 'lightBegin1', + namePrefix: process.env.DEV && 'lightCrystals1', } ); light1.color = [ 400.0, 400.0, 400.0 ]; light1.transform.lookAt( new Vector3( [ 0.0, 4.0, 1.0 ] ) ); + auto( 'SceneCrystals/light/amp', ( { value } ) => { + light1.color = [ 400.0 * value, 400.0 * value, 400.0 * value ]; + } ); + this.lights = [ light1 ]; // -- children --------------------------------------------------------------------------------- diff --git a/src/entities/SceneDynamic.ts b/src/entities/SceneDynamic.ts new file mode 100644 index 0000000..f1856c6 --- /dev/null +++ b/src/entities/SceneDynamic.ts @@ -0,0 +1,91 @@ +import { BufferRenderTarget } from '../heck/BufferRenderTarget'; +import { CyclicBoard } from './CyclicBoard'; +import { Entity } from '../heck/Entity'; +import { LightEntity } from './LightEntity'; +import { LightShaft } from './LightShaft'; +import { Quaternion, Vector3 } from '@fms-cat/experimental'; +import { RectTorus } from './RectTorus'; + +interface SceneDynamicOptions { + scenes: Entity[]; +} + +export class SceneDynamic extends Entity { + public readonly lights: LightEntity[]; + private readonly __shafts: LightShaft[]; + + public constructor( { scenes }: SceneDynamicOptions ) { + super(); + + // -- rectTorus -------------------------------------------------------------------------------- + const rectToruses = [ ...new Array( 4 ).keys() ].map( ( i ) => { + const rectTorus = new RectTorus(); + + rectTorus.transform.position = new Vector3( [ 0.0, 0.0, -0.5 - 0.5 * i ] ); + rectTorus.transform.rotation = Quaternion.fromAxisAngle( + new Vector3( [ 1.0, 0.0, 0.0 ] ).normalized, + 1.57 + ).multiply( Quaternion.fromAxisAngle( + new Vector3( [ 0.0, 1.0, 0.0 ] ).normalized, + i + ).multiply( Quaternion.fromAxisAngle( + new Vector3( [ 1.0, 0.0, 1.0 ] ).normalized, + 0.1 + ) ) ); + + return rectTorus; + } ); + + // -- cyclic board ----------------------------------------------------------------------------- + const cyclicBoard = new CyclicBoard(); + cyclicBoard.transform.position = new Vector3( [ 0.0, -2.0, 0.0 ] ); + + // -- lights ----------------------------------------------------------------------------------- + this.__shafts = []; + + const light1 = new LightEntity( { + scenes, + shadowMapFov: 70.0, + shadowMapNear: 1.0, + shadowMapFar: 20.0, + namePrefix: process.env.DEV && 'lightDynamic1', + } ); + light1.color = [ 50.0, 50.0, 50.0 ]; + light1.transform.lookAt( new Vector3( [ 5.0, 5.0, 5.0 ] ) ); + + const light2 = new LightEntity( { + scenes, + shadowMapFov: 30.0, + shadowMapNear: 1.0, + shadowMapFar: 20.0, + namePrefix: process.env.DEV && 'lightDynamic2', + } ); + light2.spotness = 0.9; + light2.color = [ 300.0, 360.0, 400.0 ]; + light2.transform.lookAt( new Vector3( [ 0.0, 6.0, 1.0 ] ) ); + + const shaft = new LightShaft( { + light: light2, + namePrefix: process.env.DEV && 'sceneDynamic/light2/Shaft', + intensity: 0.06, + } ); + light2.children.push( shaft ); + this.__shafts.push( shaft ); + + this.lights = [ light1, light2 ]; + cyclicBoard.lights.push( ...this.lights ); + + // -- scene ------------------------------------------------------------------------------------ + this.children.push( + ...rectToruses, + cyclicBoard, + ...this.lights, + ); + } + + public setDefferedCameraTarget( deferredCameraTarget: BufferRenderTarget ): void { + this.__shafts.map( ( shaft ) => { + shaft.setDefferedCameraTarget( deferredCameraTarget ); + } ); + } +} diff --git a/src/entities/SceneNeuro.ts b/src/entities/SceneNeuro.ts index 2326740..d2874b2 100644 --- a/src/entities/SceneNeuro.ts +++ b/src/entities/SceneNeuro.ts @@ -8,11 +8,15 @@ import { Quaternion, Vector3 } from '@fms-cat/experimental'; import { SufferTexts } from './SufferTexts'; import { Wobbleball } from './Wobbleball'; +interface SceneNeuroOptions { + scenes: Entity[]; +} + export class SceneNeuro extends Entity { public readonly lights: LightEntity[]; private readonly __shafts: LightShaft[]; - public constructor() { + public constructor( { scenes }: SceneNeuroOptions ) { super(); // -- lights ----------------------------------------------------------------------------------- @@ -26,7 +30,7 @@ export class SceneNeuro extends Entity { [ [ 20.0, 20.0, 20.0 ], [ 0.0, -2.0, 4.0 ], false ], ] as TypeScriptSucks ).map( ( [ color, pos, isSpot ], i ) => { const light = new LightEntity( { - scenes: [ this ], + scenes, shadowMapFov: isSpot ? 15.0 : 50.0, shadowMapNear: 0.5, shadowMapFar: 20.0, @@ -35,7 +39,7 @@ export class SceneNeuro extends Entity { } ); light.color = color; - light.spotness = isSpot ? 0.99 : 0.0; + light.spotness = isSpot ? 0.9 : 0.0; light.transform.lookAt( new Vector3( pos ) ); if ( isSpot ) { diff --git a/src/entities/StoneParticles.ts b/src/entities/StoneParticles.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/entities/SufferTexts.ts b/src/entities/SufferTexts.ts index 956ee3a..d4a63fe 100644 --- a/src/entities/SufferTexts.ts +++ b/src/entities/SufferTexts.ts @@ -1,10 +1,11 @@ +import { AutomatonWithGUI } from '@fms-cat/automaton-with-gui'; import { Entity } from '../heck/Entity'; import { GPUParticles } from './GPUParticles'; import { InstancedGeometry } from '../heck/InstancedGeometry'; import { Lambda } from '../heck/components/Lambda'; import { Material } from '../heck/Material'; import { TRIANGLE_STRIP_QUAD } from '@fms-cat/experimental'; -import { auto } from '../globals/automaton'; +import { auto, automaton } from '../globals/automaton'; import { dummyRenderTarget } from '../globals/dummyRenderTarget'; import { gl, glCat } from '../globals/canvas'; import { quadGeometry } from '../globals/quadGeometry'; @@ -141,6 +142,20 @@ export class SufferTexts extends Entity { name: process.env.DEV && 'SufferTexts/logic', } ) ); + if ( process.env.DEV ) { + ( automaton as AutomatonWithGUI ).on( 'play', () => { + this.queue = []; + } ); + + ( automaton as AutomatonWithGUI ).on( 'pause', () => { + this.queue = []; + } ); + + ( automaton as AutomatonWithGUI ).on( 'seek', () => { + this.queue = []; + } ); + } + // -- gpu particles ---------------------------------------------------------------------------- const gpuParticles = new GPUParticles( { materialCompute, diff --git a/src/entities/Tetrahedron.ts b/src/entities/Tetrahedron.ts new file mode 100644 index 0000000..b48069c --- /dev/null +++ b/src/entities/Tetrahedron.ts @@ -0,0 +1,120 @@ +import { Entity } from '../heck/Entity'; +import { Geometry } from '../heck/Geometry'; +import { Lambda } from '../heck/components/Lambda'; +import { Material } from '../heck/Material'; +import { Mesh, MeshCull } from '../heck/components/Mesh'; +import { Quaternion, Vector3 } from '@fms-cat/experimental'; +import { auto } from '../globals/automaton'; +import { dummyRenderTarget, dummyRenderTargetFourDrawBuffers } from '../globals/dummyRenderTarget'; +import { genCube } from '../geometries/genCube'; +import { objectValuesMap } from '../utils/objectEntriesMap'; +import { randomTexture, randomTextureStatic } from '../globals/randomTexture'; +import raymarchObjectVert from '../shaders/raymarch-object.vert'; +import tetrahedronFrag from '../shaders/tetrahedron.frag'; + +export class Tetrahedron extends Entity { + public constructor() { + super(); + + // -- geometry --------------------------------------------------------------------------------- + const cube = genCube( { dimension: [ 1.1, 1.1, 1.1 ] } ); + + const geometry = new Geometry(); + + geometry.vao.bindVertexbuffer( cube.position, 0, 3 ); + geometry.vao.bindIndexbuffer( cube.index ); + + geometry.count = cube.count; + geometry.mode = cube.mode; + geometry.indexType = cube.indexType; + + // -- materials -------------------------------------------------------------------------------- + const deferred = new Material( + raymarchObjectVert, + tetrahedronFrag, + { + defines: [ 'DEFERRED 1' ], + initOptions: { geometry, target: dummyRenderTargetFourDrawBuffers }, + }, + ); + + const depth = new Material( + raymarchObjectVert, + tetrahedronFrag, + { + defines: [ 'DEPTH 1' ], + initOptions: { geometry, target: dummyRenderTarget } + }, + ); + + const materials = { deferred, depth }; + + if ( process.env.DEV ) { + if ( module.hot ) { + module.hot.accept( '../shaders/tetrahedron.frag', () => { + deferred.replaceShader( raymarchObjectVert, tetrahedronFrag ); + depth.replaceShader( raymarchObjectVert, tetrahedronFrag ); + } ); + } + } + + objectValuesMap( materials, ( material ) => { + material.addUniformTexture( 'samplerRandom', randomTexture.texture ); + material.addUniformTexture( 'samplerRandomStatic', randomTextureStatic.texture ); + } ); + + // -- updater ---------------------------------------------------------------------------------- + this.components.push( new Lambda( { + onDraw: ( event ) => { + objectValuesMap( materials, ( material ) => { + material.addUniform( + 'cameraNearFar', + '2f', + event.camera.near, + event.camera.far + ); + + material.addUniformMatrixVector( + 'inversePVM', + 'Matrix4fv', + event.projectionMatrix + .multiply( event.viewMatrix ) + .multiply( event.globalTransform.matrix ) + .inverse! + .elements + ); + + material.addUniform( 'deformAmp', '1f', auto( 'Music/NEURO_WUB_AMP' ) ); + material.addUniform( 'deformFreq', '1f', auto( 'Music/NEURO_WUB_FREQ' ) + auto( 'Music/NEURO_DETUNE' ) ); + material.addUniform( 'deformTime', '1f', auto( 'Music/NEURO_TIME' ) ); + } ); + }, + name: process.env.DEV && 'Tetrahedron/updater', + } ) ); + + // -- mesh ------------------------------------------------------------------------------------- + const mesh = new Mesh( { + geometry, + materials, + name: process.env.DEV && 'Tetrahedron/mesh', + } ); + mesh.cull = MeshCull.None; + this.components.push( mesh ); + + // -- speen ------------------------------------------------------------------------------------ + const axis = new Vector3( [ 1.0, -1.0, 1.0 ] ).normalized; + this.components.push( new Lambda( { + onUpdate: ( { time } ) => { + this.transform.rotation = Quaternion.fromAxisAngle( axis, time ); + objectValuesMap( materials, ( material ) => { + material.addUniform( + 'distort', + '1f', + auto( 'Tetrahedron/distortAmp' ) + ); + } ); + }, + name: process.env.DEV && 'Tetrahedron/update', + } ) ); + } +} diff --git a/src/entities/Trails.ts b/src/entities/Trails.ts index 937679e..cc8777b 100644 --- a/src/entities/Trails.ts +++ b/src/entities/Trails.ts @@ -1,6 +1,7 @@ import { Entity } from '../heck/Entity'; import { GPUParticles } from './GPUParticles'; import { InstancedGeometry } from '../heck/InstancedGeometry'; +import { Lambda } from '../heck/components/Lambda'; import { Material } from '../heck/Material'; import { dummyRenderTarget, dummyRenderTargetFourDrawBuffers, dummyRenderTargetTwoDrawBuffers } from '../globals/dummyRenderTarget'; import { gl, glCat } from '../globals/canvas'; @@ -38,6 +39,15 @@ export class Trails extends Entity { } } + // -- lambda to say update --------------------------------------------------------------------- + this.components.push( new Lambda( { + onUpdate: ( { time, deltaTime } ) => { + const shouldUpdate + = Math.floor( 60.0 * time ) !== Math.floor( 60.0 * ( time - deltaTime ) ); + materialCompute.addUniform( 'shouldUpdate', '1i', shouldUpdate ? 1 : 0 ); + }, + } ) ); + // -- geometry render -------------------------------------------------------------------------- const geometryRender = new InstancedGeometry(); diff --git a/src/entities/Wobbleball.ts b/src/entities/Wobbleball.ts index ea4ee26..000c8b9 100644 --- a/src/entities/Wobbleball.ts +++ b/src/entities/Wobbleball.ts @@ -45,7 +45,7 @@ export class Wobbleball extends Entity { raymarchObjectVert, wobbleballFrag, { - defines: [ 'SHADOW 1' ], + defines: [ 'DEPTH 1' ], initOptions: { geometry, target: dummyRenderTarget } }, ); diff --git a/src/main.ts b/src/main.ts index e019bb9..d01cfbe 100644 --- a/src/main.ts +++ b/src/main.ts @@ -79,6 +79,10 @@ async function load(): Promise { ( automaton as AutomatonWithGUI ).play(); } + if ( !process.env.DEV ) { + document.write( 'Wait a moment... ' ); + } + await music.prepare(); if ( !process.env.DEV ) { diff --git a/src/music/music.vert b/src/music/music.vert index 88a61e1..c53c257 100644 --- a/src/music/music.vert +++ b/src/music/music.vert @@ -406,24 +406,15 @@ vec2 mainAudio( vec4 time ) { dest += 0.25 * kick( t, 1.0 ); } - // -- gabber ------------------------------------------------------------------------------------- - if ( - inRange( time.w, SECTION_WHOA, SECTION_PORTER_FUCKING_ROBINSON ) && - inRange( mod( time.z, 8.0 * BEAT ), 4.0 * BEAT, 8.0 * BEAT ) - ) { - const int pattern[16] = int[]( - 0, 1, 0, 1, - 2, 3, 4, 0, - 1, 2, 0, 1, - 2, 3, 4, 5 - ); - float tHeadKick = 0.25 * BEAT * float( pattern[ int( time.y / 0.25 / BEAT ) ] ); - float tKick = tHeadKick + mod( time.y, 0.25 * BEAT ); + // -- snare -------------------------------------------------------------------------------------- + if ( inRange( time.w, SECTION_WHOA, SECTION_PORTER_FUCKING_ROBINSON - 4.0 * BEAT ) ) { + float t = mod( time.z - 4.0 * BEAT, 8.0 * BEAT ); + dest += 0.1 * snare( t ); } // -- amen --------------------------------------------------------------------------------------- if ( - inRange( time.w, SECTION_WHOA, SECTION_PORTER_FUCKING_ROBINSON ) && + inRange( time.w, SECTION_WHOA, SECTION_PORTER_FUCKING_ROBINSON - 4.0 * BEAT ) && inRange( mod( time.z, 8.0 * BEAT ), 4.0 * BEAT, 8.0 * BEAT ) ) { float chunk = floor( 6.0 * fs( lofi( time.z, 0.5 * BEAT ) ) ); @@ -473,7 +464,7 @@ vec2 mainAudio( vec4 time ) { } // -- choir -------------------------------------------------------------------------------------- - if ( inRange( time.w, SECTION_WHOA, SECTION_PORTER_FUCKING_ROBINSON ) ) { + if ( inRange( time.w, SECTION_WHOA, SECTION_PORTER_FUCKING_ROBINSON - 0.5 * BEAT ) ) { vec2 sum = vec2( 0.0 ); float t = mod( time.z, 8.0 * BEAT ); @@ -492,7 +483,13 @@ vec2 mainAudio( vec4 time ) { sum += 0.4 * mix( 0.0, 1.0, sidechain ) * choir( t * rate * 0.5 ); } - dest += 0.09 * inRangeSmooth( t, 0.0, 4.0 * BEAT, 1E3 ) * aSaturate( 2.0 * sum ); + float release = ( ( time.z > 60.0 * BEAT ) ? 2.0 : 1E3 ); + dest += 0.09 * inRangeSmooth( t, 0.0, 4.0 * BEAT, release ) * aSaturate( 2.0 * sum ); + } + + // -- reversecrash ------------------------------------------------------------------------------- + if ( inRange( time.w, SECTION_WHOA, SECTION_PORTER_FUCKING_ROBINSON - 0.5 * BEAT ) ) { + dest += 0.1 * crash( max( 0.0, 63.5 * BEAT - time.z ) ); } // -- kick --------------------------------------------------------------------------------------- @@ -695,6 +692,10 @@ vec2 mainAudio( vec4 time ) { dest += 0.3 * deepkick( time.z ); } + if ( inRange( time.w, SECTION_PORTER_FUCKING_ROBINSON - 4.0 * BEAT, SECTION_PORTER_FUCKING_ROBINSON - 0.5 * BEAT ) ) { + dest += 0.3 * deepkick( time.y ); + } + if ( inRange( time.w, SECTION_AAAA - 8.0 * BEAT, SECTION_AAAA ) ) { dest += 0.3 * deepkick( mod( time.z, 8.0 * BEAT ) ); } diff --git a/src/scene.ts b/src/scene.ts index 1fd752a..e20a92f 100644 --- a/src/scene.ts +++ b/src/scene.ts @@ -9,21 +9,25 @@ import { DeferredCamera } from './entities/DeferredCamera'; import { Dog } from './heck/Dog'; import { Entity } from './heck/Entity'; import { EnvironmentMap } from './entities/EnvironmentMap'; -import { FlashyTerrain } from './entities/FlashyTerrain'; +import { FlashyBall } from './entities/FlashyBall'; import { FlickyParticles } from './entities/FlickyParticles'; import { ForwardCamera } from './entities/ForwardCamera'; import { Glitch } from './entities/Glitch'; import { IBLLUT } from './entities/IBLLUT'; +import { IFSAsUsual } from './entities/IFSAsUsual'; import { Lambda } from './heck/components/Lambda'; +import { NoiseVoxels } from './entities/NoiseVoxels'; import { PixelSorter } from './entities/PixelSorter'; import { Post } from './entities/Post'; import { RTInspector } from './entities/RTInspector'; import { SceneBegin } from './entities/SceneBegin'; import { SceneCrystals } from './entities/SceneCrystals'; +import { SceneDynamic } from './entities/SceneDynamic'; import { SceneNeuro } from './entities/SceneNeuro'; import { Serial } from './entities/Serial'; import { SphereParticles } from './entities/SphereParticles'; import { Swap, Vector3 } from '@fms-cat/experimental'; +import { Tetrahedron } from './entities/Tetrahedron'; import { Trails } from './entities/Trails'; import { arraySetDelete } from './utils/arraySetDelete'; import { auto, automaton } from './globals/automaton'; @@ -50,12 +54,10 @@ dog.root.components.push( new Lambda( { // -- util ----------------------------------------------------------------------------------------- class EntityReplacer { - private __root: Entity; public current!: T; public creator: () => T; - public constructor( root: Entity, creator: () => T, name?: string ) { - this.__root = root; + public constructor( creator: () => T, name?: string ) { this.creator = creator; this.replace(); @@ -73,12 +75,12 @@ class EntityReplacer { public replace(): void { if ( process.env.DEV ) { if ( this.current ) { - arraySetDelete( this.__root.children, this.current ); + arraySetDelete( dog.root.children, this.current ); } } this.current = this.creator(); - this.__root.children.push( this.current ); + dog.root.children.push( this.current ); // not visible by default this.current.active = false; @@ -95,7 +97,6 @@ const deferredRoot = new Entity(); dog.root.children.push( deferredRoot ); const replacerSphereParticles = new EntityReplacer( - deferredRoot, () => new SphereParticles(), 'SphereParticles', ); @@ -105,25 +106,57 @@ if ( process.env.DEV && module.hot ) { } ); } -const replacerFlashyTerrain = new EntityReplacer( - deferredRoot, - () => new FlashyTerrain(), - 'FlashyTerrain', +const replacerFlashyBall = new EntityReplacer( + () => new FlashyBall(), + 'FlashyBall', ); if ( process.env.DEV && module.hot ) { - module.hot.accept( './entities/FlashyTerrain', () => { - replacerFlashyTerrain.replace(); + module.hot.accept( './entities/FlashyBall', () => { + replacerFlashyBall.replace(); } ); } -const replacerTrails = new EntityReplacer( deferredRoot, () => new Trails(), 'Trails' ); +const replacerTetrahedron = new EntityReplacer( + () => new Tetrahedron(), + 'Tetrahedron', +); +if ( process.env.DEV && module.hot ) { + module.hot.accept( './entities/Tetrahedron', () => { + replacerTetrahedron.replace(); + } ); +} + +const replacerNoiseVoxels = new EntityReplacer( + () => new NoiseVoxels(), + 'NoiseVoxels', +); +if ( process.env.DEV && module.hot ) { + module.hot.accept( './entities/NoiseVoxels', () => { + replacerNoiseVoxels.replace(); + } ); +} + +const replacerIFSAsUsual = new EntityReplacer( + () => new IFSAsUsual(), + 'IFSAsUsual', +); +if ( process.env.DEV && module.hot ) { + module.hot.accept( './entities/IFSAsUsual', () => { + replacerIFSAsUsual.replace(); + } ); +} + +const replacerTrails = new EntityReplacer( () => new Trails(), 'Trails' ); if ( process.env.DEV && module.hot ) { module.hot.accept( './entities/Trails', () => { replacerTrails.replace(); } ); } -const replacerSceneBegin = new EntityReplacer( deferredRoot, () => new SceneBegin(), 'SceneBegin' ); +const replacerSceneBegin = new EntityReplacer( + () => new SceneBegin( { scenes: [ dog.root ] } ), + 'SceneBegin' +); if ( process.env.DEV && module.hot ) { module.hot.accept( './entities/SceneBegin', () => { replacerSceneBegin.current.lights.map( ( light ) => arraySetDelete( lights, light ) ); @@ -132,7 +165,25 @@ if ( process.env.DEV && module.hot ) { } ); } -const replacerSceneNeuro = new EntityReplacer( deferredRoot, () => new SceneNeuro(), 'SceneNeuro' ); +const replacerSceneDynamic = new EntityReplacer( + () => new SceneDynamic( { scenes: [ dog.root ] } ), + 'SceneDynamic', +); + +if ( process.env.DEV && module.hot ) { + module.hot.accept( './entities/SceneDynamic', () => { + replacerSceneDynamic.current.lights.map( ( light ) => arraySetDelete( lights, light ) ); + replacerSceneDynamic.replace(); + lights.push( ...replacerSceneDynamic.current.lights ); + replacerSceneDynamic.current.setDefferedCameraTarget( deferredCamera.cameraTarget ); + } ); +} + +const replacerSceneNeuro = new EntityReplacer( + () => new SceneNeuro( { scenes: [ dog.root ] } ), + 'SceneNeuro' +); + if ( process.env.DEV && module.hot ) { module.hot.accept( './entities/SceneNeuro', () => { replacerSceneNeuro.current.lights.map( ( light ) => arraySetDelete( lights, light ) ); @@ -142,7 +193,10 @@ if ( process.env.DEV && module.hot ) { } ); } -const replacerSceneCrystals = new EntityReplacer( deferredRoot, () => new SceneCrystals(), 'SceneCrystals' ); +const replacerSceneCrystals = new EntityReplacer( + () => new SceneCrystals( { scenes: [ dog.root ] } ), + 'SceneCrystals', +); if ( process.env.DEV && module.hot ) { module.hot.accept( './entities/SceneCrystals', () => { replacerSceneCrystals.current.lights.map( ( light ) => arraySetDelete( lights, light ) ); @@ -157,7 +211,6 @@ const forwardRoot = new Entity(); dog.root.children.push( forwardRoot ); const replacerFlickyParticles = new EntityReplacer( - forwardRoot, () => new FlickyParticles(), 'FlickyParticles', ); @@ -187,6 +240,7 @@ const swap = new Swap( const lights = [ ...replacerSceneBegin.current.lights, ...replacerSceneNeuro.current.lights, + ...replacerSceneDynamic.current.lights, ...replacerSceneCrystals.current.lights, ]; @@ -222,6 +276,7 @@ const deferredCamera = new DeferredCamera( { } ); dog.root.children.push( deferredCamera ); replacerSceneNeuro.current.setDefferedCameraTarget( deferredCamera.cameraTarget ); +replacerSceneDynamic.current.setDefferedCameraTarget( deferredCamera.cameraTarget ); replacerSceneCrystals.current.setDefferedCameraTarget( deferredCamera.cameraTarget ); const forwardCamera = new ForwardCamera( { @@ -275,9 +330,9 @@ dog.root.components.push( new Lambda( { if ( shake > 0.0 ) { camera.transform.position = camera.transform.position.add( new Vector3( [ - Math.sin( 145.0 * time ), - Math.sin( 2.0 + 148.0 * time ), - Math.sin( 4.0 + 151.0 * time ) + Math.sin( 45.0 * time ), + Math.sin( 2.0 + 48.0 * time ), + Math.sin( 4.0 + 51.0 * time ) ] ).scale( shake ) ); } diff --git a/src/shaders/crystal.frag b/src/shaders/crystal.frag index 49ea84b..a1fd215 100644 --- a/src/shaders/crystal.frag +++ b/src/shaders/crystal.frag @@ -6,7 +6,6 @@ precision highp float; #define saturate(x) clamp(x,0.,1.) #define linearstep(a,b,x) saturate(((x)-(a))/((b)-(a))) -const int MARCH_ITER = 90; const float PI = 3.14159265; const float TAU = PI * 2.0; const float foldcos = cos( PI / 5.0 ); @@ -23,7 +22,7 @@ const vec3 foldface = vec3( 0.0, foldrem, foldcos ); in vec4 vPositionWithoutModel; -#ifdef SHADOW +#ifdef DEPTH out vec4 fragColor; #endif @@ -41,9 +40,6 @@ uniform mat4 modelMatrix; uniform mat4 viewMatrix; uniform mat4 projectionMatrix; uniform mat4 inversePVM; -uniform sampler2D samplerRandom; -uniform sampler2D samplerRandomStatic; -uniform sampler2D samplerCapture; vec3 divideByW( vec4 v ) { return v.xyz / v.w; @@ -73,7 +69,7 @@ vec3 fold( vec3 p ) { float distFunc( vec3 p ) { p.zx = rot2d( 0.5 * time ) * p.zx; - p -= size.xyx * vec3( 0.02, 0.2, 0.02 ) * cyclicNoise( vec3( 1.0, 0.04, 1.0 ) / size.xyx * p + noiseOffset ); + p -= size.xyx * vec3( 0.02, 0.2, 0.02 ) * cyclicNoise( vec3( 1.0, 0.1, 1.0 ) / size.xyx * p + noiseOffset ); p.y -= min( 0.8 * size.y - size.x, abs( p.y ) ) * sign( p.y ); p = fold( p ); return dot( p, foldface ) - size.x; @@ -98,6 +94,16 @@ void main() { vec3 rayPos = rayOri + rayDir * rayLen; float dist; + int MARCH_ITER; + + #ifdef DEFERRED + MARCH_ITER = 60; + #endif + + #ifdef DEPTH + MARCH_ITER = 10; + #endif + for ( int i = 0; i < MARCH_ITER; i ++ ) { dist = distFunc( rayPos ); rayLen += 0.5 * dist; @@ -121,11 +127,11 @@ void main() { #ifdef DEFERRED fragPosition = vec4( modelPos.xyz, depth ); fragNormal = vec4( modelNormal, 1.0 ); - fragColor = vec4( vec3( 0.5, 0.52, 1.0 ), 1.0 ); + fragColor = vec4( vec3( 0.5 ), 1.0 ); fragWTF = vec4( vec3( 0.04, 1.0, 0.0 ), 3 ); #endif - #ifdef SHADOW + #ifdef DEPTH float shadowDepth = linearstep( cameraNearFar.x, cameraNearFar.y, diff --git a/src/shaders/cyclic-board.frag b/src/shaders/cyclic-board.frag new file mode 100644 index 0000000..e157b3d --- /dev/null +++ b/src/shaders/cyclic-board.frag @@ -0,0 +1,195 @@ +#version 300 es + +precision highp float; + +#define fs(i) (fract(sin((i)*114.514)*1919.810)) +#define saturate(x) clamp(x,0.,1.) +#define linearstep(a,b,x) saturate(((x)-(a))/((b)-(a))) + +const float PI = 3.14159265; +const float TAU = PI * 2.0; + +#ifdef FORWARD + out vec4 fragColor; +#endif + +#ifdef DEFERRED + layout (location = 0) out vec4 fragPosition; + layout (location = 1) out vec4 fragNormal; + layout (location = 2) out vec4 fragColor; + layout (location = 3) out vec4 fragWTF; +#endif + +in vec4 vPositionWithoutModel; + +#ifdef DEPTH + out vec4 fragColor; +#endif + +uniform int lightCount; +uniform float deformAmp; +uniform float deformFreq; +uniform float deformTime; +uniform float time; +uniform float noiseOffset; +uniform vec2 lightNearFar[ 8 ]; +uniform vec2 resolution; +uniform vec2 size; +uniform vec2 cameraNearFar; +uniform vec3 lightPos[ 8 ]; +uniform vec3 lightColor[ 8 ]; +uniform vec3 cameraPos; +uniform vec4 lightParams[ 8 ]; +uniform mat4 lightPV[ 8 ]; +uniform mat4 normalMatrix; +uniform mat4 modelMatrix; +uniform mat4 viewMatrix; +uniform mat4 projectionMatrix; +uniform mat4 inversePVM; +uniform sampler2D samplerRandom; +uniform sampler2D samplerRandomStatic; +uniform sampler2D samplerCapture; +uniform sampler2D samplerShadow[ 8 ]; + +vec3 divideByW( vec4 v ) { + return v.xyz / v.w; +} + +#pragma glslify: cyclicNoise = require( ./modules/cyclicNoise ); +#pragma glslify: doAnalyticLighting = require( ./modules/doAnalyticLighting.glsl ); +#pragma glslify: doShadowMapping = require( ./modules/doShadowMapping.glsl ); + +vec4 fetchShadowMap( int iLight, vec2 uv ) { + if ( iLight == 0 ) { + return texture( samplerShadow[ 0 ], uv ); + } else if ( iLight == 1 ) { + return texture( samplerShadow[ 1 ], uv ); + } else if ( iLight == 2 ) { + return texture( samplerShadow[ 2 ], uv ); + } else if ( iLight == 3 ) { + return texture( samplerShadow[ 3 ], uv ); + } else if ( iLight == 4 ) { + return texture( samplerShadow[ 4 ], uv ); + } else if ( iLight == 5 ) { + return texture( samplerShadow[ 5 ], uv ); + } else if ( iLight == 6 ) { + return texture( samplerShadow[ 6 ], uv ); + } else if ( iLight == 7 ) { + return texture( samplerShadow[ 7 ], uv ); + } +} + +float distFunc( vec3 p ) { + float d = p.y; + d += 0.2 * cyclicNoise( p ).x; + return d; +} + +vec3 normalFunc( vec3 p, float dd ) { + vec2 d = vec2( 0.0, dd ); + return normalize( vec3( + distFunc( p + d.yxx ) - distFunc( p - d.yxx ), + distFunc( p + d.xyx ) - distFunc( p - d.xyx ), + distFunc( p + d.xxy ) - distFunc( p - d.xxy ) + ) ); +} + +void main() { + vec2 p = ( gl_FragCoord.xy * 2.0 - resolution ) / resolution.y; + + vec3 rayOri = divideByW( inversePVM * vec4( p, 0.0, 1.0 ) ); + vec3 farPos = divideByW( inversePVM * vec4( p, 1.0, 1.0 ) ); + vec3 rayDir = normalize( farPos - rayOri ); + float rayLen = length( vPositionWithoutModel.xyz - rayOri ); + vec3 rayPos = rayOri + rayDir * rayLen; + float dist; + + int MARCH_ITER; + + #ifdef FORWARD + MARCH_ITER = 30; + #endif + + #ifdef DEFERRED + MARCH_ITER = 60; + #endif + + #ifdef DEPTH + MARCH_ITER = 10; + #endif + + for ( int i = 0; i < MARCH_ITER; i ++ ) { + dist = distFunc( rayPos ); + rayLen += 0.5 * dist; + rayPos = rayOri + rayDir * rayLen; + + if ( abs( dist ) < 1E-3 ) { break; } + if ( rayLen > cameraNearFar.y ) { break; } + } + + if ( 0.01 < dist ) { + discard; + } + + vec3 modelNormal = normalize( normalMatrix * vec4( normalFunc( rayPos, 1E-2 ), 1.0 ) ).xyz; + + vec4 modelPos = modelMatrix * vec4( rayPos, 1.0 ); + vec4 projPos = projectionMatrix * viewMatrix * modelPos; // terrible + float depth = projPos.z / projPos.w; + gl_FragDepth = 0.5 + 0.5 * depth; + + #ifdef FORWARD + vec3 color = vec3( 0.0 ); + + // for each lights + for ( int iLight = 0; iLight < 8; iLight ++ ) { + if ( iLight >= lightCount ) { break; } + + vec3 V = cameraPos - modelPos.xyz; + vec3 L = lightPos[ iLight ] - modelPos.xyz; + + // shading + vec3 shade = doAnalyticLighting( + V, + L, + modelNormal, + vec3( 0.6, 0.5, 0.4 ), + 0.5, + 0.2 + ) * lightColor[ iLight ]; + + // fetch shadowmap + spot lighting + vec4 lightProj = lightPV[ iLight ] * modelPos; + vec2 lightP = lightProj.xy / lightProj.w; + + shade *= doShadowMapping( + L, + modelNormal, + fetchShadowMap( iLight, 0.5 + 0.5 * lightP ), + lightP, + lightNearFar[ iLight ], + lightParams[ iLight ].x + ); + + color += shade; + } + + fragColor = vec4( color, 1.0 ); + #endif + + #ifdef DEFERRED + fragPosition = vec4( modelPos.xyz, depth ); + fragNormal = vec4( modelNormal, 1.0 ); + fragColor = vec4( vec3( 0.6, 0.5, 0.4 ), 1.0 ); + fragWTF = vec4( vec3( 0.5, 0.2, 0.0 ), 3 ); + #endif + + #ifdef DEPTH + float shadowDepth = linearstep( + cameraNearFar.x, + cameraNearFar.y, + length( cameraPos - modelPos.xyz ) + ); + fragColor = vec4( shadowDepth, shadowDepth * shadowDepth, shadowDepth, 1.0 ); + #endif +} diff --git a/src/shaders/dvi.frag b/src/shaders/dvi.frag index 9ad6ae6..3280155 100644 --- a/src/shaders/dvi.frag +++ b/src/shaders/dvi.frag @@ -61,17 +61,6 @@ float dOverlay( vec2 p ) { float d = 1E9; float t = time + offset; - // center bar - d = min( d, sdbox( p, vec2( 0.12, 0.002 ) ) ); - - // circles - { - vec2 pt = abs( p ); - d = min( d, dCirc( pt - vec2( 0.0, 0.05 ) ) ); - d = min( d, dCirc( pt - vec2( 0.07, 0.05 ) ) ); - d = min( d, dCirc( pt - vec2( 0.035, 0.05 + 0.035 * sqrt( 3.0 ) ) ) ); - } - // rings { float d2 = 1E9; diff --git a/src/shaders/environment-map.frag b/src/shaders/environment-map.frag index 01aef75..7e86c0d 100644 --- a/src/shaders/environment-map.frag +++ b/src/shaders/environment-map.frag @@ -61,11 +61,12 @@ void main() { float a = TAU * uv.x; float b = PI * ( uv.y - 0.5 ); - vec3 N = vec3( -sin( a ) * cos( b ), sin( b ), -cos( a ) * cos( b ) ); + vec3 N = vec3( -sin( a ) * cos( b ), -sin( b ), -cos( a ) * cos( b ) ); vec3 R = N; vec3 V = R; - seed = uniformSeed + 500.0 * vec4( N.xy, uv00 ); + seed = uniformSeed + 10.0 + 500.0 * vec4( uv00, N.xy ); + prng( seed ); vec4 col = vec4( 0.0 ); for ( int i = 0; i < SAMPLES; i ++ ) { diff --git a/src/shaders/flashy-terrain.frag b/src/shaders/flashy-ball.frag similarity index 54% rename from src/shaders/flashy-terrain.frag rename to src/shaders/flashy-ball.frag index 45f66b2..d7ca6a0 100644 --- a/src/shaders/flashy-terrain.frag +++ b/src/shaders/flashy-ball.frag @@ -18,23 +18,16 @@ in vec4 vPositionWithoutModel; uniform float time; +#pragma glslify: orthBasis = require( ./modules/orthBasis ); #pragma glslify: cyclicNoise = require( ./modules/cyclicNoise ); void main() { - float grid = max( - step( 0.996, cos( 16.0 * TAU * vPositionWithoutModel.x ) ), - step( 0.996, cos( 16.0 * TAU * vPositionWithoutModel.y ) ) - ); - vec2 cell = floor( 16.0 * vPositionWithoutModel.xy ); - grid = max( - grid, - smoothstep( 0.2, 0.3, cyclicNoise( vec3( cell.xy, 4.0 * time ) ).x ) - ); + float roughness = 0.3 + 0.1 * cyclicNoise( 4.0 * vPositionWithoutModel.xyz ).x; #ifdef DEFERRED fragPosition = vPosition; - fragNormal = vec4( 0.0, 0.0, 1.0, 1.0 ); - fragColor = vec4( grid * vec3( 2.0 ), 1.0 ); - fragWTF = vec4( 0.0, 0.0, 0.0, 1 ); + fragNormal = vec4( vNormal, 1.0 ); + fragColor = vec4( vec3( 0.2 ), 1.0 ); + fragWTF = vec4( roughness, 0.9, 0.0, 2 ); #endif } diff --git a/src/shaders/flashy-terrain.vert b/src/shaders/flashy-ball.vert similarity index 65% rename from src/shaders/flashy-terrain.vert rename to src/shaders/flashy-ball.vert index e64afa2..b5a8b7f 100644 --- a/src/shaders/flashy-terrain.vert +++ b/src/shaders/flashy-ball.vert @@ -1,11 +1,14 @@ #version 300 es layout (location = 0) in vec3 position; +layout (location = 1) in vec3 normal; -out vec4 vPositionWithoutModel; +out vec3 vNormal; out vec4 vPosition; +out vec4 vPositionWithoutModel; uniform float time; +uniform float distort; uniform vec2 resolution; uniform mat4 projectionMatrix; uniform mat4 viewMatrix; @@ -15,12 +18,12 @@ uniform mat4 normalMatrix; #pragma glslify: cyclicNoise = require( ./modules/cyclicNoise ); void main() { + vNormal = normalize( ( normalMatrix * vec4( normal, 1.0 ) ).xyz ); + vPositionWithoutModel = vec4( position, 1.0 ); - - float n = 0.5 + 0.5 * cyclicNoise( 2.0 * vPositionWithoutModel.xyz - vec3( 0.0, time, 0.0 ) ).x; - vPositionWithoutModel.z += 1.0 * n * exp( -2.0 * length( vPositionWithoutModel.xy ) ); - vPosition = modelMatrix * vPositionWithoutModel; + vPosition.xyz -= distort * cyclicNoise( 0.3 * vPosition.xyz + 0.3 * time ); + vNormal = normalize( vNormal + distort * cyclicNoise( 1.0 + 0.3 * vPosition.xyz + 0.3 * time ) ); vec4 outPos = projectionMatrix * viewMatrix * vPosition; outPos.x *= resolution.y / resolution.x; diff --git a/src/shaders/flicky-particles-render.frag b/src/shaders/flicky-particles-render.frag index 8b00009..971d757 100644 --- a/src/shaders/flicky-particles-render.frag +++ b/src/shaders/flicky-particles-render.frag @@ -36,13 +36,6 @@ uniform sampler2D samplerRandomStatic; out vec4 fragColor; #endif -#ifdef DEFERRED - layout (location = 0) out vec4 fragPosition; - layout (location = 1) out vec4 fragNormal; - layout (location = 2) out vec4 fragColor; - layout (location = 3) out vec4 fragWTF; -#endif - #ifdef DEPTH out vec4 fragColor; #endif @@ -185,13 +178,6 @@ void main() { fragColor = vec4( color, 1.0 ); #endif - #ifdef DEFERRED - fragPosition = vPosition; - fragNormal = vec4( vNormal, 1.0 ); - fragColor = vec4( color, 1.0 ); - fragWTF = vec4( vec3( 0.0 ), MTL_UNLIT ); - #endif - #ifdef DEPTH float depth = linearstep( cameraNearFar.x, diff --git a/src/shaders/ifs-as-usual.frag b/src/shaders/ifs-as-usual.frag new file mode 100644 index 0000000..c4ec639 --- /dev/null +++ b/src/shaders/ifs-as-usual.frag @@ -0,0 +1,156 @@ +#version 300 es + +precision highp float; + +#define fs(i) (fract(sin((i)*114.514)*1919.810)) +#define saturate(x) clamp(x,0.,1.) +#define linearstep(a,b,x) saturate(((x)-(a))/((b)-(a))) + +const int MARCH_ITER = 90; +const float PI = 3.14159265; +const float TAU = PI * 2.0; + +#ifdef DEFERRED + layout (location = 0) out vec4 fragPosition; + layout (location = 1) out vec4 fragNormal; + layout (location = 2) out vec4 fragColor; + layout (location = 3) out vec4 fragWTF; +#endif + +in vec4 vPositionWithoutModel; + +#ifdef DEPTH + out vec4 fragColor; +#endif + +uniform float time; +uniform float ifsSeed; +uniform vec2 resolution; +uniform vec2 cameraNearFar; +uniform vec3 cameraPos; +uniform mat4 normalMatrix; +uniform mat4 modelMatrix; +uniform mat4 viewMatrix; +uniform mat4 projectionMatrix; +uniform mat4 inversePVM; +uniform sampler2D samplerRandom; +uniform sampler2D samplerRandomStatic; +uniform sampler2D samplerCapture; + +vec3 divideByW( vec4 v ) { + return v.xyz / v.w; +} + +// https://www.iquilezles.org/www/articles/smin/smin.htm +float smin( float a, float b, float k ) { + float h = max( k - abs( a - b ), 0.0 ) / k; + return min( a, b ) - h * h * h * k * ( 1.0 / 6.0 ); +} + +mat2 rot2d( float t ) { + float c = cos( t ); + float s = sin( t ); + return mat2( c, -s, s, c ); +} + +#pragma glslify: orthBasis = require( ./modules/orthBasis ); +#pragma glslify: cyclicNoise = require( ./modules/cyclicNoise ); + +vec3 ifs( vec3 p, vec3 r, vec3 t ) { + vec3 s = t; + mat3 bas = orthBasis( r ); + + for ( int i = 0; i < 5; i ++ ) { + p = abs( p ) - abs( s ) * pow( 1.8, -float( i ) ); + + s = bas * s; + + p.xy = p.x < p.y ? p.yx : p.xy; + p.yz = p.y < p.z ? p.zy : p.yz; + } + + return p; +} + +float box( vec3 p, vec3 s ) { + vec3 d = abs( p ) - s; + return min( 0.0, max( d.x, max( d.y, d.z ) ) ) + length( max( vec3( 0.0 ), d ) ); +} + +float map( vec3 p ) { + vec4 isect; + + vec3 pt = p; + + float clampbox = box( pt, vec3( 1.0, 1.0, 1.0 ) ); + + vec3 r = mix( + fs( vec3( 4.7, 3.2, 4.3 ) + floor( ifsSeed ) ), + fs( vec3( 4.7, 3.2, 4.3 ) + floor( ifsSeed + 1.0 ) ), + fract( ifsSeed ) + ); + vec3 t = vec3( 4.8, 3.8, 4.2 ); + pt = ifs( pt, r, 0.2 * t ); + pt = ifs( pt, r.yzx, 0.1 * t.yzx ); + + float d = max( box( pt, vec3( 0.08 ) ), clampbox ); + + return d; +} + +vec3 normalFunc( vec3 p, float dd ) { + vec2 d = vec2( 0.0, dd ); + return normalize( vec3( + map( p + d.yxx ) - map( p - d.yxx ), + map( p + d.xyx ) - map( p - d.xyx ), + map( p + d.xxy ) - map( p - d.xxy ) + ) ); +} + +void main() { + vec2 p = ( gl_FragCoord.xy * 2.0 - resolution ) / resolution.y; + + vec3 rayOri = divideByW( inversePVM * vec4( p, 0.0, 1.0 ) ); + vec3 farPos = divideByW( inversePVM * vec4( p, 1.0, 1.0 ) ); + vec3 rayDir = normalize( farPos - rayOri ); + float rayLen = length( vPositionWithoutModel.xyz - rayOri ); + vec3 rayPos = rayOri + rayDir * rayLen; + float isect; + + for ( int i = 0; i < MARCH_ITER; i ++ ) { + isect = map( rayPos ); + rayLen += 0.5 * isect; + rayPos = rayOri + rayDir * rayLen; + + if ( abs( isect ) < 1E-3 ) { break; } + if ( rayLen > cameraNearFar.y ) { break; } + } + + if ( 0.01 < isect ) { + discard; + } + + vec3 modelNormal = normalize( normalMatrix * vec4( normalFunc( rayPos, 1E-3 ), 1.0 ) ).xyz; + + vec4 modelPos = modelMatrix * vec4( rayPos, 1.0 ); + vec4 projPos = projectionMatrix * viewMatrix * modelPos; // terrible + float depth = projPos.z / projPos.w; + gl_FragDepth = 0.5 + 0.5 * depth; + + #ifdef DEFERRED + fragPosition = vec4( modelPos.xyz, depth ); + fragNormal = vec4( modelNormal, 1.0 ); + + fragColor = vec4( vec3( 0.2 ), 1.0 ); + fragWTF = vec4( vec3( 0.6, 0.8, 0.0 ), 2 ); + #endif + + #ifdef DEPTH + float shadowDepth = linearstep( + cameraNearFar.x, + cameraNearFar.y, + length( cameraPos - modelPos.xyz ) + ); + fragColor = vec4( shadowDepth, shadowDepth * shadowDepth, shadowDepth, 1.0 ); + #endif +} diff --git a/src/shaders/ifs-piston.frag b/src/shaders/ifs-piston.frag index 66c0bed..ca56bc1 100644 --- a/src/shaders/ifs-piston.frag +++ b/src/shaders/ifs-piston.frag @@ -19,7 +19,7 @@ const float TAU = PI * 2.0; in vec4 vPositionWithoutModel; -#ifdef SHADOW +#ifdef DEPTH out vec4 fragColor; #endif @@ -216,11 +216,11 @@ void main() { #endif - #ifdef SHADOW + #ifdef DEPTH float shadowDepth = linearstep( cameraNearFar.x, cameraNearFar.y, - length( cameraPos - rayPos ) + length( cameraPos - modelPos.xyz ) ); fragColor = vec4( shadowDepth, shadowDepth * shadowDepth, shadowDepth, 1.0 ); #endif diff --git a/src/shaders/modules/doAnalyticLighting.glsl b/src/shaders/modules/doAnalyticLighting.glsl new file mode 100644 index 0000000..b9f747f --- /dev/null +++ b/src/shaders/modules/doAnalyticLighting.glsl @@ -0,0 +1,38 @@ +const float PI = 3.14159265359; +const float EPSILON = 1E-3; +const vec3 DIELECTRIC_SPECULAR = vec3( 0.04 ); +const vec3 ONE_SUB_DIELECTRIC_SPECULAR = 1.0 - DIELECTRIC_SPECULAR; + +#pragma glslify: brdfLambert = require( ./brdfLambert.glsl ); +#pragma glslify: brdfSpecularGGX = require( ./brdfSpecularGGX.glsl ); + +vec3 doAnalyticLighting( + vec3 V, + vec3 L, // MUST NOT be normalized + vec3 N, + vec3 color, + float roughness, + float metallic +) { + vec3 albedo = mix( color * ONE_SUB_DIELECTRIC_SPECULAR, vec3( 0.0 ), metallic ); + vec3 f0 = mix( DIELECTRIC_SPECULAR, color, metallic ); + + V = normalize( V ); + float lenL = length( L ); + L = normalize( L ); + vec3 H = normalize( V + L ); + + float NdotL = clamp( dot( N, L ), EPSILON, 1.0 ); + float NdotH = clamp( dot( N, H ), EPSILON, 1.0 ); + float VdotH = clamp( dot( V, H ), EPSILON, 1.0 ); + float NdotV = clamp( dot( N, V ), EPSILON, 1.0 ); + + float decayL = 1.0 / ( lenL * lenL ); + + vec3 diffuse = brdfLambert( f0, albedo, VdotH ); + vec3 spec = brdfSpecularGGX( f0, roughness, VdotH, NdotL, NdotV, NdotH ); + + return PI * decayL * NdotL * ( diffuse + spec ); +} + +#pragma glslify: export(doAnalyticLighting) diff --git a/src/shaders/modules/doShadowMapping.glsl b/src/shaders/modules/doShadowMapping.glsl new file mode 100644 index 0000000..7ed9a36 --- /dev/null +++ b/src/shaders/modules/doShadowMapping.glsl @@ -0,0 +1,40 @@ +const float PI = 3.14159265359; +const float EPSILON = 1E-3; + +float doShadowMapping( + vec3 L, // MUST NOT be normalized + vec3 N, // have to be normalized + vec4 tex, + vec2 lightP, // lightPV * vec4( isect.position, 1.0 ), then its xy / w + vec2 lightNearFar, + float spotness +) { + float depth = clamp( ( length( L ) - lightNearFar.x ) / ( lightNearFar.y - lightNearFar.x ), 0.0, 1.0 ); // linearstep + + L = normalize( L ); + float NdotL = clamp( dot( N, L ), EPSILON, 1.0 ); + + float shadow = mix( + 1.0, + smoothstep( 1.0, 0.5, length( lightP ) ), + spotness + ); + + float bias = 0.0001 + 0.0001 * ( 1.0 - NdotL ); + depth -= bias; + + float variance = clamp( tex.y - tex.x * tex.x, 0.0, 1.0 ); + float md = depth - tex.x; + float p = variance / ( variance + md * md ); + p = clamp( ( p - 0.2 ) / 0.8, 0.0, 1.0 ); // linearstep + + shadow *= mix( + md < 0.0 ? 1.0 : p, + 1.0, + smoothstep( 0.8, 1.0, max( abs( lightP.x ), abs( lightP.y ) ) ) // edgeclip + ); + + return shadow; +} + +#pragma glslify: export(doShadowMapping) diff --git a/src/shaders/noise-voxels.frag b/src/shaders/noise-voxels.frag new file mode 100644 index 0000000..9e3e3b8 --- /dev/null +++ b/src/shaders/noise-voxels.frag @@ -0,0 +1,29 @@ +#version 300 es + +precision highp float; + +in vec3 vNormal; +in vec3 vPositionForNoise; +in vec4 vPosition; + +#ifdef DEFERRED + layout (location = 0) out vec4 fragPosition; + layout (location = 1) out vec4 fragNormal; + layout (location = 2) out vec4 fragColor; + layout (location = 3) out vec4 fragWTF; +#endif + +uniform float time; + +#pragma glslify: cyclicNoise = require( ./modules/cyclicNoise ); + +void main() { + float roughness = 0.6 + 0.1 * cyclicNoise( 1.0 * vPositionForNoise.xyz ).x; + + #ifdef DEFERRED + fragPosition = vPosition; + fragNormal = vec4( normalize( vNormal ), 1.0 ); + fragColor = vec4( vec3( 0.1, 0.1, 0.12 ), 1.0 ); + fragWTF = vec4( vec3( roughness, 0.77, 0.0 ), 2 ); + #endif +} diff --git a/src/shaders/noise-voxels.vert b/src/shaders/noise-voxels.vert new file mode 100644 index 0000000..8c60faa --- /dev/null +++ b/src/shaders/noise-voxels.vert @@ -0,0 +1,41 @@ +#version 300 es + +#define fs(i) (fract(sin((i)*114.514)*1919.810)) + +layout (location = 0) in vec3 position; +layout (location = 1) in vec3 normal; +layout (location = 2) in vec3 instancePos; + +out vec3 vNormal; +out vec3 vPositionForNoise; +out vec4 vPosition; + +uniform float phase; +uniform vec2 resolution; +uniform mat4 projectionMatrix; +uniform mat4 viewMatrix; +uniform mat4 modelMatrix; +uniform mat4 normalMatrix; + +#pragma glslify: noise = require( ./-simplex4d ); + +void main() { + vNormal = normalize( ( normalMatrix * vec4( normal, 1.0 ) ).xyz ); + + float good = clamp( + 0.5 + noise( vec4( 0.3 * instancePos, phase ) ), + 0.0, + 1.0 + ); + vPosition = vec4( good * position / 8.0, 1.0 ); + vPosition.xyz += mix( vec3( -1.0 ), vec3( 1.0 ), instancePos / 7.0 ); + vPosition = modelMatrix * vPosition; + + vPositionForNoise = position + 2.0 * instancePos; + + vec4 outPos = projectionMatrix * viewMatrix * vPosition; + outPos.x *= resolution.y / resolution.x; + gl_Position = outPos; + + vPosition.w = outPos.z / outPos.w; +} diff --git a/src/shaders/phantom.frag b/src/shaders/phantom.frag index 7e4b021..9161c6e 100644 --- a/src/shaders/phantom.frag +++ b/src/shaders/phantom.frag @@ -12,8 +12,8 @@ const float TAU = PI * 2.0; out vec4 fragColor; -uniform float frameCount; uniform float time; +uniform float amp; uniform vec2 resolution; uniform mat4 viewMatrix; uniform mat4 projectionMatrix; @@ -93,7 +93,7 @@ void main() { float flicker = step( 0.5, fract( 30.0 * time ) ); vec3 col = 0.3 + 0.3 * sin( 3.5 + 1.0 * accum + vec3( 0.0, 2.0, 4.0 ) ); - col *= ( 0.5 + 0.1 * flicker ) * accum; + col *= amp * ( 0.5 + 0.1 * flicker ) * accum; fragColor = vec4( col, 1.0 ); } diff --git a/src/shaders/post.frag b/src/shaders/post.frag index 4e99fe8..02f9372 100644 --- a/src/shaders/post.frag +++ b/src/shaders/post.frag @@ -70,8 +70,9 @@ vec3 liftGammaGain( vec3 rgb ) { void main() { vec2 uv = vUv; - if ( mosaicAmp > 1.0 ) { - uv = lofi( uv - 0.5, mosaicAmp / resolution ) + mosaicAmp * 0.5 / resolution + 0.5; + float mosaic = mosaicAmp * resolution.y; + if ( mosaic > 1.0 ) { + uv = lofi( uv - 0.5, mosaic / resolution ) + mosaic * 0.5 / resolution + 0.5; } vec2 p = ( uv * resolution * 2.0 - resolution ) / resolution.y; diff --git a/src/shaders/rect-torus.frag b/src/shaders/rect-torus.frag new file mode 100644 index 0000000..dcab252 --- /dev/null +++ b/src/shaders/rect-torus.frag @@ -0,0 +1,33 @@ +#version 300 es + +#define lofi(i,m) (floor((i)/(m))*(m)) + +precision highp float; + +const int MTL_PBR = 2; + +in vec3 vNormal; +in vec4 vPosition; +in vec4 vPositionWithoutModel; + +#ifdef DEFERRED + layout (location = 0) out vec4 fragPosition; + layout (location = 1) out vec4 fragNormal; + layout (location = 2) out vec4 fragColor; + layout (location = 3) out vec4 fragWTF; +#endif + +uniform float time; + +#pragma glslify: cyclicNoise = require( ./modules/cyclicNoise ); + +void main() { + float rough = 0.2 + 0.2 * cyclicNoise( 4.0 * vPositionWithoutModel.xyz ).x; + + #ifdef DEFERRED + fragPosition = vPosition; + fragNormal = vec4( normalize( vNormal ), 1.0 ); + fragColor = vec4( vec3( 0.1 ), 1.0 ); + fragWTF = vec4( vec3( 0.2 + 0.5 * rough, 0.9, 0.0 ), MTL_PBR ); + #endif +} diff --git a/src/shaders/rect-torus.vert b/src/shaders/rect-torus.vert new file mode 100644 index 0000000..2b34aaa --- /dev/null +++ b/src/shaders/rect-torus.vert @@ -0,0 +1,43 @@ +#version 300 es + +#define fs(i) (fract(sin((i)*114.514)*1919.810)) + +const float PI = 3.14159265; +const float TAU = 6.28318531; + +layout (location = 0) in vec3 position; +layout (location = 1) in vec3 normal; +layout (location = 2) in float instanceId; + +out vec3 vNormal; +out vec4 vPositionWithoutModel; +out vec4 vPosition; + +uniform vec2 resolution; +uniform mat4 projectionMatrix; +uniform mat4 viewMatrix; +uniform mat4 modelMatrix; +uniform mat4 normalMatrix; + +mat2 rotate2D( float t ) { + return mat2( cos( t ), sin( t ), -sin( t ), cos( t ) ); +} + +void main() { + mat2 rot = rotate2D( 0.25 * instanceId * TAU ); + + vNormal = normal; + vNormal.zx = rot * vNormal.zx; + vNormal = normalize( ( normalMatrix * vec4( vNormal, 1.0 ) ).xyz ); + + vPositionWithoutModel = vec4( vec3( 3.1, 0.1, 0.1 ) * position + vec3( 0.0, 0.0, 3.0 ), 1.0 ); + vPositionWithoutModel.zx = rot * vPositionWithoutModel.zx; + + vPosition = modelMatrix * vPositionWithoutModel; + + vec4 outPos = projectionMatrix * viewMatrix * vPosition; + outPos.x *= resolution.y / resolution.x; + gl_Position = outPos; + + vPosition.w = outPos.z / outPos.w; +} diff --git a/src/shaders/rings.vert b/src/shaders/rings.vert index 3199166..834e1e9 100644 --- a/src/shaders/rings.vert +++ b/src/shaders/rings.vert @@ -9,6 +9,7 @@ layout (location = 2) in float instanceId; out vec4 vPosition; out vec3 vNormal; +uniform float begin; uniform float time; uniform vec2 resolution; uniform mat4 projectionMatrix; @@ -36,7 +37,10 @@ void main() { vNormal = normalize( ( normalMatrix * vec4( normal, 1.0 ) ).xyz ); - vPosition = vec4( mix( 2.0, 2.7, random() ) * position, 1.0 ); + float radius = mix( 2.0, 2.7, random() ); + radius *= 1.0 - exp( -10.0 * max( 0.0, begin - 0.2 * random() ) ); + + vPosition = vec4( radius * position, 1.0 ); vPosition.xyz += mix( 0.005, 0.01, random() ) * normal; vPosition.y += sin( random() * time + random() * vPosition.x + TAU * random() ) * 0.2 * random(); vPosition.y += sin( random() * time + random() * vPosition.z + TAU * random() ) * 0.2 * random(); diff --git a/src/shaders/serial-decode.frag b/src/shaders/serial-decode.frag index e4fde18..04a7d01 100644 --- a/src/shaders/serial-decode.frag +++ b/src/shaders/serial-decode.frag @@ -41,7 +41,7 @@ void main() { // back to rgb vec3 col = YCBCR_TO_RGB * vec3( - saturate( 1.2 * ( linearstep( CHROMA_AMP, 1.0 - CHROMA_AMP, y ) - 0.5 ) + 0.5 ), + saturate( 0.07 + 1.2 * ( linearstep( CHROMA_AMP, 1.0 - CHROMA_AMP, y ) - 0.5 ) + 0.5 ), PI * cbcr / CHROMA_AMP ); diff --git a/src/shaders/shading.frag b/src/shaders/shading.frag index cdedac8..41c92a2 100644 --- a/src/shaders/shading.frag +++ b/src/shaders/shading.frag @@ -48,9 +48,9 @@ uniform sampler2D samplerRandom; // == commons ====================================================================================== #pragma glslify: prng = require( ./-prng ); -#pragma glslify: brdfLambert = require( ./modules/brdfLambert.glsl ); -#pragma glslify: brdfSpecularGGX = require( ./modules/brdfSpecularGGX.glsl ); #pragma glslify: importanceSampleGGX = require( ./modules/importanceSampleGGX.glsl ); +#pragma glslify: doAnalyticLighting = require( ./modules/doAnalyticLighting.glsl ); +#pragma glslify: doShadowMapping = require( ./modules/doShadowMapping.glsl ); vec3 catColor( float _p ) { return 0.5 + 0.5 * vec3( @@ -170,36 +170,31 @@ vec3 shadePBR( Isect isect ) { for ( int iLight = 0; iLight < 8; iLight ++ ) { if ( iLight >= lightCount ) { break; } - // calc vectors vec3 L = lightPos[ iLight ] - isect.position; - float lenL = length( L ); - L = normalize( L ); - vec3 H = normalize( V + L ); - float NdotL = clamp( dot( isect.normal, L ), EPSILON, 1.0 ); - float NdotH = clamp( dot( isect.normal, H ), EPSILON, 1.0 ); - float VdotH = clamp( dot( V, H ), EPSILON, 1.0 ); - - float decayL = 1.0 / ( lenL * lenL ); + // shading + vec3 shade = doAnalyticLighting( + V, + L, + isect.normal, + isect.color, + roughness, + metallic + ) * lightColor[ iLight ] * ao; // fetch shadowmap + spot lighting vec4 lightProj = lightPV[ iLight ] * vec4( isect.position, 1.0 ); vec2 lightP = lightProj.xy / lightProj.w; - float shadow = mix( - 1.0, - smoothstep( 1.0, 0.5, length( lightP ) ), + shade *= doShadowMapping( + L, + isect.normal, + fetchShadowMap( iLight, 0.5 + 0.5 * lightP ), + lightP, + lightNearFar[ iLight ], lightParams[ iLight ].x ); - shadow *= castShadow( iLight, lightP * 0.5 + 0.5, isect, NdotL ); - - // do shading - vec3 diffuse = brdfLambert( f0, albedo, VdotH ); - vec3 spec = brdfSpecularGGX( f0, roughness, VdotH, NdotL, NdotV, NdotH ); - - vec3 shade = PI * lightColor[ iLight ] * decayL * ao * shadow * NdotL * ( diffuse + spec ); - color += shade; } @@ -208,16 +203,16 @@ vec3 shadePBR( Isect isect ) { // diffuse ibl vec2 uvEnvDiffuse = vec2( - 0.5 + atan( nEnvDiffuse.x, -nEnvDiffuse.z ) / TAU, + 0.5 + atan( nEnvDiffuse.x, nEnvDiffuse.z ) / TAU, 0.5 + atan( nEnvDiffuse.y, length( nEnvDiffuse.zx ) ) / PI ); vec3 texEnvDiffuse = sampleEnvNearest( uvEnvDiffuse, 4.0 ).rgb; color += ao * texEnvDiffuse * albedo; // reflective ibl - vec3 reflEnvReflective = reflect( V, isect.normal ); + vec3 reflEnvReflective = reflect( -V, isect.normal ); vec2 uvEnvReflective = vec2( - 0.5 + atan( reflEnvReflective.x, -reflEnvReflective.z ) / TAU, + 0.5 + atan( reflEnvReflective.x, reflEnvReflective.z ) / TAU, 0.5 + atan( reflEnvReflective.y, length( reflEnvReflective.zx ) ) / PI ); vec2 brdfEnvReflective = texture( samplerIBLLUT, vec2( NdotV, roughness ) ).xy; @@ -245,7 +240,7 @@ void main() { isect.screenUv = vUv; isect.position = tex0.xyz; isect.depth = tex0.w; - isect.normal = tex1.xyz; + isect.normal = normalize( tex1.xyz ); isect.color = tex2.rgb; isect.materialId = int( tex3.w + 0.5 ); isect.materialParams = tex3.xyz; @@ -272,9 +267,9 @@ void main() { color = shadePBR( isect ); // really really cheap full spectrum - vec3 refrEnvRefractive = refract( V, isect.normal, 1.0 / 2.56 ); + vec3 refrEnvRefractive = refract( -V, isect.normal, 1.0 / 2.56 ); vec2 uvEnvRefractive = vec2( - 0.5 + atan( refrEnvRefractive.x, -refrEnvRefractive.z ) / TAU, + 0.5 + atan( refrEnvRefractive.x, refrEnvRefractive.z ) / TAU, 0.5 + atan( refrEnvRefractive.y, length( refrEnvRefractive.zx ) ) / PI ); vec3 texEnvRefractive = sampleEnvLinear( uvEnvRefractive, 0.5 ).rgb; @@ -283,7 +278,6 @@ void main() { } - float lenV = length( cameraPos - isect.position ); color *= exp( -0.4 * max( lenV - 3.0, 0.0 ) ); // color = 0.5 + 0.5 * isect.normal; @@ -291,7 +285,7 @@ void main() { // color = vec3( 0.5, 0.2, 0.9 ) * ( 1.0 - texture( samplerAo, isect.screenUv ).xyz ); // color = mix( // color, - // vec3( 0.96 ) * smoothstep( 0.9, 0.1, texture( samplerAo, isect.screenUv ).xyz ), + // vec3( 0.96 ) * smoothstep( 0.5, 0.9, texture( samplerAo, isect.screenUv ).xyz ), // 1.0 // ); diff --git a/src/shaders/tetrahedron.frag b/src/shaders/tetrahedron.frag new file mode 100644 index 0000000..6a6a5e2 --- /dev/null +++ b/src/shaders/tetrahedron.frag @@ -0,0 +1,134 @@ +#version 300 es + +precision highp float; + +#define fs(i) (fract(sin((i)*114.514)*1919.810)) +#define saturate(x) clamp(x,0.,1.) +#define linearstep(a,b,x) saturate(((x)-(a))/((b)-(a))) + +const float PI = 3.14159265; +const float TAU = PI * 2.0; +const float foldcos = cos( PI / 3.0 ); +const float foldrem = sqrt( 0.75 - foldcos * foldcos ); +const vec3 foldvec = vec3( -0.5, -foldcos, foldrem ); +const vec3 foldface = vec3( 0.0, foldrem, foldcos ); + +#ifdef DEFERRED + layout (location = 0) out vec4 fragPosition; + layout (location = 1) out vec4 fragNormal; + layout (location = 2) out vec4 fragColor; + layout (location = 3) out vec4 fragWTF; +#endif + +in vec4 vPositionWithoutModel; + +#ifdef DEPTH + out vec4 fragColor; +#endif + +uniform float distort; +uniform float time; +uniform vec2 resolution; +uniform vec2 cameraNearFar; +uniform vec3 cameraPos; +uniform mat4 normalMatrix; +uniform mat4 modelMatrix; +uniform mat4 viewMatrix; +uniform mat4 projectionMatrix; +uniform mat4 inversePVM; +uniform sampler2D samplerRandom; +uniform sampler2D samplerRandomStatic; +uniform sampler2D samplerCapture; + +vec3 divideByW( vec4 v ) { + return v.xyz / v.w; +} + +#pragma glslify: noise = require( ./-simplex4d ); +#pragma glslify: orthBasis = require( ./modules/orthBasis ); + +vec3 fold( vec3 p ) { + for ( int i = 0; i < 5; i ++ ) { + p.xy = abs( p.xy ); + p -= 2.0 * min( dot( foldvec, p ), 0.0 ) * foldvec; + } + return p; +} + +float distFunc( vec3 p ) { + vec3 pt = p; + pt = fold( pt ); + float d = dot( pt, foldface ) - 0.36; + + d += ( 0.001 + 0.02 * distort ) * noise( + vec4( 8.0 * p.xyz, 8.0 * time ) + ); + + return d; +} + +vec3 normalFunc( vec3 p, float dd ) { + vec2 d = vec2( 0.0, dd ); + return normalize( vec3( + distFunc( p + d.yxx ) - distFunc( p - d.yxx ), + distFunc( p + d.xyx ) - distFunc( p - d.xyx ), + distFunc( p + d.xxy ) - distFunc( p - d.xxy ) + ) ); +} + +void main() { + vec2 p = ( gl_FragCoord.xy * 2.0 - resolution ) / resolution.y; + + vec3 rayOri = divideByW( inversePVM * vec4( p, 0.0, 1.0 ) ); + vec3 farPos = divideByW( inversePVM * vec4( p, 1.0, 1.0 ) ); + vec3 rayDir = normalize( farPos - rayOri ); + float rayLen = length( vPositionWithoutModel.xyz - rayOri ); + vec3 rayPos = rayOri + rayDir * rayLen; + float dist; + + int MARCH_ITER; + + #ifdef DEFERRED + MARCH_ITER = 50; + #endif + + #ifdef DEPTH + MARCH_ITER = 30; + #endif + + for ( int i = 0; i < MARCH_ITER; i ++ ) { + dist = distFunc( rayPos ); + rayLen += 0.5 * dist; + rayPos = rayOri + rayDir * rayLen; + + if ( abs( dist ) < 1E-3 ) { break; } + if ( rayLen > cameraNearFar.y ) { break; } + } + + if ( 0.01 < dist ) { + discard; + } + + vec3 modelNormal = normalize( normalMatrix * vec4( normalFunc( rayPos, 1E-3 ), 1.0 ) ).xyz; + + vec4 modelPos = modelMatrix * vec4( rayPos, 1.0 ); + vec4 projPos = projectionMatrix * viewMatrix * modelPos; // terrible + float depth = projPos.z / projPos.w; + gl_FragDepth = 0.5 + 0.5 * depth; + + #ifdef DEFERRED + fragPosition = vec4( modelPos.xyz, depth ); + fragNormal = vec4( modelNormal, 1.0 ); + fragColor = vec4( vec3( 0.2 ), 1.0 ); + fragWTF = vec4( vec3( 0.05 , 0.93, 0.0 ), 2 ); + #endif + + #ifdef DEPTH + float shadowDepth = linearstep( + cameraNearFar.x, + cameraNearFar.y, + length( cameraPos - modelPos.xyz ) + ); + fragColor = vec4( shadowDepth, shadowDepth * shadowDepth, shadowDepth, 1.0 ); + #endif +} diff --git a/src/shaders/trails-compute.frag b/src/shaders/trails-compute.frag index 5d0d6f7..f99b5ea 100644 --- a/src/shaders/trails-compute.frag +++ b/src/shaders/trails-compute.frag @@ -15,6 +15,7 @@ layout (location = 0) out vec4 fragCompute0; layout (location = 1) out vec4 fragCompute1; uniform bool init; +uniform bool shouldUpdate; uniform float time; uniform float beat; uniform float trails; @@ -51,7 +52,7 @@ vec4 sampleRandom( vec2 _uv ) { } #pragma glslify: prng = require( ./-prng ); -#pragma glslify: noise = require( ./-simplex4d ); +#pragma glslify: cyclicNoise = require( ./modules/cyclicNoise ); vec3 randomSphere( inout vec4 seed ) { vec3 v; @@ -107,11 +108,16 @@ void main() { // == if it is not head of particles ============================================================= if ( 1.0 < gl_FragCoord.x ) { - uv.x -= 1.0 / resolution.x; + if ( shouldUpdate ) { + uv.x -= 1.0 / resolution.x; + } + vec4 tex0 = texture( samplerCompute0, uv ); vec4 tex1 = texture( samplerCompute1, uv ); - tex0.w = saturate( tex0.w - 1.0 / trailLength ); // decrease the life + if ( shouldUpdate ) { + tex0.w = saturate( tex0.w - 1.0 / trailLength ); // decrease the life + } fragCompute0 = tex0; fragCompute1 = tex1; @@ -157,11 +163,7 @@ void main() { // == update particles =========================================================================== // noise field - vel += 40.0 * vec3( - noise( vec4( pos.xyz, 1.485 + sin( time * 0.1 ) + noisePhase ) ), - noise( vec4( pos.xyz, 3.485 + sin( time * 0.1 ) + noisePhase ) ), - noise( vec4( pos.xyz, 5.485 + sin( time * 0.1 ) + noisePhase ) ) - ) * dt; + vel += 40.0 * cyclicNoise( pos ) * dt; // resistance vel *= exp( -10.0 * dt ); diff --git a/src/shaders/trails-render.frag b/src/shaders/trails-render.frag index 00d6e67..9677759 100644 --- a/src/shaders/trails-render.frag +++ b/src/shaders/trails-render.frag @@ -34,11 +34,11 @@ mat2 rotate2D( float _t ) { void main() { if ( vColor.a < 0.0 ) { discard; } - float emissive = 5.0; + float emissive = 0.0; // emissive *= 0.5 + 0.5 * sin( TAU * vRandom.z + 20.0 * time ); fragPosition = vPosition; fragNormal = vec4( vNormal, 1.0 ); fragColor = vColor; - fragWTF = vec4( vec3( 0.9, 0.9, emissive ), MTL_PBR ); + fragWTF = vec4( vec3( 0.4, 0.1, emissive ), MTL_PBR ); } diff --git a/src/shaders/wobbleball.frag b/src/shaders/wobbleball.frag index 04a8696..df5fe33 100644 --- a/src/shaders/wobbleball.frag +++ b/src/shaders/wobbleball.frag @@ -7,10 +7,6 @@ precision highp float; #define linearstep(a,b,x) saturate(((x)-(a))/((b)-(a))) const int MARCH_ITER = 90; -const int MTL_UNLIT = 1; -const int MTL_PBR = 2; -const int MTL_GRADIENT = 3; -const int MTL_IRIDESCENT = 4; const float PI = 3.14159265; const float TAU = PI * 2.0; @@ -23,7 +19,7 @@ const float TAU = PI * 2.0; in vec4 vPositionWithoutModel; -#ifdef SHADOW +#ifdef DEPTH out vec4 fragColor; #endif @@ -143,14 +139,14 @@ void main() { fragPosition = vec4( modelPos.xyz, depth ); fragNormal = vec4( modelNormal, 1.0 ); fragColor = vec4( vec3( 0.3 ), 1.0 ); - fragWTF = vec4( vec3( 1.0, 0.1, 0.0 ), MTL_PBR ); + fragWTF = vec4( vec3( 1.0, 0.1, 0.0 ), 2 ); #endif - #ifdef SHADOW + #ifdef DEPTH float shadowDepth = linearstep( cameraNearFar.x, cameraNearFar.y, - length( cameraPos - rayPos ) + length( cameraPos - modelPos.xyz ) ); fragColor = vec4( shadowDepth, shadowDepth * shadowDepth, shadowDepth, 1.0 ); #endif diff --git a/src/utils/setLightUniforms.ts b/src/utils/setLightUniforms.ts new file mode 100644 index 0000000..c9dc28c --- /dev/null +++ b/src/utils/setLightUniforms.ts @@ -0,0 +1,57 @@ +import { LightEntity } from '../entities/LightEntity'; +import { Material } from '../heck/Material'; + +export function setLightUniforms( + material: Material, + lights: LightEntity[], + frameCount: number, +): void { + const activeLights = lights.filter( ( light ) => ( + frameCount === light.lastUpdateFrame + ) ); + + material.addUniform( + 'lightCount', + '1i', + activeLights.length, + ); + + material.addUniformVector( + 'lightNearFar', + '2fv', + activeLights.map( ( light ) => [ light.camera.near, light.camera.far ] ).flat(), + ); + + material.addUniformVector( + 'lightPos', + '3fv', + activeLights.map( ( light ) => light.globalTransformCache.position.elements ).flat(), + ); + + material.addUniformVector( + 'lightColor', + '3fv', + activeLights.map( ( light ) => light.color ).flat(), + ); + + material.addUniformVector( + 'lightParams', + '4fv', + activeLights.map( ( light ) => [ light.spotness, 0.0, 0.0, 0.0 ] ).flat(), + ); + + material.addUniformMatrixVector( + 'lightPV', + 'Matrix4fv', + activeLights.map( ( light ) => ( + light.camera.projectionMatrix.multiply( + light.globalTransformCache.matrix.inverse! + ).elements + ) ).flat(), + ); + + material.addUniformTextureArray( + 'samplerShadow', + activeLights.map( ( light ) => light.shadowMap.texture ), + ); +} diff --git a/webpack.config.js b/webpack.config.js index cae720a..abf16d3 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -33,6 +33,10 @@ const terserOptions = { ] }, }, + format: { + ascii_only: true, + ecma: 2020, + }, module: true, toplevel: true, };