three.js練習 boids
three.jsでboidsを試す
サンプル
URL: https://hittaito.github.io/three-practice/day11/index.html
ソースコードはこちら
注意
メモ書き&簡易実装なのできちんと知りたい方は参考の方を見てください。参考のp5.jsの劣化版移植みたいなもんなので
実装
参考1によるとboidsは結合、分離、整列の3つのルールを基に自身の移動先を決めている。 自身以外のposition, velocity情報が必要なため、テクスチャにposition, velocity情報を書き込みフラグメントシェーダで計算することにする。
基本的な処理
テクスチャのサイズに合わせてループを回す。最初に一定範囲内の判定を行い一定範囲内の時は結合、分離、整列の処理を行う。
今回は履歴を持たせるためy = 0の場合のみ。
for (int x = 0; x < size.x; x++) { int y = 0; vec3 otherPos = texelFetch(uPosition, ivec2(x,y), 0).xyz; vec3 dir = otherPos - pos; float dist = length(dir); if (dist < 0.0001 || dist > radius) continue; /** 結合 */ /** 分離 */ /** 整列 */ } /** 結合 後処理 */ /** 整列 後処理 */ vel += cohesDir + separation + align; pos += vel;
結合
自身から一定範囲内に存在する要素の中心に移動させる。単純に要素の中心を求め方向を求める。
vec3 cohesion; // 要素のpositionを合計 float nCohesion; // 一定範囲の要素数 /** ループ処理内 */ cohesion += otherPos; nCohesion++; /** ループ後処理*/ vec3 cohesDir = vec3(0); if (nCohesion > 0.) { cohesion/= nCohesion; cohesDir = cohesion - pos; }
分離
近接した場合反対方向に移動させる。近接距離によって変化を入れてもいいかも
vec3 separation / ** ループ処理内 */ if (dist < uSeparate) { separation -= dir; }
整列
速度を周囲と合わせる動き。
vec3 align; float nAlign; /** ループ処理内 */ vec3 otherVel = texelFetch(uVelocity, ivec2(x,y), 0).xyz; // velocityテクスチャ align += otherVel; nAlign++; /** ループ処理後 */ if (nAlign > 0.) { align /= nAlign; }
後はこれらを速度として合計し、positionを更新する。
参考
Boids|クリエイティブコーディングの教科書
three.js examples
感想等
簡易的な実装だが一応boidsとして動いているので動いたときは感動する(´;ω;`)
移動履歴をとっているのでこの作品(
POOL)みたいにいい感じの作品を目指したい