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 は以下。
使用画像は以下。
_leaf.png
_leaf2.png
以下のページで動作確認できる。
_draw_leafs
- マウスクリックで葉っぱを増やせる。
- Cキーで画像を切替。葉っぱ1枚と、葉っぱ複数の画像を切り替えられる。
- Rキーで全消去。
スクリーンショットは以下。解像度が荒いけど雰囲気ぐらいは伝わるかなと…。
一応関連ファイルを 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() (パーリンノイズ) で変化させてる。

ところで、p5.js は思っていたより処理が重かった…。200個ぐらい描画すると処理落ちしてしまう。AMD Ryzen 5 5600X + NVIDIA GeForce GTX 1060 6GB のスペックで、60FPS を 24FPS に落としても処理落ちしてしまうので、ちょっと残念…。
Processing で動かしたらもっと軽いのだろうか? それとも重いのだろうか? 何にせよ p5.js では、各フレームをアルファチャンネルを持った画像として保存することができないので、この生成結果を動画編集ソフトに持っていって利用することができない。Processing で書き直して、連番画像として保存できないか試してみる予定。
葉っぱの色は tint() を使って明度だけ変えてる状態だけど、もっと色数を絞って、3〜4色で描画したほうが、かえって奥行きを感じる見た目になるのではと想像したりもする。

ところで、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とかもあったし…。
余談。TVアニメ「アクロトリップ」を見ていたら、木の幹と木の葉っぱをレイヤー分けしておいて、木の葉っぱ部分だけ何かのフィルタをかけて動かして、強風でザワザワしてる感じを出していて感心してしまった。コストパフォーマンスが圧倒的に高そう。企画のジャンルによるだろうけど、このぐらいでも十分な場面って多いだろうなと…。
もっとも、そういうことをしたかったらレイヤー分けした素材が必要になるだろうけど。せめて、動かすところと動かさないところをレイヤー分けしておいてくれないと…。セル+フィルムで作ってた時代ですら、動くところだけセルにしてたよな…。BOOKとかもあったし…。
[ ツッコむ ]
以上です。