mieki256's diary



2024/10/26() [n年前の日記]

#1 [proce55ing][processing][javascript] p5.jsで木の葉サワサワ処理を試しに書いてみた

JavaScriptライブラリ p5.js を使って、サワサワと動く木の葉を描く処理を試しに書いてみた。動作確認環境は Windows10 x64 22H2 + p5.js 1.10.0。Firefox 131.0.3 64bit、Google Chrome 130.0.6723.70。

以下のページで動作確認できる。

_draw_leafs
スクリーンショットは以下。解像度が荒いけど雰囲気ぐらいは伝わるかなと…。




一応関連ファイルを zip でまとめておいた。

_draw_leafs.zip

sketch.js は以下。
// draw rotate image with noise.
// Last updated: <2024/10/26 03:17:06 +0900>

let fps = 24;
let base_ang = 90 + 45;
let spd = 0.03;
let lmax = 10;
let rmax = 100;

var img;
var img2;
let leafs = [];
let resetfg = false;
let imgkind = 0;

function setup() {
  createCanvas(windowWidth, windowHeight);
  img = loadImage("./leaf.png");
  img2 = loadImage("./leaf2.png");
  imgkind = 0;
  angleMode(DEGREES);
  frameRate(fps);
}

function draw() {
  background("#1989ca");

  // draw text
  noStroke();
  fill(255);
  textSize(16);
  text("Please click", 8, 20);
  text("R: Reset", 8, 40);
  text(`C: Change image (${imgkind})`, 8, 60);
  text("Leaf: " + leafs.length, 8, 80);

  if (resetfg) {
    // leafs all clear
    leafs = [];
    resetfg = false;
  }

  // draw leafs
  for (let leaf of leafs) {
    leaf.update();
    leaf.draw();
  }
}

function mouseClicked() {
  let x = mouseX;
  let y = mouseY;
  if (imgkind == 0) {
    set_leafs(x, y, img);
  } else {
    set_leafs(x, y, img2);
  }
}

function keyTyped() {
  if (key == "r") {
    // reset
    resetfg = true;
  }
  if (key == "c") {
    // change image
    imgkind = (imgkind + 1) % 2;
  }
}

function set_leafs(bx, by, img) {
  for (let i = 0; i < lmax; i++) {
    let r = random() * rmax;
    let ang = random() * 360.0;
    let x = bx + r * cos(ang);
    let y = by + r * sin(ang);
    let tintv = 255 - 180 * ((lmax - i) / lmax);
    // tv = 255 - 200 * random();
    let rv = random() * 65536;
    let leaf = new Leaf(img, x, y, rv, spd, tintv);
    leafs.push(leaf);
  }
  sort_tintv();
}

function sort_tintv() {
  let len = leafs.length;
  for (let i = 0; i < len; i++) {
    leafs[i].set_tintv(255 - 180 * ((len - i) / len));
  }
}

// ----------------------------------------
// leaf class
class Leaf {
  constructor(img, bx, by, tm, spd, tv) {
    this.img = img;
    this.bx = bx;
    this.by = by;
    this.tm = tm;     // counter
    this.spd = spd;   // animation speed
    this.tintv = tv;
    this.x = 0;
    this.y = 0;
    this.ang = 0;
  }

  set_tintv(v) {
    this.tintv = v;
  }

  update() {
    this.x = -(100 * noise(this.tm * this.spd * 1.0));
    this.y = -(50 * noise(this.tm * this.spd * 1.0));
    let a = 75;
    this.ang = base_ang + a * noise(this.tm * this.spd) - (a / 2);
    this.tm += 1;
  }

  draw() {
    // draw rotate image
    push();
    translate(this.bx, this.by);
    translate(this.x, this.y);
    rotate(this.ang);
    tint(this.tintv);
    image(this.img, 0, - this.img.height / 2);
    pop();
  }
}


使用画像は以下。

_leaf.png
_leaf2.png

処理内容その他 :

やってることは、葉っぱの画像をその場で回転させてるだけ。回転の基準座標と、回転角度を、noise() (パーリンノイズ) で変化させてる。

draw_leafs_about.png

ところで、p5.js は思っていたより処理が重かった…。200個ぐらい描画すると処理落ちしてしまう。AMD Ryzen 5 5600X + NVIDIA GeForce GTX 1060 6GB のスペックで、60FPS を 24FPS に落としても処理落ちしてしまうので、ちょっと残念…。

Processing で動かしたらもっと軽いのだろうか? それとも重いのだろうか? 何にせよ p5.js では、各フレームをアルファチャンネルを持った画像として保存することができないので、この生成結果を動画編集ソフトに持っていって利用することができない。Processing で書き直して、連番画像として保存できないか試してみる予定。

葉っぱの色は tint() を使って明度だけ変えてる状態だけど、もっと色数を絞って、3〜4色で描画したほうが、かえって奥行きを感じる見た目になるのではと想像したりもする。

作った経緯 :

TVアニメ「オーイ!とんぼ」を視聴していたら、満開の桜の木が風でサワサワとするカットがあって、「どうやって作ってるんだろう?」と…。TVer で視聴していたからコマ送りができなくて、3DCGでやってるのか、それとも After Effects でやってるのか、それすら分からなかったのだけど、2D処理でも似た感じが出せないものかなと試してみた次第。

余談。TVアニメ「アクロトリップ」を見ていたら、木の幹と木の葉っぱをレイヤー分けしておいて、木の葉っぱ部分だけ何かのフィルタをかけて動かして、強風でザワザワしてる感じを出していて感心してしまった。コストパフォーマンスが圧倒的に高そう。企画のジャンルによるだろうけど、このぐらいでも十分な場面って多いだろうなと…。

もっとも、そういうことをしたかったらレイヤー分けした素材が必要になるだろうけど。せめて、動かすところと動かさないところをレイヤー分けしておいてくれないと…。セル+フィルムで作ってた時代ですら、動くところだけセルにしてたよな…。BOOKとかもあったし…。

以上、1 日分です。

過去ログ表示

Prev - 2024/10 - Next
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project