2012.02.13 | 

あと15分で月曜日。今回苦戦のため画像が準備できませんでした。
こんばんはmuchoです。

今回はGLSLでGaussian Blurの自作に挑戦しました。
作りたいというか欲しかったのが、とにかく高速で、大きくボケるフィルター。

ズバリ目指したのはこれ↓
http://www.quasimondo.com/StackBlurForCanvas/StackBlurDemo.html
最初はquasimondoさんのソースをさっくり移植しようと思ったんですが、
商用で使ってる方もいるみたいで、二次利用を断念。

こちらのサイトを参考にしました。
http://www.gamerendering.com/2008/10/11/gaussian-blur-filter-shader/
英語なのでいまいちよく分かりませんが、
まず横にぼかしをかけて、
その結果画像をさらに縦にぼかすと
計算が少なくてすむということらしい。
9ピクセルぼかすとすると本来なら
9x9=81
それを横と縦で分けることで
9+9=18
この差は大きい!
実際9x9的な本来のブラーを作ってみましたが、OpenCVのGaussian Blurと比べて
高速化が感じられず、上記の横かけて、縦かけての2段階描画方式にしてみました。
まずはそのままコピペしてみたところ、大きくぼかすとおかしなことに。
というわけで、参考サイトでは9+9固定なのですが、ボカすサイズによって、
描画回数が変わるように書き直してみました。
以下がそのソース。

煮詰まりまくりで作ったので、微妙にソースに意味不明なところがあります。
さらにどうも正弦波の値の求め方がおかしいような?
おまけに、本来のブラーよりは高速化したとはいえ、大きくぼかすと
まだまだ実用には厳しい遅さ。。。
次回はquasimondoさんのソースをさらに読み解きつつ、
これをチューニングできたらと思います。できるのかなー。怪しいなー。



//horizontal Fragment Shader
#version 120
uniform sampler2D texture0;
uniform int width;
uniform int height;
uniform float blurSize;

void main()
{
	float v;
	float w_step = 1.0 / width;
	float h_step = 1.0 / height; 
	float radius = blurSize;
	if ( radius < 0 ) radius = 0;
	int steps = int(radius);
	float x = gl_TexCoord[0].x;
	float y = gl_TexCoord[0].y;
	float pi = 3.141592653589793;
	float t = 1/(steps*2+1);
	vec4 sum = texture2D(texture0, vec2(x, y))*t;
	int i;
	for(i = 1; i<=steps;i++){
		v = (cos(i/(steps+1)*pi)+1)*0.5;
		sum += texture2D(texture0, vec2(x + i*w_step, y))*v*t;
		sum += texture2D(texture0, vec2(x - i*w_step, y))*v*t;
	}
 
  gl_FragColor = sum;
	
}

//---------------------------------------------------------------
//vertical Fragment Shader

#version 120
uniform sampler2D texture0;
uniform int width;
uniform int height;
uniform float blurSize;

void main()
{
	float v;
	float w_step = 1.0 / width;
	float h_step = 1.0 / height; 
	float radius = blurSize;
	if ( radius < 0 ) radius = 0;
	int steps = int(radius);
	float x = gl_TexCoord[0].x;
	float y = gl_TexCoord[0].y;
	float pi = 3.141592653589793;
	float t = 1/(steps*2+1);
	vec4 sum = texture2D(texture0, vec2(x, y))*t;
	int i;
	for(i = 1; i<=steps;i++){
		v = (cos(i/(steps+1)/pi)+1)*0.5;
		sum += texture2D(texture0, vec2(x, y + i*h_step))*v*t;
		sum += texture2D(texture0, vec2(x, y - i*h_step))*v*t;
	}
 
  gl_FragColor = sum;
	
}



2012.02.03 | 

こんばんは。muchoです。
寒い日が続きますね。こんな日はおでんで一杯とか。
そんな夢のような枕詞を置いたところで
今日もはりきっていってみましょう。0時回ってます。

さて今回は前回の続きでnoiseです。
simplex noiseを何回もかけて複雑なnoiseにしようという試みです。
http://www.davidcornette.com/glsl/noise.html
上のサイトに参考画像があるので分かりやすいと思いますが、
ノイズの細かさを変更して何度も計算することで複雑なノイズになります。



	float k = 200;
	float n1 = simplexNoise(vec3(gl_TexCoord[0].x*k*0.005,gl_TexCoord[0].y*k*0.005,time));
	float n2 = simplexNoise(vec3(gl_TexCoord[0].x*k*0.01,gl_TexCoord[0].y*k*0.01,time));
	float n3 = simplexNoise(vec3(gl_TexCoord[0].x*k*0.02,gl_TexCoord[0].y*k*0.02,time));
	float n4 = simplexNoise(vec3(gl_TexCoord[0].x*k*0.03,gl_TexCoord[0].y*k*0.03,time));
	float n5 = simplexNoise(vec3(gl_TexCoord[0].x*k*1.0,gl_TexCoord[0].y*k*1.0,time));
	float n6 = (n1 + n2 + n3 + n4 + n5)*0.2;



こんな感じで5回かけてみました。
n1が一番ゆるくて、n5が一番こまかいです。

さすがに激重かなと思ったのですが、耐えれる速度で動きました。
前回と同じように雲模様的な動画にしてもよかったんですが、
より処理速度が分かるようにと思いカメラ映像に合成してみました。

結局パラメータを調整してノイズを飛ばし気味にしてしまったので、
フラクタル感がいまいちよく分からないですね・・・。

2012.01.29 | 

こんにちは。ってこの時間はこんばんはですかね?
最近ようやくGLSLをさわり始めたmuchoです。
cinderにはPerlin Noiseを生成するPerlinクラスという便利なものがあるんですが、
似たようなことをGLSLでできないだろうか?できない訳ないでしょ!
ということで調べてみたら、noise関数なるものがあることが判明。
しかし、どうもまだ実装されてないらしい・・・。
さらに調べたら、Simplex noiseというアルゴリズムがPerlin Noiseよりよさげで、
さらにSimplex noiseをGLSL化してくれてる人がっ!
https://github.com/ashima/webgl-noise

こりゃあっさり行くんじゃね?と思ったら
さすがGLSL若葉マークのmuchoはごっついはまりました。
そもそも座標変換に使いたかったので、
Vertex Shaderの方で計算させようとしたんですが、
なぜかうまく行きませんでした。

なんじゃこりゃ。
x,yのパラメーターがうまく渡ってないようなのですが、
原因究明には至らず・・・。

そこで、Fragment Shaderで計算させたらこれまたなぜかうまく行った。

高速ですごいことしてるはずなのに全然すごく見えない不思議!

これのソースが以下。と言っても上記のリンク先から移植しただけです。
(続きを読む...)

2012.01.21 | 

だいぶ遅くなりましたが、ようやくキネクトいじれるようになりました。
とりあえず今回はOpenNiを利用したCinder-Kinectを使用してみました。

getDepthImage()で640x480のグレースケールの深度イメージが取得できます。
getDepthData()で最大0xffffまでの数値が640x480個の配列で取得できます。
有効距離はだいたい1m〜10m程度(?)
近すぎると正確なデータが返ってきません。
getDepthData()で取得したデータを映像化してみました。
.H264のmovをvimeoにアップしてみたんですが、
画質の劣化の凄さにびっくり。
アップするときに設定とかあるのかも。
初vimeoなのでよくわかりませんでした。

2011.11.02 | 

こんばんわ DevJamのコータローです。

先日、都内某所で行われたイベントに
極秘潜入してきましたので、レポートいたします。
(続きを読む...)