見出し画像

Signed distance functions 符号付き距離関数

「符号付き距離関数」(“Signed distance functions”、略してSDF)とは怖そうな名前ですが、実は割とシンプルです。SDFとは、ある点がある他の形の表面、例えば球面から(通常ユークリッド空間で)どのくらい離れているかを教えてくれる関数です。
“Signed distance functions”, or SDF sounds scary but it is not too crazy to understand. A SDF is a function that can tell you how far a point is from a surface of a shape, say a sphere (usually in Euclidean space)

For example the distance of a point of from the surface of a sphere can be expressed as below where $${p}$$ is the coordinate of the point, $${c}$$ is the center of the sphere, and $${r}$$ is the radius:
例えば、ある点が球の表面からどれくらい離れているかは、その点の座標を$${p}$$、球の中心を$${c}$$、半径を$${r}$$とすると、次のように表すことができます。

$${d = \sqrt{(p_{x}-c_{x})^{2} + (p_{y}-c_{y})^{2} + (p_{z}-c_{z})^{2}} - r}$$

This is very interesting because SDF is the technique used as basis for many mind-blowing 3D graphics demos with really small amount of code you often find on ShaderToy.
なぜこれが面白いかというと、SDFはShaderToyでよく見かける、短いコードで凄まじいクオリティの3Dグラフィックを実現するデモの背景にある技術だからです。

2D Demos

The three demonstrations below use SDF to define different shapes and fill in the inside and outside of the shape with dots.
下の3つのデモではSDFを用いてそれぞれ異なる形を定義し、形の内側と外側を点で塗りつぶしています。

The size of the dot represents the distance from the shape's boundary (the smaller the closer). White dots represent the inside of the shape. Black dots are outside the shape.
点の大きさは、図形の境界線からの距離を表しています(小さいほど近い)。白い点はシェイプの内側を表します。黒い点は図形の外側にあります。

function sdf(p, center, radius) {
    return Math.sqrt(Math.pow(p.x - center.x, 2) + Math.pow(p.y - center.y, 2)) - radius; // or use p5.Vector.dist()
}

I don't seem to be able to adjust the size of the Codepen embeddings. Please click the Codepen logo to open it in a new window if the demo is clipped.
Codepen埋め込みの大きさが調整できないようなので、はみ出している場合はロゴをクリックして別ウィンドウで開いてください。

function sdf(p, size, center) {
    const diff = p.copy().sub(center);
    return Math.max(Math.abs(diff.x) - size.x, Math.abs(diff.y) - size.y);
}
function sdf(p, size, center) {
    let diff = p.copy().sub(center);
    diff = rotate2d(diff, Math.PI * 0.25);
    return Math.max(Math.abs(diff.x) - size.x, Math.abs(diff.y) - size.y);
}

It will be fun to try coming up with your own new formulas and see what shapes you can draw with it. Inigo Quilez's site has great references of SDFs and functions for transforming and merging shapes.
自分で新しい式を考えて、どんな形が描けるか試してみるのも楽しいでしょう。Inigo Quilez のサイトには沢山のSDFや形を変形させたり合体させたりための関数の例があるので参考にしてください。

3D Demos

Below are a couple of examples of rendering 3D shapes using SDF.
下記はSDFを使って3D描画を行なった例です。

Shadertoy Demo

Shadertoy Demo

For learning about how to draw 3D graphics using SDF, the following sites are highly recommended.
SDFを使って3Dグラフィックを描く方法については下記のサイトがお勧めです。

This is a copy from kyndinfo.notion.site. Here's the original page.
このページはkyndinfo.notion.site からの転載です。元のページはこちら。

この記事が気に入ったらサポートをしてみませんか?