前回 React
+ GLSL
で音声波形の表示ができたので、どんなふうに描画するのがいいかいくつか試してみました。
今回は基本的に GLSL
のコードサンプルになります。
線グラフ
「線分を引く」でやったように波形を線にします。
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 |
precision highp float; varying vec2 uv; uniform sampler2D t; uniform float data[1024]; float cs; void line(vec2 s,vec2 e){ vec2 p=uv; vec2 se=e-s,ps=s-p,pe=e-p; if(dot(ps,se)*dot(pe,se)>=0.)return; if(s.x!=e.x){ float a=(e-s).y/(e-s).x; float d=abs(a*p.x-p.y-a*s.x+s.y)/sqrt(a*a+1.); cs=max(pow(3e-3/(d+1e-6),3.),cs); }else{ float d=abs(p.x-s.x); cs=max(pow(3e-3/(d+1e-6),3.),cs); } } void main(){ vec4 c=texture2D(t,uv); for(int i=0;i<1023;i++){ vec2 s=vec2(float(i)/1024.,data[i]/256.); vec2 e=vec2(float(i+1)/1024.,data[i+1]/256.); line(s,e); } c+=cs*vec4(1,0,0,1); gl_FragColor=c; } |
棒グラフ
fftSize
に合わせて縦線を引く。
1 2 3 4 5 6 7 8 9 10 |
void main(){ vec4 c=texture2D(t,uv); for(int i=0;i<1024;i++){ vec2 s=vec2(float(i)/1024.,data[i]/256.); vec2 e=vec2(float(i)/1024.,.5); line(s,e); } c+=cs*vec4(1,0,0,1); gl_FragColor=c; } |
棒グラフ2
先ほどの棒を上下に書くだけ。
よく見かけるし音の波形というとコレというイメージがあります。
1 2 3 4 5 6 7 8 9 10 11 |
void main(){ vec4 c=texture2D(t,uv); for(int i=0;i<1024;i++){ vec2 s=vec2(float(i)/1024.,data[i]/256.); vec2 e=vec2(float(i)/1024.,.5); line(s,e); line(vec2(s.x,1.-s.y),e); } c+=cs*vec4(1,0,0,1); gl_FragColor=c; } |
2色塗り分け
data
の値の上下で色を塗り分ける。
個人的にはこれが一番好き。
1 2 3 4 5 6 7 8 9 10 11 |
vec3 cc,u=vec3(.3,0,0),d=vec3(0,.3,0); void main(){ vec4 c=texture2D(t,uv); for(int i=0;i<1024;i++){ vec2 v=vec2(float(i)/1024.,data[i]/256.); if(abs(uv.x-v.x)<.001) if(uv.y<v.y)cc=u;else cc=d; } c.rgb+=cc; gl_FragColor=c; } |
2色塗り分けと棒グラフ
一番気に入った塗分けに棒グラフを重ねます。
横長の方が見栄えが良い気がしたので最後は適当な画像に重ねました。
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 |
precision highp float; varying vec2 uv; uniform sampler2D t; uniform float data[1024]; float cs; void line(vec2 s,vec2 e){ vec2 p=uv; vec2 se=e-s,ps=s-p,pe=e-p; if(dot(ps,se)*dot(pe,se)>=0.)return; if(s.x!=e.x){ float a=(e-s).y/(e-s).x; float d=abs(a*p.x-p.y-a*s.x+s.y)/sqrt(a*a+1.); cs=max(pow(3e-3/(d+1e-6),3.),cs); }else{ float d=abs(p.x-s.x); cs=max(pow(3e-3/(d+1e-6),3.),cs); } } vec3 cc,u=vec3(.3,0,0),d=vec3(0,.3,0); void main(){ vec4 c=texture2D(t,uv); for(int i=0;i<1024;i++){ vec2 v=vec2(float(i)/1024.,data[i]/256.); if(abs(uv.x-v.x)<.001) if(uv.y<v.y)cc=u;else cc=d; if(i!=1023)line(v,vec2(float(i+1)/1024.,data[i+1]/256.)); } c.rgb+=cc+cs*vec3(0,0,1); gl_FragColor=c; } |
塗り分けの条件や棒グラフの線分の太さを変えると、色が重なってシアンやマゼンタになっている部分の形を変えられます。