title: "線とストローク" description: "SDFからアウトライン(ストローク)を生成する方法を学びます。abs(sdf)を使ったテクニックを理解しましょう。" chapter: "04-shapes" order: 4 challenge: description: "矩形のアウトライン(枠線)を描いてください。矩形のサイズは 0.3 x 0.2、線の太さは 0.01 にしましょう。" hints:
- "アウトラインは abs(sdf) - thickness で作れます。"
- "sdBox 関数で矩形のSDFを計算し、abs() で絶対値を取ってから太さを引きます。"
- "float outline = smoothstep(0.005, 0.0, abs(sdBox(p, vec2(0.3, 0.2))) - 0.01); で矩形のアウトラインになります。"
線とストローク
SDFからアウトラインを作る
SDFの大きな利点のひとつは、図形のアウトライン(ストローク)が簡単に作れることです。
SDFの値がゼロの位置が図形の表面です。アウトラインとは、表面の近くだけを描画することです。つまり、SDFの絶対値が小さい領域を抽出すればよいのです:
float outline = abs(d) - thickness;
abs(d) は表面からの距離(方向を問わず)を返します。そこから太さを引くと、表面付近だけが負の値になる新しいSDFが得られます。
円のアウトライン
float d = length(p) - 0.3;
float outline = abs(d) - 0.01; // 太さ 0.01 のアウトライン
float stroke = smoothstep(0.005, 0.0, outline);
これだけで、塗りつぶしではなく輪郭だけの円が描けます。
任意のSDFでアウトライン
この手法はどんなSDFにも使えます:
// 矩形のアウトライン
float d = sdBox(p, vec2(0.3, 0.2));
float outline = abs(d) - 0.01;
float stroke = smoothstep(0.005, 0.0, outline);
塗りとストロークの組み合わせ
塗り(fill)とストローク(stroke)を組み合わせることもできます:
float d = sdCircle(p, 0.2);
// 塗り(内側全体)
float fill = smoothstep(0.005, 0.0, d);
// ストローク(外側にも広がるアウトライン)
float stroke = smoothstep(0.005, 0.0, abs(d) - 0.02);
vec3 color = vec3(0.0);
color += fill * vec3(0.2, 0.3, 0.5); // 塗りの色
color += stroke * vec3(1.0, 0.8, 0.2); // ストロークの色
複数のリング
SDFを使えば、同心円のようなパターンも簡単です:
float d = length(p) - 0.3;
float rings = abs(fract(d * 10.0) - 0.5) - 0.1;
float pattern = smoothstep(0.005, 0.0, rings);
fract で距離を繰り返しパターンに変換し、等間隔のリングを生成しています。
まとめ
abs(sdf) - thicknessでアウトライン(ストローク)が作れる- この手法はどんなSDF図形にも適用できる
- 塗りとストロークを組み合わせてリッチな表現が可能
fractと組み合わせて繰り返しパターンも作れる