from つぶやきGLSL

これを理解したい

void main(){vec2 p=(.5-fract(mat2(cos(-t*.4+vec4(1,33,11,1)))*(gl_FragCoord.xy*2.-r)/min(r.y,r.x)))*2.4;float q=length(p),a=atan(p.y,p.x)*2.5+t*2.;gl_FragColor=vec4(mix(q*.9*step(q,min(abs(sin(a))+.4,abs(cos(a))+1.1)*.7),.7,step(q,.15)));}
  • image

どうやって動かすのか

  • GLSL Sandboxってのがあるらしい
  • GLSL Sandboxで遊ぼう | notargs.com
  • エラーメッセージはどうやって見るのか
    • コンソールに出てた
  • tとrをtimeとresolutionに変更したら動いた
    • image

OpenGL 4.x Reference Pages

時間による拡大縮小部分 :

mat2(
    cos(-time * .4 + vec4(1,33,11,1))
) 

タイリング :

vec2 from_center_x2 = (gl_FragCoord.xy * 2. - resolution);
vec2 p1 = from_center_x2 / min(resolution.y, resolution.x); 
vec2 p2 = fract(p1); 
vec2 p=( .5 - p2 ) * 2.4;
  • image

中心からの距離 :

float q=length(p);

中心からの角度

  • 2.5倍しているので、一周で5π、これが花びらの枚数になる。時刻を足しているので時間経過で回転する :
float a=atan(p.y, p.x) * 2.5 + time * 2.;

step(q, edge)

  • 「中心からの距離がedge以下なら1.0」ということなので中心付近を塗るのに使える

輪郭の形 :

min(abs(sin(a))+.4, abs(cos(a))+1.1) 
  • image

中心からの距離に応じたグラデーション :

q * .9 * step( ... )

これは中央の丸 :

step(q,.15)

yが固定のmixは何か

  • aが0の時x、1の時y、という条件分岐

拡大縮小部分のコード :

mat2 m = mat2(cos(-time * .4 + vec4(1,33,11,1)));
vec2 p2 = fract(m * p1);
  • 33などのマジックナンバー
    • どうせcosに入れるので2πの倍数には意味がない
    • 計算してみるとπ/2の倍数に近い値
    • ショートコーディングのためのテクニックに過ぎない
    • 下記のコードと振る舞いは同じ :
float pi = 3.14159;
mat2 m2 = mat2(
  cos(-.4 * time + 1.), 
  cos(-.4 * time + pi * 0.5), 
  cos(-.4 * time + pi * 1.5),
  cos(-.4 * time + 1.));
vec2 p2 = fract(m2 * p1);
- sinも使うとこうなる

:

float t = -.4 * time;
mat2 m2 = mat2(cos(t + 1.), -sin(t), sin(t), cos(t + 1.));
vec2 p2 = fract(m2 * p1);
    - cosに対する+1.がなければ単なる回転になる

ここまでを踏まえて少し改造した