title: "関数合成" description: "複数のシェーピング関数を組み合わせて複雑な形状や動きを作る方法を学びます。関数の合成テクニックを習得します。" chapter: "03-shaping" order: 4 challenge: description: "少なくとも3つのシェーピング関数を組み合わせたオリジナルパターンを作ってください。sin, fract, smoothstep, pow, abs などを自由に使ってください。" hints:
- "まず基本の形を作ります。例: float shape = sin(uv.x * 10.0); で波を作り、それに fract や abs を適用します。"
- "形を組み合わせるには掛け算(マスク)や足し算(重ね合わせ)が使えます。max, min も便利です。"
- "例: float p = abs(sin(uv.x * 10.0 + u_time)) * fract(uv.y * 5.0); これをさらに smoothstep で整形しましょう。"
関数合成
関数を組み合わせる
これまで学んだシェーピング関数は、それぞれ単独でも便利ですが、組み合わせることで真価を発揮します。
関数の合成は、数学では f(g(x)) と表記します。GLSLでもまったく同じです:
float result = smoothstep(0.3, 0.7, sin(uv.x * 10.0));
この例では、sin で波を作り、smoothstep でなめらかに2値化しています。
合成のパターン
入力の加工(関数の内側)
関数の入力を加工して、形を変形させます:
// 通常の sin 波
float wave = sin(uv.x * 10.0);
// 入力を歪ませた sin 波
float distorted = sin(uv.x * 10.0 + sin(uv.y * 5.0));
y座標に応じて波がうねるようになります。
出力の加工(関数の外側)
関数の出力を加工して、見た目を変えます:
float wave = sin(uv.x * 10.0);
// abs で折り返し
float folded = abs(wave);
// pow でコントラスト調整
float sharp = pow(abs(wave), 0.5);
複数関数の合成
// 波打つストライプ
float stripe = sin(uv.x * 20.0 + sin(uv.y * 8.0 + u_time) * 2.0);
stripe = smoothstep(-0.1, 0.1, stripe);
掛け算と足し算
掛け算(マスク)
2つのパターンを掛け合わせると、一方がもう一方の「マスク」として機能します:
float horizontal = smoothstep(0.3, 0.7, fract(uv.x * 5.0));
float vertical = smoothstep(0.3, 0.7, fract(uv.y * 5.0));
float grid = horizontal * vertical;
足し算(重ね合わせ)
パターンを足し合わせると、両方が見える合成になります:
float pattern = wave1 + wave2;
pattern = clamp(pattern, 0.0, 1.0);
min/max(ブール的な合成)
float unionShape = min(shape1, shape2); // 和(OR的)
float intersectShape = max(shape1, shape2); // 積(AND的)
自作シェーピング関数
よく使うパターンは関数にまとめましょう:
// パルス: center を中心に width の幅の矩形波
float pulse(float x, float center, float width) {
float half = width * 0.5;
return smoothstep(center - half - 0.01, center - half, x) -
smoothstep(center + half, center + half + 0.01, x);
}
// リマップ: 値を新しい範囲にマッピング
float remap(float value, float low1, float high1, float low2, float high2) {
return low2 + (value - low1) * (high2 - low2) / (high1 - low1);
}
実践: 複雑なパターン
右のプレビューでは、複数の関数を合成して複雑なパターンを作っています。コードを読み解いて、それぞれの関数がどのような役割を果たしているか確認してみましょう。
まとめ
- 関数の入力を加工して形を変形
- 関数の出力を加工して見た目を調整
- 掛け算でマスク、足し算で重ね合わせ
min/maxでブール的な合成- よく使うパターンは自作関数にまとめる