クロス♰を敷き詰める模様を書いてみます。
以下の #つぶやきGLSL の作成ログでもあります( #17 )。
#つぶやきGLSL#define C(c,k)q=abs((p-vec2(i,j)*.2-.1-a*k)*m);q=(q.y>q.x)?q.yx:q.xy;if(q.x<.06&&q.y<.02)o.c+=.8;
vec2 p=FC.xy/r,a=vec2(.08,.04),q;
mat2 m=mat2(cos(t),sin(t),-sin(t),cos(t));
for(float i=-2.;i<5.;i++)for(float j=-1.;j<5.;j++){
C(rg,0.)C(r,1.)C(g,2.)C(b,3.)C(rgb,4.)} pic.twitter.com/04GQ5tj7zd— Narumium (@Nr_Narumium) November 29, 2020
基本の十字
距離関数で書くこともできますが、のちに重ね合わせるため条件文で書きます。
1 2 3 4 5 6 7 8 |
precision highp float; uniform vec2 resolution; void main(){ vec2 r=resolution,p=(gl_FragCoord.xy*2.-r)/min(r.x,r.y); p=abs(p); p=(p.y>p.x)?p.yx:p.xy; if(p.x<.8&&p.y<.2)gl_FragColor=vec4(1); } |
敷き詰める
【GLSL】パターンの書き方2つ でやったように敷き詰めます。
重ねていくので fract でなく for で1つづつ。
1 2 3 4 5 6 7 8 9 10 |
void main(){ vec2 r=resolution,p=(gl_FragCoord.xy)/min(r.x,r.y); for(int i=0;i<5;i++){ for(int j=0;j<5;j++){ vec2 p=abs(p-vec2(float(i),float(j))*.2-.1); p=(p.y>p.x)?p.yx:p.xy; if(p.x<.08&&p.y<.02)gl_FragColor+=vec4(1); } } } |
ずらす
十字をパターンに合わせて少しずらして描画します。
単純に for 文を分けてわかりやすく。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
void main(){ vec2 r=resolution,p=(gl_FragCoord.xy)/min(r.x,r.y); for(int i=0;i<5;i++){ for(int j=0;j<5;j++){ vec2 p=abs(p-vec2(float(i),float(j))*.2-.1); p=(p.y>p.x)?p.yx:p.xy; if(p.x<.1*3./5.&&p.y<.0333*3./5.)gl_FragColor+=vec4(1); } } for(int i=0;i<5;i++){ for(int j=0;j<5;j++){ vec2 p=abs(p-vec2(float(i),float(j))*.2-.1-vec2(.08,.04)); p=(p.y>p.x)?p.yx:p.xy; if(p.x<.1*3./5.&&p.y<.0333*3./5.)gl_FragColor.r+=.5; } } for(int i=0;i<5;i++){ for(int j=0;j<5;j++){ vec2 p=abs(p-vec2(float(i),float(j))*.2-.1-vec2(.16,.08)); p=(p.y>p.x)?p.yx:p.xy; if(p.x<.1*3./5.&&p.y<.0333*3./5.)gl_FragColor.g+=.5; } } for(int i=0;i<5;i++){ for(int j=0;j<5;j++){ vec2 p=abs(p-vec2(float(i),float(j))*.2-.1-vec2(.24,.12)); p=(p.y>p.x)?p.yx:p.xy; if(p.x<.1*3./5.&&p.y<.0333*3./5.)gl_FragColor.b+=.5; } } for(int i=0;i<5;i++){ for(int j=0;j<5;j++){ vec2 p=abs(p-vec2(float(i),float(j))*.2-.1-vec2(.32,.16)); p=(p.y>p.x)?p.yx:p.xy; if(p.x<.1*3./5.&&p.y<.0333*3./5.)gl_FragColor.rgb+=.5; } } } |
白をベースに右上に赤、緑、青、灰の十字を重ねています。
処理の統一
処理を整理するとこんな感じにまとめられます。
左下を埋めるために for 文も少し変更。
1 2 3 4 5 6 7 8 9 10 11 |
#define C(c,k)q=abs(p-vec2(float(i),float(j))*.2-.1-a*k);q=(q.y>q.x)?q.yx:q.xy;if(q.x<.06&&q.y<.02)gl_FragColor.c+=.5; void main(){ vec2 r=resolution,p=(gl_FragCoord.xy)/min(r.x,r.y),a=vec2(.08,.04),q; for(int i=-2;i<5;i++)for(int j=-1;j<5;j++){ C(rg,0.) C(r,1.) C(g,2.) C(b,3.) C(rgb,4.) } } |
回転を付けて geekest モードでこんな感じです(つぶやいたやつ)。
1 2 3 4 5 6 |
#define C(c,k)q=abs((p-vec2(i,j)*.2-.1-a*k)*m);q=(q.y>q.x)?q.yx:q.xy;if(q.x<.06&&q.y<.02)o.c+=.8; vec2 p=FC.xy/r,a=vec2(.08,.04),q; mat2 m=mat2(cos(t),sin(t),-sin(t),cos(t)); for(float i=-2.;i<5.;i++)for(float j=-1.;j<5.;j++){ C(rg,0.)C(r,1.)C(g,2.)C(b,3.)C(rgb,4.) } |
文字数の関係でこれ以上の処理を乗せれなかったんですが、何を回転させるかによって色々変わります。
余裕があれば色によって速度や回転方向を変えたりするのもしたかった。
十字の敷き詰めは、もう一つ書き方を思いついてるので次の記事で書きます。