はじめに
2次元ディスタンスフィールドまとめでは色々な距離関数(ディスタンスフィールド)について紹介しました。しかし、距離関数(ディスタンスフィールド)だけでは図形を描くことはできません。距離関数(ディスタンスフィールド)に距離を設定することではじめて図形を描くことができます。ここでは、距離関数(ディスタンスフィールド)に距離を設定して、塗り、線、グロウなど、様々な図形の描画方法を紹介します。
距離の設定と、線・塗り
距離を設定する(放射状グラデーション塗り)
まず、素のままの距離関数(ディスタンスフィールド)を可視化してみます。
precision mediump float;
uniform vec2 m; // mouse
uniform float t; // time
uniform vec2 r; // resolution
uniform sampler2D smp; // prev scene
void main(void){
vec2 p = (gl_FragCoord.xy * 2.0 - r) / min(r.x, r.y);
float distanceFunc;
float bright;
float radius=.5;
distanceFunc = length(p);
// direct output
bright = distanceFunc;
// gradation circle
//bright = radius - distanceFunc;
// circle fill
//bright = step(0.,radius - distanceFunc);
// circle stroke
//bright = 1.-step(.005,abs(radius - distanceFunc));
// circle fill + glow
//bright = radius / distanceFunc;
gl_FragColor = vec4(vec3(bright), 1.0);
}
この時点ではまだ図形が確定していません。
これに距離.5を与えてあげると半径0.5のグラデーションの円が描けます。
bright = radius - distanceFunc;
べた塗り
グラデーションの塗りで0.以上を1.としてあげればベタ塗りが出来ます。
bright = step(0.,radius - distanceFunc);
線
bright = step(abs(radius - distanceFunc),.005);
塗り+ glow
bright = radius / distanceFunc;
glow
グロウ
bright = 0.01 / abs(distanceFunc - radius);
グロウ(外側)
bright = 0.01 / (distanceFunc - radius);
グロウ(内側)
bright = 0.01 / -(distanceFunc - radius);
アンチエイリアス
線や塗りで、stepのところをsmoothstepに変えて極小な範囲を設定するとアンチエイリアスを掛ける(ギザギザを無くす)ことができます。
bright = smoothstep(0.,.01,radius - distanceFunc);
bright = 1.-smoothstep(.005,.015,abs(radius - distanceFunc));
グラデーション
smoothstepの範囲を大きくすると任意の長さのグラデーションとして利用できます。
bright = smoothstep(0.,.5,radius - distanceFunc);
bright = 1.-smoothstep(.005,.5,abs(radius - distanceFunc));