6つの円から始める。
大きな中心と小さな5滴を使い、それぞれ位置と半径を持たせます。共通の位相で距離を伸縮しながら周回し、一周の終わりで位置と大きさを始まりに合わせます。
移動 = sin²(位相 × π)
試してみよう: 「滴」で位置0%、50%、100%を見ます。移動距離を増やすと分離が分かりやすくなります。両端は同じ配置です。
滴が離れ、
表面が伸びる。
小さな光が命を与える。
ループを調整し、滴の伸びと合流を見よう。
形 + 光 + 表情 + リズム考え方 / ひとつの表面、複数の中心
円が触れる前に液体の橋が生まれます。各滴が同じ見えない場に寄与し、それを足して境界を選ぶと、間の空間も物の一部になります。
境界を照らし、表情を加えて一緒に動かします。2Dのメタボール場をWebGLで描き、高さから光沢をつくります。流体シミュレーションではありません。準備なしで試せ、編集にはJavaScriptとシェーダーの基礎が役立ちます。
大きな中心と小さな5滴を使い、それぞれ位置と半径を持たせます。共通の位相で距離を伸縮しながら周回し、一周の終わりで位置と大きさを始まりに合わせます。
試してみよう: 「滴」で位置0%、50%、100%を見ます。移動距離を増やすと分離が分かりやすくなります。両端は同じ配置です。
各ピクセルから各中心への距離を測り、近くで強く、遠くで弱く寄与させます。足した場がしきい値以上のピクセルを塗ると、液体の輪郭になります。
小さなεで中心の値を有限にします。しきい値を下げると滴が大きく、早くつながります。合流の設定はしきい値を下げ、物理的な引力は加えません。境界の短い補間で縁を滑らかにします。
試してみよう: 「合流」で位置20〜25%に止め、合流を0から100%へ。中心を固定したまま首が太くなります。
メッシュなしでも平面の輪郭を光沢の物にできます。境界でゼロ、内側で高い浅い高さをつくり、近隣の高さから傾斜を求め、法線を決めます。
拡散光で丸み、鏡面反射で明るい点、柔らかな色の帯で周囲の反射を表します。縁には薄い紫を加えます。同じ法線を使うため、伸びた橋に沿って光も曲がります。
試してみよう: 「光」で光沢0%と100%を比べます。伸びた瞬間に止め、帯が形に従う様子を見ましょう。
回る白い光と笑顔は単純な符号付き距離の形を中央に重ねます。滴と同じ位相で表情を変え、小さなサイズと固定した中心で読みやすくします。
3本の輪を異なる位相で広げ、始まりと終わりで消します。RGBを少しずらして虹色の縁をつくり、角度方向の細かな変化で揺らぎを加えます。
試してみよう: 「世界」で輪をオフ、オンにし、顔なし、笑顔、回る光を比べます。自分の作品に役立つ層だけ残しましょう。
黒い600 × 600のフレームに約180pxの中心、40〜55pxの滴5つ、白い顔、細い輪3つを置きます。青の塗りとシアン・紫の光を使い、Orb、Drop 1〜5、Face、Ring 1〜3と名付けます。
集まる、離れる、広がる、戻るの4枚に複製します。名前と階層を保ち、位置と倍率を変えます。After delayとSmart Animateでつなぎ、150msの保持と800msの遷移から調整し、最後に最初へ戻します。
Smart Animateは位置、倍率、不透明度などを補間します。メタボールの場や連続的な輪郭変形は計算しません。試作では橋の絵を別レイヤーで切り替え、連続した形と光にはこのシェーダーを使います。
試してみよう: 3つの瞬間を止めて保存し、時間の設計図にします。集まる、伸びる、離れる状態の目安にしましょう。
位置の調整は動きを止めます。中央の球をドラッグか矢印で配置し、Homeで中央、Spaceで停止と再開。動きを減らす設定では停止から始め、画面外や非表示でも更新を止めます。
色、表情、光沢を選びます。1600 × 1200のPNGには現在の段階、姿勢、背景を保存します。同じ描画処理を使うため、形と光がプレビューに一致します。
試してみよう: 笑顔と輪なしの静かなミント版と、大きな移動と虹色の輪の元気な紫版をつくります。何が個性に一番影響しますか。
実践 / 伸びの瞬間を探す
15〜30%で止め、移動距離と合流を調整して細い首でつながる滴をつくります。光沢で橋の見え方を変えましょう。
少しだけ位相を進めて分離させ、両方を保存します。その小さな差に液体らしさがあります。
世界に戻る ↑HTMLに場のシェーダー、軌道、操作、スタイルを内蔵しています。ブラウザーで開いて編集できます。動く場にはWebGLが必要ですが、サーバー、インストール、外部画像は不要です。
// Each drop contributes to one shared field.
float field(vec2 p) {
float value = 0.0;
for (int i = 0; i < 6; i++) {
vec2 d = p - bodies[i].xy;
value += bodies[i].z * bodies[i].z / (dot(d, d) + 0.00008);
}
return value;
}
// Threshold chooses the silhouette; height gives it light.