mo49
9/18/2019 - 3:30 AM

00_CellularNoiseAndVoronoi.md

セルラーノイズ

http://glslsandbox.com/e#57530

ボロノイ

http://glslsandbox.com/e#57531

解説

隣接するタイルも見ているのは...

一番近い点は、あるピクセルが存在する格子ではなく、そのピクセルが存在する格子の周辺の格子に一番近い点が存在する可能性があります。

セルラーノイズは、一番近い点までの距離で色を決めている(グラデーション)
ボロノイは、一番近い点の座標で領域を分けて色を決めている

cf.

ドロネー図

ドロネー図の双対はボロノイ図であり、ドロネー図はボロノイ領域の隣接関係を表している。

#ifdef GL_ES
precision mediump float;
#endif

#extension GL_OES_standard_derivatives : enable

uniform float time;
uniform vec2 mouse;
uniform vec2 resolution;

vec2 random2( vec2 p ) {
    return fract(sin(vec2(dot(p,vec2(127.1,311.7)),dot(p,vec2(269.5,183.3))))*43758.5453);
}

// cellular noise
void main() {
	vec2 st = gl_FragCoord.xy/resolution.xy;
	st.x *= resolution.x/resolution.y;
	vec3 color = vec3(.0);
	
	st *= 3.;
	
	vec2 i_st = floor(st);
	vec2 f_st = fract(st);
	
	float m_dist = 1.;
	
	// 現在のタイルに隣接するものだけ
	for(int y=-1; y <= 1; y++){
		for(int x=-1; x <= 1; x++){
			vec2 neighbor = vec2(float(x), float(y));
			
			// 隣接するタイルの中の点
			// Random position from current + neighbor place in the grid
			vec2 point = random2(i_st + neighbor);
			
			// animate
			point = 0.5 + 0.5*sin(time + 6.2831*point);
			
			// 点までの最小距離を測る by IQ
			// Vector between the pixel and the point
			vec2 diff = neighbor + point - f_st;
			
			// Distance to the point
			float dist = length(diff);
			
			m_dist = min(m_dist, dist);
		}
	}
	
	// 中心に近いほど最小距離が小さいので黒くなる
	color += m_dist;
	
	// Draw cell center
	color += 1.-step(0.02, m_dist);
	
	// Draw grid
	color.r += step(.99, f_st.x) + step(.99, f_st.y);
	
	gl_FragColor = vec4(color, 1.0);
}
#ifdef GL_ES
precision mediump float;
#endif

#extension GL_OES_standard_derivatives : enable

uniform float time;
uniform vec2 mouse;
uniform vec2 resolution;

vec2 random2( vec2 p ) {
    return fract(sin(vec2(dot(p,vec2(127.1,311.7)),dot(p,vec2(269.5,183.3))))*43758.5453);
}

// Voronoi
void main() {
	vec2 st = gl_FragCoord.xy/resolution.xy;
	st.x *= resolution.x/resolution.y;
	vec3 color = vec3(.0);
	
	st *= 3.;
	
	vec2 i_st = floor(st);
	vec2 f_st = fract(st);
	
	float m_dist = 1.;
	vec2 m_point;
	
	// 現在のタイルに隣接するものだけ
	for(int y=-1; y <= 1; y++){
		for(int x=-1; x <= 1; x++){
			vec2 neighbor = vec2(float(x), float(y));
			
			// 隣接するタイルの中の点
			// Random position from current + neighbor place in the grid
			vec2 point = random2(i_st + neighbor);
			
			// animate
			point = 0.5 + 0.5*sin(time + 6.2831*point);
			
			// 点までの最小距離を測る by IQ
			// Vector between the pixel and the point
			vec2 diff = neighbor + point - f_st;
			
			// Distance to the point
			float dist = length(diff);
			
			// より近い点が見つかるたびに位置を記録
			if(dist < m_dist){
				m_dist = dist;
				m_point = point;
			}
		}
	}
	
	// 最も近い点から色を決定
	color += dot(m_point, vec2(.3,.6));
	
	// Draw cell center
	color += 1.-step(0.02, m_dist);
	
	// Draw grid
	color.r += step(.99, f_st.x) + step(.99, f_st.y);
	
	gl_FragColor = vec4(color, 1.0);
}