Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

coma Creators session vol.2

3,863 views

Published on

Published in: Technology, Art & Photos

coma Creators session vol.2

  1. 1. coma Creator's session vol.2 田所 淳 1/13, 2014.
  2. 2. 自己紹介
  3. 3. 自己紹介 ‣ 田所淳 (たどころ あつし) ‣ クリエイティブ・コーダー? ‣ 大学非常勤講師 (多摩美術大学、東京藝術大学) など
  4. 4. 自己紹介 ‣ http://yoppa.org/ screenshot_679
  5. 5. 自己紹介 ‣ 『Beyond Interaction[改訂第2版] -クリエイティブ・コーディ ングのためのopenFrameworks実践ガイド』絶賛販売中!! screenshot_679
  6. 6. 今日の内容
  7. 7. 今日の内容 ‣ ライブ種明かし編!! ‣ coma discotheque ver 0.03 でのライブ ‣ http://www.youtube.com/watch?v=gbVPbc9faXw
  8. 8. ライブのおおまかなシステム構成 ‣ だいたいこんな感じ 映像 音 openFrameworks SuperCollider GLSL
  9. 9. ライブのおおまかなシステム構成 ‣ だいたいこんな感じ ! ‣ openFrameworks : ‣ 全体の構造、操作(Key, Mouse) ! ‣ GLSL : ‣ グラフィック、アニメーション ! ‣ SuperCollider : ‣ 音
  10. 10. ライブのおおまかなシステム構成 ‣ openFrameworks + GLSL + SuperCollider ‣ それぞれの内容を、紹介していきます!!
  11. 11. openFrameworks
  12. 12. openFrameworks ‣ openFrameworks (2005 - ) ‣ Processingの思想を受けつぎつつ、さらに高速化、拡張性を追 求した環境 ‣ C++による実装 ‣ http://www.openframeworks.cc/
  13. 13. openFrameworks ‣ openFrameworksを何に使用していたか? ! ‣ マウスやキーボードの入力 ‣ 全体の構造 (シーンの切り替え)
  14. 14. openFrameworks ‣ openFrameworksを何に使用していたか? ! ‣ マウスやキーボードの入力 ‣ 全体の構造 (シーンの切り替え) ← こちらの説明
  15. 15. openFrameworks + ofxStateMachine
  16. 16. openFrameworks + ofxStateMachine ‣ 今回のプロジェクトの構造 ‣ 複数のシーン(状態)の間を自由に移動したい! Scene A Scene C Scene B Scene D
  17. 17. openFrameworks + ofxStateMachine ‣ mainApp内で、条件によって場合分け? … 面倒くさい void testApp::update(){ switch (state) { case 1: // ... 状態1の処理 ... // break; case 2: // ... 状態2の処理 ... // break; case 3: // ... 状態3の処理 ... // break; } } // ...
  18. 18. openFrameworks + ofxStateMachine ‣ 便利なアドオン紹介 ‣ ofxStateMachine ‣ https://github.com/neilmendoza/ofxStateMachine
  19. 19. openFrameworks + ofxStateMachine ‣ ofxStateMachine ‣ 有限状態機械 (finite state machine)を使用したデザインパター ンを実装 Finite State Machine 有限状態機械…??
  20. 20. openFrameworks + ofxStateMachine ‣ 有限状態機械 → oFで解釈すると… ‣ 複数の状態(State)をテンプレートから生成 StateA StateB StateC State Template
  21. 21. openFrameworks + ofxStateMachine ‣ 有限状態機械 → oFで解釈すると… ‣ それぞれの状態(State)を相互に行き来可能 StateA StateB StateC
  22. 22. openFrameworks + ofxStateMachine ‣ 使い方は簡単! ‣ ofxState : それぞれの状態のテンプレートとなるクラス、継承 して使用する ‣ SharedData : 全てのクラスで共有するデータ ofxState 継承 State A State B State C SharedData 参照
  23. 23. openFrameworks + ofxStateMachine ‣ ofxStateには、ofBaseApp (つまりtestAppクラス) で定義され ているメソッドが組込まれている ‣ setup(), update(), draw(), mouseReleased(), keyPressed() … ! ‣ つまり、一つのプロジェクトの中に、沢山のoFアプリが入って いるような感覚でコーディング可能!! project ofBaseApp ofBaseApp ofBaseApp
  24. 24. openFrameworks + ofxStateMachine ‣ Stateのテンプレート class MyState : public itg::ofxState<> { public: void setup(); void update(); void draw(); ! ! }; ... string getName();
  25. 25. openFrameworks + ofxStateMachine ‣ Stateのテンプレート class MyState : public itg::ofxState<> { public: void setup(); void update(); void draw(); ! ! }; ... string getName(); ← ココ重要!
  26. 26. openFrameworks + ofxStateMachine ‣ 各Stateは、名前を呼ぶと表示される ‣ 《Stateのインスタンス》.getName() で名前を返すようにする ‣ testAppから名前を呼ぶと、Stateが選択される testApp State A state_a State B state_b State C state_c
  27. 27. openFrameworks + ofxStateMachine ‣ 各Stateは、名前を呼ぶと表示される ‣ 《Stateのインスタンス》.getName() で名前を返すようにする ‣ testAppから名前を呼ぶと、Stateが選択される changeState( state_b ) testApp State A state_a State B state_b State C state_c
  28. 28. openFrameworks + ofxStateMachine ‣ 各Stateは、名前を呼ぶと表示される ‣ 《Stateのインスタンス》.getName() で名前を返すようにする ‣ testAppから名前を呼ぶと、Stateが選択される changeState( state_b ) testApp State A 表示 state_a State B state_b State C state_c
  29. 29. ofxStateMachine Demo: コード実例でみてみる!
  30. 30. GLSL (Shader)
  31. 31. GLSL (Shader) ‣ 今回の画面の表示は、全てGLSL (OpenGL Shading Language) をつかった ‣ とっつきずらいが、綺麗、速い!
  32. 32. GLSL (Shader) ‣ GLSLを試行錯誤したい!! ‣ addonを作成しました → ofxGLSLSandbox ‣ https://github.com/tado/ofxGLSLSandbox
  33. 33. GLSL (Shader) ‣ ofxGLSLSandbox ‣ ウリは、Live Edit機能!! ‣ プログラムを動作させながら、Shaderを書き換えできる ‣ やりかたは後で
  34. 34. GLSL (Shader) ‣ ofxGLSLSandbox ‣ ウリは、Live Edit機能!! ‣ プログラムを動作させながら、Shaderを書き換えできる ‣ やりかたは後で
  35. 35. GLSL (Shader) ‣ ofxGLSLSandboxで、Shaderを書きながら基本を学ぼう!
  36. 36. GLSL (Shader) ‣ まずは、基本形 uniform float time; uniform vec2 mouse; uniform vec2 resolution; ! void main(void){ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); // Red. }
  37. 37. GLSL (Shader) ‣ 真っ赤な画面になるはず ‣ gl_FlagColor → 全てのピクセルの色を指定している ‣ vec4(…); → 色を指定(RGBA)
  38. 38. GLSL (Shader) ‣ 上にある3つの「uniform」は何か? ‣ openFrameworksから渡されている値 ! ‣ uniform float time; → 経過時間(Second) ‣ uniform vec2 mouse; → マウスの位置 (x, y) ‣ uniform vec2 resolution; → 画面の大きさ (x, y) ! ‣ 手始めに、resolutionをつかってみる
  39. 39. GLSL (Shader) ‣ 座標の値を利用してグラデーションをつくる uniform float time; uniform vec2 mouse; uniform vec2 resolution; ! void main(void){ float br = gl_FragCoord.x / resolution.x; gl_FragColor = vec4(br, br, br, 1.0); }
  40. 40. GLSL (Shader) ‣ x軸方向へのグラデーションになる
  41. 41. GLSL (Shader) ‣ gl_FragCoord → ウィンドウ上でのフラグメントの位置(x, y) ‣ gl_FragCoord.x : x方向 ‣ gl_FragCoord.y : y方向 ‣ gl_FragCoord.xy : 2次元平面 (vec2)
  42. 42. GLSL (Shader) ‣ RGBごとに別の値に uniform float time; uniform vec2 mouse; uniform vec2 resolution; ! void main(void){ vec3 color; color.r = gl_FragCoord.x / resolution.x; color.g = 0.2; color.b = gl_FragCoord.y / resolution.y; gl_FragColor = vec4(color, 1.0); }
  43. 43. GLSL (Shader) ‣ カラフルなグラデーション完成!!
  44. 44. GLSL (Shader) ‣ 次に時間を操作してみる ‣ timeを使用 ! ‣ 時間によって色の濃度を変化させるとどうなるか? ‣ 定期的な色の変化を、時間とsin関数で生成してみる
  45. 45. GLSL (Shader) ‣ 時間変化 uniform float time; uniform vec2 mouse; uniform vec2 resolution; ! void main(void){ vec3 color; color.r = sin(time * 1.0); color.g = sin(time * 1.7); color.b = sin(time * 2.3); gl_FragColor = vec4(color, 1.0); }
  46. 46. GLSL (Shader) ‣ 時間によって、色が変化していくはず!
  47. 47. GLSL (Shader) ‣ sin関数に、gl_FragCoord(座標) を入れるとどうなるか? ‣ 実験!!
  48. 48. GLSL (Shader) ‣ gl_FragCoordとSin関数 uniform float time; uniform vec2 mouse; uniform vec2 resolution; ! void main(void){ vec3 color; color.r = sin(gl_FragCoord.x / 10.0); color.g = sin(gl_FragCoord.x / 13.0); color.b = sin(gl_FragCoord.x / 17.0); gl_FragColor = vec4(color, 1.0); }
  49. 49. GLSL (Shader) ‣ 縞々模様に!
  50. 50. GLSL (Shader) ‣ さらに時間(time)を足してみる uniform float time; uniform vec2 mouse; uniform vec2 resolution; ! void main(void){ vec3 color; color.r = sin(gl_FragCoord.x / 10.0 + time * 5.0); color.g = sin(gl_FragCoord.x / 13.0 + time * 6.0); color.b = sin(gl_FragCoord.x / 17.0 + time * 7.0); gl_FragColor = vec4(color, 1.0); }
  51. 51. GLSL (Shader) ‣ 縞模様が左右に動く(はず)
  52. 52. GLSL (Shader) ‣ 濃度ではなく、(x, y)座標にsinwaveを描いてみる ‣ ちょっと複雑… ! ‣ 少しずつやってみる
  53. 53. GLSL (Shader) ‣ はじめの一歩: y座標の位置で色を変化 = グラデーション uniform float time; uniform vec2 mouse; uniform vec2 resolution; ! void main(void){ vec2 pos = ( gl_FragCoord.xy / resolution.xy ); vec3 color = vec3(pos.y); gl_FragColor = vec4(color, 1.0); }
  54. 54. GLSL (Shader) ‣ グラデーション
  55. 55. GLSL (Shader) ‣ グラデーションのy座標を、sin関数で変化させてみる uniform float time; uniform vec2 mouse; uniform vec2 resolution; ! void main(void){ vec2 pos = ( gl_FragCoord.xy / resolution.xy ); pos.y -= 0.5; pos.y += sin(pos.x * 10.0 + time) * 0.2; vec3 color = vec3(pos.y); gl_FragColor = vec4(color, 1.0); }
  56. 56. GLSL (Shader) ‣ 波うつグラデーションができた
  57. 57. GLSL (Shader) ‣ 明度の絶対値を表示してみる 1 1 明度 明度 -1 -1 y座 y座
  58. 58. GLSL (Shader) ‣ 明度の絶対値を表示してみる uniform float time; uniform vec2 mouse; uniform vec2 resolution; ! void main(void){ vec2 pos = ( gl_FragCoord.xy / resolution.xy ); pos.y -= 0.5; pos.y += sin(pos.x * 10.0 + time) * 0.2; ! ! } vec3 color = vec3(abs(pos.y)); gl_FragColor = vec4(color, 1.0);
  59. 59. GLSL (Shader) ‣ 波の形が見えてきた!!
  60. 60. GLSL (Shader) ‣ さらに1から引いて、乗算する 1 1 明度 明度 -1 -1 y座 y座
  61. 61. GLSL (Shader) ‣ さらに1から引いて、乗算する uniform float time; uniform vec2 mouse; uniform vec2 resolution; ! void main(void){ vec2 pos = ( gl_FragCoord.xy / resolution.xy ); pos.y -= 0.5; pos.y += sin(pos.x * 10.0 + time) * 0.2; ! ! } vec3 color = vec3(1.0 - pow(abs(pos.y),0.2)); gl_FragColor = vec4(color, 1.0);
  62. 62. GLSL (Shader) ‣ きれいなSin波が描けた!!
  63. 63. GLSL (Shader) ‣ 色合いを工夫してみる uniform float time; uniform vec2 mouse; uniform vec2 resolution; ! void main(void){ vec2 pos = ( gl_FragCoord.xy / resolution.xy ); pos.y -= 0.5; pos.y += sin(pos.x * 10.0 + time) * 0.2; vec3 color = vec3(1.0 - pow(abs(pos.y),0.2)); ! ! } gl_FragColor = vec4(color.r*0.2, color.g*0.5, color.b*1.0, 1.0);
  64. 64. GLSL (Shader) ‣ 自分の好みの色に!!
  65. 65. GLSL (Shader) ‣ さらに時間で振幅を変化させてみたり uniform float time; uniform vec2 mouse; uniform vec2 resolution; ! void main(void){ vec2 pos = ( gl_FragCoord.xy / resolution.xy ); pos.y -= 0.5; ! ! } pos.y += sin(pos.x * 10.0 + time) * 0.2 * sin(time); vec3 color = vec3(1.0 - pow(abs(pos.y),0.2)); gl_FragColor = vec4(color.r*0.2, color.g*0.5, color.b*1.0, 1.0);
  66. 66. GLSL (Shader) ‣ 完成!!
  67. 67. GLSL (Shader) ‣ openFrameworksとGLSLの連携をしてみる ‣ このSin波のパラメータを、oFで生成して渡してみる ! ‣ oF側 → float array[] を生成し、setUniform1fv() で渡す ‣ GLSL側 → uniform float array[] で受ける ! ‣ oF側でランダムにパラメータ生成して、Shaderに入れてみる!
  68. 68. GLSL (Shader) ‣ Shader側 #include "testApp.h" ! //波の数 static const int NUM = 20; //Shaderへ渡す周波数の配列 float freq[NUM]; ! void testApp::setup(){ //Shaderの画面サイズ設定 width = 400; height = 300; fbo.allocate(width, height); //Shaderファイルの読込み shader.load("shader"); //ランダムに周波数の配列を生成 for (int i = 0; i < NUM; i++) { freq[i] = ofRandom(4.0, 10.0); } }
  69. 69. GLSL (Shader) ‣ openFrameworks: testApp.cpp #include "testApp.h" ! //波の数 static const int NUM = 20; //Shaderへ渡す周波数の配列 float freq[NUM]; ! void testApp::setup(){ //Shaderの画面サイズ設定 width = 400; height = 300; fbo.allocate(width, height); //Shaderファイルの読込み shader.load("shader"); //ランダムに周波数の配列を生成 for (int i = 0; i < NUM; i++) { freq[i] = ofRandom(4.0, 10.0); } }
  70. 70. GLSL (Shader) ‣ openFrameworks: testApp.cpp void testApp::draw(){ //Shaderパラメータ設定 float resolution[] = {width, height}; float mousePoint[] = {mouse.x, mouse.y}; float time = ofGetElapsedTimef(); //FBO開始 fbo.begin(); shader.begin(); //Shaderに渡す値(時間、解像度、マウスの位置) shader.setUniform1f("time", time); shader.setUniform2fv("resolution", resolution); shader.setUniform2fv("mouse", mousePoint); //freqの配列をShaderに渡す ! shader.setUniform1fv("freq", freq, NUM); //画面全体に描画する ofRect(0, 0, ofGetWidth(), ofGetHeight()); shader.end(); fbo.end(); fbo.draw(0, ofGetHeight(), ofGetWidth(), -ofGetHeight()); }
  71. 71. GLSL (Shader) ‣ 折り重なる様々な周波数のSin波
  72. 72. SuperCollider
  73. 73. SuperCollider Basics ‣ Sup
  74. 74. SuperCollider Basics ‣ SuperColliderとは? ‣ リアルタイムな音響合成やアルゴリズミック・コンポジション のためのプログラミング言語 ‣ SmallTalkライクなオブジェクト指向言語 ‣ リアルタイムに音響を生成できる → ライブコーディング!
  75. 75. SuperCollider Basics ‣ 1996年にJames McCartneyによりリリース ‣ James McCartneyの就職(Apple!)などの事情で、オープソース として公開 ‣ 現在は、GPLライセンスとして多くの開発者により更新されて いる
  76. 76. SuperCollider Basics ‣ 参考図書:The SuperCollider Book ‣ Wilson, S., Cottle, D. and Collins, N. (eds). 2011. The SuperCollider Book. Cambridge, MA: MIT Press
  77. 77. SuperCollider Basics ‣ Website: http://supercollider.sourceforge.net/
  78. 78. SuperCollider Basics ‣ SuperColliderをダウンロード ‣ 最新版は、version 3.6.5 (2013年10月現在) ‣ http://supercollider.sourceforge.net/downloads/
  79. 79. The SuperCollider Language ‣ SuperColliderの独特な文法 ‣ Smalltalkのオブジェクト指向な言語構造と、C言語系の制御構 造などの機能を足したような感じ // print "Hello world!"! "Hello world!".postln;! // play a mixture of an 800 Hz sine tone and pink noise! { SinOsc.ar(800, 0, 0.1) + PinkNoise.ar(0.01) }.play;! // modulate a sine frequency and a noise amplitude with another sine! // whose frequency depends on the horizontal mouse pointer position! { ! var x = SinOsc.ar(MouseX.kr(1, 100));! SinOsc.ar(300 * x + 800, 0, 0.1) ! + ! PinkNoise.ar(0.1 * x + 0.1) ! }.play;! // list iteration: multiply the elements of a collection by their indices! [1, 2, 5, 10, -3].collect { ! arg elem, idx;! elem * idx;! };! // factorial function! f = {! arg x;! if(x == 0) { 1 } { f.(x-1) * x }! };
  80. 80. The SuperCollider Language ‣ 冒頭のドローン系の音を解説 ‣ 楽器はこんな感じ - 1.5倍の比率でノコギリ波を重ねている //楽器基本 SynthDef("col_closesaw", { arg fadeTime = 10, n = 0, rq = 0.3, detune = 0.001, base = 20, ratio = 1.5, harm = 1.5, amp = 0.2, gate=0; var lfo, env, out; env = EnvGen.kr(Env.new([0,1], [fadeTime], 'sine')); lfo = SinOsc.ar(rrand(0.03, 0.05), 0, 100, 600); out = Saw.ar([base+detune.rand, base+detune.rand] * (ratio ** n)) * amp + Saw.ar([base*harm+detune.rand, base*harm+detune.rand] * (ratio ** n)) * amp; out = out * env; out = RLPF.ar(out, lfo * (1.5 ** n), rq).clip2 * 0.5; out = out * EnvGen.kr(Env.adsr(releaseTime:20), gate, doneAction: 2); Out.ar(0, out); }).store;
  81. 81. The SuperCollider Language ‣ 演奏してみる ‣ …ちょっと味気ない Synth("col_closesaw",["n", 1, "gate", 1]);
  82. 82. The SuperCollider Language ‣ エフェクトを加えてみる ‣ オールパス・フィルタを幾重にも重ねていく ! SynthDef("col_closefx", { arg lpf=440, rq=0.5, amp=0.8; var in, out; in = In.ar(0, 2); 12.do({ in = AllpassL.ar(in, 0.1, LFNoise2.kr([rrand(0.0, 0.1),rrand(0.0, 0.1)],0.01,0.06), 4.0) }); out = CompanderD.ar(in) * amp; ReplaceOut.ar(0, out); }).store;
  83. 83. The SuperCollider Language ‣ エフェクト付きで演奏してみる ‣ ぐっと深みが増した Synth("col_closefx"); Synth("col_closesaw",["n", 0, "gate", 1]);
  84. 84. The SuperCollider Language ‣ どんどん倍音を足していく ‣ ある値を境に、突然非線形に歪んでドラマチックな展開へ Synth("col_closesaw",["n", Synth("col_closesaw",["n", Synth("col_closesaw",["n", Synth("col_closesaw",["n", Synth("col_closesaw",["n", Synth("col_closesaw",["n", Synth("col_closesaw",["n", Synth("col_closesaw",["n", Synth("col_closesaw",["n", Synth("col_closesaw",["n", Synth("col_closesaw",["n", ... 1, "gate", 1]); 2, "gate", 1]); 3, "gate", 1]); 4, "gate", 1]); 5, "gate", 1]); 6, "gate", 1]); 7, "gate", 1]); 8, "gate", 1]); 9, "gate", 1]); 10, "gate", 1]); 11, "gate", 1]);
  85. 85. まとめ
  86. 86. まとめ ‣ 駆け足で、それぞれの要素を解説してきた 映像 音 openFrameworks SuperCollider GLSL
  87. 87. まとめ ‣ openFrameworks ‣ SuperCollider ‣ GLSL ! ‣ どれもフリーウェア ‣ ネットで調べると、情報もたくさん SuperCollider ! ‣ 適材適所で開発環境を使い分け GLSL
  88. 88. まとめ ‣ 今後も様々な情報を交換していきましょう!! SuperCollider GLSL

×