VEDAを用いたGLSLのライブコーディングの練習をしていて、fbm関数の特性にとても興味があったので試しに使ってみました。
fbm関数
fbm.frag
float random (in vec2 st) {
return fract(sin(dot(st.xy,
vec2(12.9898,78.233)))
* 43758.5453123);
}
float noise (in vec2 st) {
vec2 i = floor(st);
vec2 f = fract(st);
float a = random(i);
float b = random(i + vec2(1.0, 0.0));
float c = random(i + vec2(0.0, 1.0));
float d = random(i + vec2(1.0, 1.0));
vec2 u = f*f*(3.0-2.0*f);
return mix(a, b, u.x) +
(c - a)* u.y * (1.0 - u.x) +
(d - b) * u.x * u.y;
}
float fbm ( in vec2 _st) {
float v = 0.0;
float a = 0.5;
vec2 shift = vec2(100.0);
mat2 rot = mat2(cos(0.5), sin(0.5),
-sin(0.5), cos(0.50));
for (float i = 0.0; i < 5.0; ++i) {
v += a * noise(_st);
_st = rot * _st * 2.0 + shift;
a *= 0.5;
}
return v;
}
ここの記事がとても勉強になりました。
コード
helloworld.frag
/*{
"audio": true,
}*/
precision mediump float;
uniform float time;
uniform vec2 resolution;
uniform float volume;
float random (in vec2 st) {
return fract(sin(dot(st.xy,
vec2(12.9898,78.233)))
* 43758.5453123);
}
float noise (in vec2 st) {
vec2 i = floor(st);
vec2 f = fract(st);
float a = random(i);
float b = random(i + vec2(1.0, 0.0));
float c = random(i + vec2(0.0, 1.0));
float d = random(i + vec2(1.0, 1.0));
vec2 u = f*f*(3.0-2.0*f);
return mix(a, b, u.x) +
(c - a)* u.y * (1.0 - u.x) +
(d - b) * u.x * u.y;
}
float fbm ( in vec2 _st) {
float v = 0.0;
float a = 0.5;
vec2 shift = vec2(100.0);
mat2 rot = mat2(cos(0.5), sin(0.5),
-sin(0.5), cos(0.50));
for (float i = 0.0; i < 5.0; ++i) {
v += a * noise(_st);
_st = rot * _st * 2.0 + shift;
a *= 0.5;
}
return v;
}
void main() {
vec2 point = (gl_FragCoord.xy * 2. - resolution) / min(resolution.x, resolution.y);
vec3 orbs = vec3(0.0);
for(float loop = 0.0; loop < 5.0; loop++) {
vec2 q = point + vec2(fbm(point + sin(time)) * loop, fbm(point + time) * loop);
orbs += 0.1 * abs(sin(time)) / length(q);
}
gl_FragColor = vec4(vec3(orbs), 1.0);
}
クリエイティブコーディングやっぱ面白いです。