title: "矩形" description: "abs関数を使って矩形のSDFを構築する方法と、角丸矩形の作り方を学びます。" chapter: "04-shapes" order: 3 challenge: description: "画面中央に角丸矩形を描いてください。角の丸み(radius)を 0.05 に設定し、矩形のサイズは横 0.4、縦 0.25 にしましょう。" hints:
- "角丸矩形は sdBox の結果から角丸の半径を引くことで作れます。"
- "sdBox の引数 b を (0.4 - 0.05, 0.25 - 0.05) のように角丸分だけ小さくし、結果から 0.05 を引きます。"
- "float d = sdBox(p, vec2(0.35, 0.20)) - 0.05; で角丸矩形になります。"
矩形
abs()を使った矩形のSDF
矩形のSDFは、abs() 関数を使って構築します。考え方は:
- 座標の絶対値を取る(対称性を利用)
- 矩形の半分のサイズを引く
- 外側の距離を計算する
float sdBox(vec2 p, vec2 b) {
vec2 d = abs(p) - b;
return length(max(d, 0.0)) + min(max(d.x, d.y), 0.0);
}
この関数を分解して理解しましょう:
ステップ1: abs(p) - b
abs(p) で座標を第1象限に折りたたみます。矩形は対称なので、4つの象限すべてを同じように扱えます。そこから矩形の半サイズ b を引きます。
ステップ2: 外側の距離
length(max(d, 0.0)) は矩形の外側の距離を正しく計算します。max(d, 0.0) で負の成分をゼロにクランプし、外側の距離だけを残します。
ステップ3: 内側の距離
min(max(d.x, d.y), 0.0) は矩形の内側の距離(負の値)を返します。
矩形を描く
vec2 p = uv - vec2(0.5);
p.x *= u_resolution.x / u_resolution.y;
float d = sdBox(p, vec2(0.3, 0.2));
float box = smoothstep(0.005, 0.0, d);
角丸矩形
角丸矩形は驚くほど簡単に作れます。SDFの結果から角丸の半径を引くだけです:
float roundRadius = 0.05;
// 矩形サイズを角丸分だけ小さくする
float d = sdBox(p, vec2(0.3 - roundRadius, 0.2 - roundRadius)) - roundRadius;
SDFから定数を引くと、図形が均一に膨張します。これは等距離面のオフセットと同じで、角が自然に丸くなります。
まとめ
- 矩形のSDFは
abs()を使って対称性を利用する length(max(d, 0.0)) + min(max(d.x, d.y), 0.0)で正確な距離が得られる- SDFから定数を引くだけで角丸矩形が作れる