yoppa.org


前橋工科大学 - デザイン演習 II 2020

「家具の映像」制作チュートリアル (1)

制作に必要なもの

「家具の映像」をどう実現するか

  • 再生方法 → フルスクリーンで
    • 方法は直接レクチャー
  • 生活を遮らないもの
    • ゆっくりとした変化
    • 絶えず変化しつづける
    • 同じパターンの繰り返しは避ける → ランダム
    • 色合いの工夫 : HSBによる指定

Processingの基本の確認

  • setup() 初期設定 : 最初に1度だけ実行される
  • draw() 描画 : 一定間隔でくりかえし実行、繰り返す速さ : fps (frame per second)

code_01 : シンプルなアニメーションのサンプル

//変数
float x, y;

void setup(){
  size(1920, 1080);
  frameRate(30);
  //変数の初期化
  x = 0;
  y = height/2;
}

void draw(){
  background(0);
  fill(31, 127, 255);
  ellipse(x, y, 100, 100);
  //変数を更新してアニメーション
  x = x + 5;
}

ランダム

  • ランダム : 規則性の無い数、範囲を指定して使用する
    • random(100) : 0 ~ 100のランダムな数
    • random(100, 200) : 100 ~ 200のランダムな数

code_02 : ランダムな場所にランダムな大きさの円を描く

void setup(){
  size(1920, 1080);
  frameRate(30);
  //最初に背景を1度だけ塗る
  background(0);
}

void draw(){
  //ランダムな座標と大きさを生成
  float x = random(width);
  float y = random(height);
  float diameter = random(20, 200);
  //円を描く
  noStroke();
  fill(31, 127, 255, 128);
  ellipse(x, y, diameter, diameter);
}

色彩について

  • RGBで色彩をコントロールするのは難しい

code_03 : RGBのランダム

void setup(){
  size(1920, 1080);
  frameRate(30);
  //最初に背景を1度だけ塗る
  background(0);
}
​
void draw(){
  //ランダムな座標と大きさを生成
  float x = random(width);
  float y = random(height);
  float diameter = random(20, 200);
  //円を描く
  noStroke();
  //RGBのランダム
  fill(random(256), random(256), random(256), 128);
  ellipse(x, y, diameter, diameter);
}
  • RGBではなくHSBカラーモードを使用する、HSB = Hue(色相)、Saturation(彩度)、Brightness(明度)

code_04 : HSBのランダム

void setup(){
  size(1920, 1080);
  frameRate(30);
  //カラーをHSBモードに
  colorMode(HSB, 360, 100, 100, 100);
  //最初に背景を1度だけ塗る
  background(0);
}
​
void draw(){
  //ランダムな座標と大きさを生成
  float x = random(width);
  float y = random(height);
  float diameter = random(20, 200);
  //円を描く
  noStroke();
  //HSBでランダムな色彩を生成
  fill(random(100, 200), 80, 90, 70);
  ellipse(x, y, diameter, diameter);
}

物体の数を制限する : 繰り返しとリスト

  • 現状では永遠に円が増殖してしまう
  • 一定の数で制限することはできないだろうか?
  • 繰り返し (for文) とリストを利用する
    • x, y, diameter をそれぞれリスト(floatList)に
  • 指定した数を超えたらリストの先頭の要素を消去する

code_05 : リストと繰り返しで最大数を制限

FloatList x;
FloatList y;
FloatList diameter;
FloatList hue;
​
void setup() {
  size(1920, 1080);
  frameRate(30);
  //カラーをHSBモードに
  colorMode(HSB, 360, 100, 100, 100);
  //リストを初期化
  x = new FloatList();
  y = new FloatList();
  diameter = new FloatList();
  hue = new FloatList();
}
​
void draw() {
  background(0);
  //ランダムな値をリストに追加
  x.append(random(width));
  y.append(random(height));
  diameter.append(random(100, 400));
  hue.append(random(100, 200));
  //最大数を100に限定
  if(x.size() > 100){
    //先頭の要素を消去
    x.remove(0);
    y.remove(0);
    diameter.remove(0);
    hue.remove(0);
  }
  //リストの数だけ繰り返し
  for (int i = 0; i < x.size(); i++) {
    //円を描く
    noStroke();
    //HSBでランダムな色彩を生成
    fill(hue.get(i), 80, 90, 50);
    ellipse(x.get(i), y.get(i), diameter.get(i), diameter.get(i));
  }
}

要素をクラスへ

  • だいぶプログラムが煩雑になってきた
  • パラメータ毎にリストがあるのはちょっと煩雑
  • 「ランダムな円」という要素を独立したプログラムへ → クラス

code_06 : クラス化した増殖する円

ArrayList<Dot> dots = new ArrayList<Dot>();

void setup() {
  size(1920, 1080);
  frameRate(60);
  //カラーをHSBモードに
  colorMode(HSB, 360, 100, 100, 100);
}

void draw() {
  background(0);
  //1秒に1回追加
  if(frameCount % 60 == 0){
    //Dotをリストに追加
    dots.add(new Dot());
  }
  //最大数を100に限定
  if(dots.size() > 100){
    //先頭の要素を消去
    dots.remove(0);
  }
  //リストの数だけ繰り返し
  for (int i = 0; i < dots.size(); i++) {
    //円を描く
    dots.get(i).draw();
  }
}

class Dot {
  float x, y, diameter, hue;
  Dot(){
    x = random(width);
    y = random(height);
    diameter = random(100, 400);
    hue = random(100, 200);
  }
  
  void draw(){
    noStroke();
    fill(hue, 80, 90, 50);
    ellipse(x, y, diameter, diameter);
  }
}

個別のオブジェクトを動かす

  • 円をクラス化すれば、個別にアニメーションさせることも簡単にできる
  • 例えばゆっくりと膨張しながら薄くなっていく円

code_07 : 膨張しながらフェードアウトする円

ArrayList<Dot> dots = new ArrayList<Dot>();

void setup() {
  size(1920, 1080);
  frameRate(60);
  //カラーをHSBモードに
  colorMode(HSB, 360, 100, 100, 100);
}

void draw() {
  background(0);
  //1秒に1回追加
  if (frameCount % 60 == 0) {
    //Dotをリストに追加
    dots.add(new Dot());
  }
  //リストの数だけ繰り返し
  for (int i = 0; i < dots.size(); i++) {
    //もし透明度が0より小さかったら消去
    if (dots.get(i).alpha < 0) {
      dots.remove(i);
    }
    //円を描く
    dots.get(i).draw();
  }
}

class Dot {
  float x, y, diameter, speed, hue, alpha, alphaSpeed;
  Dot() {
    x = random(width);
    y = random(height);
    diameter = 0;
    hue = random(100, 200);
    alpha = 100;
    speed = random(0.2, 0.8);
    alphaSpeed = random(0.05, 0.1);
  }

  void draw() {
    noStroke();
    fill(hue, 80, 90, alpha);
    ellipse(x, y, diameter, diameter);
    diameter += speed;
    alpha -= alphaSpeed;
  }
}

応用1 : 色相をシフトさせる

  • それぞれの円の色相を少しずつ変化させてみる

code_08 : 色相のシフト

ArrayList<Dot> dots = new ArrayList<Dot>();

void setup() {
  size(1920, 1080);
  frameRate(60);
  //カラーをHSBモードに
  colorMode(HSB, 360, 100, 100, 100);
}

void draw() {
  background(0);
  //4秒に1回追加
  if (frameCount % 240 == 0) {
    //Dotをリストに追加
    dots.add(new Dot());
  }
  //リストの数だけ繰り返し
  for (int i = 0; i < dots.size(); i++) {
    //もし透明度が0より小さかったら消去
    if (dots.get(i).alpha < 0) {
      dots.remove(i);
    }
    //円を描く
    dots.get(i).draw();
  }
}

class Dot {
  float x, y, diameter, speed, hue, alpha, alphaSpeed, hueBase;
  Dot() {
    x = random(width);
    y = random(height);
    diameter = 0;
    hue = (random(100, 200) + (frameCount / 60.0)) % 360;
    alpha = 100;
    speed = random(0.1, 0.4);
    alphaSpeed = random(0.01, 0.03);
  }

  void draw() {
    noStroke();
    fill(hue, 80, 90, alpha);
    ellipse(x, y, diameter, diameter);
    diameter += speed;
    alpha -= alphaSpeed;
  }
}

応用2 形を変化させる

code_09 : 円から矩形に

ArrayList<Dot> dots = new ArrayList<Dot>();

void setup() {
  size(1920, 1080, P2D);
  frameRate(60);
  //カラーをHSBモードに
  colorMode(HSB, 360, 100, 100, 100);
}

void draw() {
  background(0);
  //4秒に1回追加
  if (frameCount % 240 == 0) {
    //Dotをリストに追加
    dots.add(new Dot());
  }
  //リストの数だけ繰り返し
  for (int i = 0; i < dots.size(); i++) {
    //もし透明度が0より小さかったら消去
    if (dots.get(i).alpha < 0) {
      dots.remove(i);
    }
    //円を描く
    dots.get(i).draw();
  }
}

class Dot {
  float x, y, diameter, speed, hue, alpha, alphaSpeed, hueBase;
  Dot() {
    x = random(width);
    y = random(height);
    diameter = 0;
    hue = (random(100, 200) + (frameCount / 60.0)) % 360;
    alpha = 100;
    speed = random(0.1, 0.4);
    alphaSpeed = random(0.01, 0.03);
  }

  void draw() {
    noStroke();
    fill(hue, 60, 100, alpha);
    rectMode(CENTER);
    rect(x, y, diameter, diameter);
    diameter += speed;
    alpha -= alphaSpeed;
  }
}

応用3 違う動きに

  • 高さを画面いっぱいにした矩形を左右に動かす
  • 左右の辺に到達したら折り返す
  • アルファの値を変化させて色の重なりを楽しむ

code_10 : 重なる矩形

ArrayList<Rect> rects = new ArrayList<Rect>();

void setup() {
  size(1920, 1080);
  frameRate(60);
  //カラーをHSBモードに
  colorMode(HSB, 360, 100, 100, 100);
}

void draw() {
  background(0, 0, 70);
  //4秒に1回追加
  if (frameCount % 240 == 0) {
    //Dotをリストに追加
    rects.add(new Rect());
  }
  //リストの数だけ繰り返し
  for (int i = 0; i < rects.size(); i++) {
    //矩形を描く
    rects.get(i).draw();
    //もし透明度が0より小さかったら消去
    if (rects.get(i).alpha < 0) {
      rects.remove(i);
    }
  }
}

class Rect {
  float x, w, speed, hue, alpha, alphaSpeed;
  Rect() {
    //初期値を設定
    w = random(500, 1000);
    x = random(-w, width);
    speed = random(-0.5, 0.5);
    hue = random(360);
    alpha = 0;
    alphaSpeed = 0.2;
  }
  void draw() {
    noStroke();
    fill(hue, 60, 100, alpha);
    rect(x, 0, w, height);
    x += speed;
    //両端で跳ね返り
    if (x < -width || x > width) {
      speed *= -1;
    }
    //フェードイン
    if(alpha > 100){
      alphaSpeed *= 1;
      alpha = 100;
    }
    alpha += alphaSpeed;
  }
}