スケール


title: "スケール" description: "座標のスケーリングとSDFスケール時の注意点を学びます。非均一スケールで楕円を作る方法も理解しましょう。" chapter: "05-transforms" order: 2 challenge: description: "楕円を描いてください。円のSDFに非均一スケール(x方向とy方向で異なるスケール)を適用して、横長の楕円を作りましょう。" hints:

  • "座標をスケールしてから円のSDFに渡すと、楕円になります。"
  • "vec2 sp = p * vec2(1.0, 2.0); のようにy方向を2倍にすると、y方向が圧縮された(横長の)楕円になります。"
  • "非均一スケール時はSDFの距離が歪むので、補正が必要な場合があります。簡単な方法は結果をスケール係数の最小値で割ることです。"

スケール

均一スケール

座標全体を同じ比率で拡大・縮小するのが均一スケールです:

vec2 sp = p / scale; // scaleが2.0なら図形が2倍に
float d = sdCircle(sp, 0.2);
d *= scale; // SDFの距離を補正

重要なポイント:座標を縮小すると図形は拡大されます。スケールファクターで割ることで、座標空間を縮小し、結果的に図形が拡大して見えます。

また、SDFの距離値もスケールの影響を受けるため、結果にスケール係数を掛けて補正する必要があります。

SDFスケール時の注意点

SDFの基本的な性質は「表面からの正確な距離を返す」ことです。座標をスケールすると、この距離が歪んでしまいます。

均一スケールの場合は単純な掛け算で補正できます:

vec2 sp = p / scale;
float d = sdBox(sp, vec2(0.2, 0.1));
d *= scale; // 補正

非均一スケール

x方向とy方向で異なるスケールを使うと、図形が変形します。これを使うと、円から楕円を作れます:

vec2 scale = vec2(1.0, 2.0); // y方向を2倍に圧縮
vec2 sp = p * scale;
float d = sdCircle(sp, 0.3);

座標のy成分を2倍にすると、y方向の距離が2倍に伸びるため、結果としてy方向が半分に圧縮された楕円になります。

非均一スケールの距離補正

非均一スケールでは正確なSDF補正が難しいですが、近似的には:

d /= max(scale.x, scale.y); // 近似的な補正

完全に正確ではありませんが、描画には十分な精度が得られます。

中心を基準にスケール

回転と同様に、スケールもデフォルトでは原点基準です。任意の点を中心にスケールするには:

vec2 center = vec2(0.3, 0.2);
vec2 sp = (p - center) / scale + center;

ただし、通常は座標系を最初に uv - 0.5 で中心に移動しているため、そのまま原点基準のスケールで問題ありません。

まとめ

  • 均一スケールは座標をスケール係数で割り、SDFにスケール係数を掛けて補正
  • 非均一スケールで円を楕円に変形できる
  • スケール後はSDFの距離が歪むので補正が必要
  • 回転と組み合わせて様々な変形が可能