線とストローク


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 と組み合わせて繰り返しパターンも作れる