title: "時間アニメーション" description: "u_timeユニフォームを使った時間ベースのアニメーションを学びます。sin関数で周期的な動きを作りましょう。" chapter: "06-animation" order: 1 challenge: description: "3つの円を異なる速度でアニメーションさせてください。1つは上下に、1つは左右に、1つはサイズが変わるようにしましょう。" hints:
- "上下の動きは y座標に sin(u_time) を加えます。左右の動きは x座標に cos(u_time * 速度) を加えます。"
- "サイズのアニメーションは半径に sin(u_time * 速度) * 振幅 を加えます。"
- "異なる速度にするには u_time に異なる係数を掛けます。例:sin(u_time * 1.0), sin(u_time * 1.5), sin(u_time * 2.0)"
時間アニメーション
u_timeユニフォーム
u_time はシェーダーに渡される時間のユニフォーム変数です。プログラム開始からの経過秒数が float で渡されます。
uniform float u_time; // 0.0, 0.5, 1.0, 1.5, ... と増え続ける
この値は毎フレーム更新され、アニメーションの原動力になります。
sin()で周期的な動き
sin() は -1 から 1 の間を滑らかに往復する関数です。u_time を入力すると、時間に応じた周期的な値が得られます:
float wave = sin(u_time); // 約6.28秒で1周期
float fast = sin(u_time * 3.0); // 3倍速
float slow = sin(u_time * 0.5); // 半分の速度
値の範囲を調整する
sin() の出力は -1〜1 ですが、多くの場合 0〜1 の範囲が必要です:
// -1〜1 → 0〜1 に変換
float value = sin(u_time) * 0.5 + 0.5;
// 任意の範囲に変換
float minVal = 0.1;
float maxVal = 0.4;
float value = minVal + (maxVal - minVal) * (sin(u_time) * 0.5 + 0.5);
位置のアニメーション
図形の位置を時間で動かすには、中心座標に sin や cos を加えます:
// 円運動
vec2 center = vec2(cos(u_time), sin(u_time)) * 0.2;
// 上下の動き
vec2 center = vec2(0.0, sin(u_time) * 0.2);
サイズのアニメーション
半径を時間で変化させると、脈動するような効果が得られます:
float radius = 0.2 + 0.05 * sin(u_time * 2.0);
float d = length(p) - radius;
位相をずらす
複数のオブジェクトを異なるタイミングで動かすには、u_time に定数を足して位相をずらします:
float wave1 = sin(u_time);
float wave2 = sin(u_time + 2.094); // 120度ずらし
float wave3 = sin(u_time + 4.189); // 240度ずらし
2π / 3 ≈ 2.094 ずつずらすと、3つの波が均等に分散します。
まとめ
u_timeはプログラム開始からの経過秒数sin(u_time)で -1〜1 の滑らかな周期運動- 速度は
u_timeの係数、範囲は* 0.5 + 0.5で調整 - 位相をずらして複数オブジェクトのタイミングを制御