はじめに
Youtube動画で、sin波を使ったアニメーション処理を見て、Three.jsで似たような物を作りたくなったので実装してみたメモです。
動画ではサイン波に円を描写して拡大していくものでしたが、今回は星形にしています。
今回は、過去記事でも度々使っている CanvasTexture を使ってCanvas 2Dで以前作成した星形の描写を応用しています。
![]()
動画(パソコン)
ちなみに、画像のように「THREE.Fog」で霧を実装しました。
余りにも簡単なので実装方法は省きます。
// 霧(FOG)
config.scene.fog = new THREE.Fog(
config.fog.color, // 背景色
config.fog.near, // 開始距離
config.fog.far // 終了距離
);
config.scene.background = new THREE.Color(config.fog.color);
1. 何を作ったか
three.js を使って、sin 波に沿ってスプライトが生成され、時間とともに拡散・消滅していくアニメーション演出を試作した。
用途としては、
- UIや背景の装飾
- 魔法・エフェクト表現
- 雰囲気づくり用の軽量なアニメーション
といった「主役ではないが画面の印象を支える」要素を想定している。
実装には Sprite と CanvasTexture を使い、
ポリゴン数や複雑なシェーダに頼らない、軽量な表現を目指した。
この記事では完成品というより、
- どういう構造で作ったか
- どこを工夫したか
- やりすぎて戻した判断
を中心にまとめている。
2. 基本構造(全体像)
構造はシンプルで、大きく3つに分けている。
-
Circleスプライト1個分の寿命と挙動を管理するクラス -
SinCircleSystemスプライトの生成、時間管理、配列管理を行うシステム側のクラス -
updateSinCircl(delta)外部(メインループ)から呼ばれる更新用の関数
重要なのは、 System と個体(Circle)を分けている点。
Circle は「生まれて、少し動いて、消える」だけを担当し、
生成タイミングや全体のリズムは SinCircleSystem が管理する。
この分離をしておくことで、
- 表現を増やしてもクラスが肥大化しない
- 破綻したら System 側だけ戻せる
- 後から別の演出に流用しやすい
というメリットがある。
3. 見た目の工夫
three.js の SpriteMaterial は、
デフォルトでは正方形の板として表示される。
そのままだとどうしても「四角い感じ」が残るため、
CanvasTexture を使って星形のテクスチャを自前で描画した。
createStarTexture(...)
この関数では、
- Canvas に星形のパスを描く
- 塗りつぶさず線だけで描画する
- それを
CanvasTextureに変換する
という流れを取っている。
線だけのテクスチャにすることで、
- 見た目は軽い
- 拡大しても破綻しにくい
- 重ねても主張しすぎない
という、装飾向きの表現になる。
4. 動きが単調にならない工夫
sin 波に沿って配置するだけだと、 どうしても動きが規則的で単調になりがちだった。
そこで、いくつかの「小さなランダム要素」を足している。
個体ごとのランダム要素
Circle ごとに以下の値をランダムで持たせている。
speed:成長・時間進行の速さfade:消え方の速さspin:回転速度
これだけでも、 「全員が同じテンポで動いている感じ」はかなり薄れる。
sin 波に wobble を足す
基本の sin 波に、 もう一段遅い sin を重ねて揺らぎを作っている。
これにより、
- 完全な規則運動ではなくなる
- それでも全体の流れは保たれる
という、ちょうどいい崩し方になる。
位置を少しずつ進める
生成時の位置に固定せず、
velocity を持たせて毎フレーム少しずつ位置を進めている。
この「ほんの少し動く」だけで、
- 静止した装飾 → 空間に存在するエフェクト
という印象の差が出る。
ここは 数行の差で印象が大きく変わるポイントだった。
5. 今後の拡張余地
この構成のままでも、拡張余地はいくつかある。
- 出現位置(スポナー)を切り替える
- テクスチャを円や別の図形に差し替える
- HUD演出や魔法エフェクトとして転用する
ただし、 全部やらなくてもいい。
「やろうと思えばできる」余地を残したまま止めるのが、 この手の演出ではちょうどいいと感じている。
💬 コメント