頭と尻尾はくれてやる!

パソコンおやじのiPhoneアプリ・サイト作成・運営日記


Metalでチューリングパターンを作ってみる

初めてチューリングパターンってのを聞いたのは
所さんの目がテン!
ってテレビ番組。
知識の宝庫!目がテン!ライブラリー
↑第1274回(2015年5月3日)の分みたいだな。ちなみに関西では1週くらい遅れて放送されてるんじゃないかな。

調べたらいろいろと見つかるので勉強はできる、としていざシミュレーションしてみようとすると

[作ってみた] [プログラミング] 反応拡散方程式で遊ぶ | ぞうさんの何でもノート
↑このページがとても役に立ったわ。サンプルコード(C++)もダウンロードできる。ありがたや、ありがたや。

でもいざコードを読んでいくと、、、はて、微分方程式をどうやってシミュレーションするのよ?って思ったんだけど、、、

微分方程式と差分方程式(漸化式)
↑このあたりが助けになったよ。この辺りをヒントに調べれば理解が深まると思う。

Metalでいうとシェーダに現在のテクスチャを与えて、計算、別なテクスチャに出力すればOKってことになるよね。

そうそう、微分方程式に出てくる三角形はなんなの?見るページによってxだけで微分してるけど?なんなの?って頭がこんがらがってきた場合は
ラプラス作用素 - Wikipedia
↑この辺りを参考に。ラプラシアン、、、大昔に習ったような気がしますがこんなところで再会するとは。

ラプラス方程式を差分法で解いてみる - Kiの研究部屋
↑ラプラシアンを差分化する時にここもとても参考になった。なるほど、そういうことかとこれでようやくサンプルコードでやってることに納得。

というわけで、これをMetalのシェーダでやってみるんだけど、テクスチャのメモリを確保しといてcompute shaderに現在のテクスチャと出力用の新しいテクスチャを渡してやる、、、って流れは画像処理のサンプルと同じだね。
シェーダ内はこんな感じ。u,vはそれぞれRGBAのr,gにそれぞれ割りあててる。
fとkとru,rv(拡散係数)はCPU側からFKD_tって構造体使って渡してる。
実行される時のピクセル位置が簡単にわかるのがcompute shaderのいいところだなあ。
kernel void turing(texture2d<half, access::read>  inTexture   [[ texture(0) ]],
                     texture2d<half, access::write> outTexture  [[ texture(1) ]],
                     constant FKD_t &coefficients [[ buffer(0) ]],
                      uint2 gid  [[ thread_position_in_grid ]],
                        uint2 imageSize [[ threads_per_grid ]])
{
    uint xx = gid[0];
    uint yy = gid[1];
    
    float f = coefficients.f;
    float k = coefficients.k;
    float ru = coefficients.ru;
    float rv = coefficients.rv;

    float u_next , v_next;
    
    
    if ( (xx == 0)||(yy == 0)||(xx == imageSize[0]-1)||(yy == imageSize[1]-1) ) {
        u_next = 0.0;
        v_next = 0.0;
    } else {
        half4 inColor  = inTexture.read(gid);
        half u = inColor[0];// r
        half v = inColor[1];// g
        
        half4 inColor1 = inTexture.read(uint2(xx+1,yy));
        half4 inColor2 = inTexture.read(uint2(xx-1,yy));
        half4 inColor3 = inTexture.read(uint2(xx,yy+1));
        half4 inColor4 = inTexture.read(uint2(xx,yy-1));
        float u_xm1_y = inColor2[0];
        float u_xp1_y = inColor1[0];
        float u_x_ym1 = inColor4[0];
        float u_x_yp1 = inColor3[0];
        float v_xm1_y = inColor2[1];
        float v_xp1_y = inColor1[1];
        float v_x_ym1 = inColor4[1];
        float v_x_yp1 = inColor3[1];
        
        u_next = u + ru*( (u_x_ym1 - 2.0*u + u_x_yp1) + (u_xm1_y - 2.0*u + u_xp1_y)) - u*v*v + f*(1.0-u);
        v_next = v + rv*( (v_x_ym1 - 2.0*v + v_x_yp1) + (v_xm1_y - 2.0*v + v_xp1_y)) + u*v*v - (f+k)*v;
        
    }
    
    half4 outColor = half4(u_next, v_next, 0.0, 1.0);
    
    outTexture.write(outColor, gid);
}

チューリングパターン結果
↑u,vを赤と緑に割りあてたもんだから見栄えはさほどよろしくないどころか目に悪そうなので動画はやめて写真だけにしとくわ。

係数を少し変えるだけでいろんな模様になっていくのは面白いね。


コタツの足を長くしたい(3)

コタツの足を長くしたい(2)
↑この続きね。次は塗装。できれば元々のコタツの色に近いのがいい。
塗装の方法にもいろいろあるみたいで迷ったんだけど、結局ブライワックスのダークオークをアマゾンで買ってみたんだ。


↑これ。塗って乾燥させて拭き取ったらいいらしく、それなら俺でもできそうってな感じで購入。

ベランダで塗装
↑臭いがすごいらしいからさすがに部屋ではやらずにベランダに新聞紙を広げてそこでやったよ。

手袋とスチールウール
↑手袋とスチールウールは近所のホームセンターで購入。


気温がさほど高くなかったのでブライワックスは液状にはなってなかったけど塗りやすかったな。
拭き取るのにえらい苦労したので、今度からは塗って乾燥させたらOKみたいなのがいいな、とか思ってしまったよ。

ブライワックス塗装後
↑まあ足の部分はこんな感じに。正直、、、すごくイイ!
ただ足の部分(ホワイトウッド)はともかく幕板部分(SPF材)は全体的に白っぽくなってしまったんだよな。原因はよくわからないけど。
今回は急いで作ったので出来なかったけど、余裕があるならちゃんと端材でテストするべきなんだろうな。

天板滑り止めのゴム
↑天板と接する足のてっぺん部分に滑り止めのゴムシート(厚さ1mm)を釘で固定してみた(シールっぽいのだと簡単にめくれてしまったので)。

コタツ完成品
↑中央部分もスリムビスで固定して右側だけなんだけどコタツのコード置き場をベニア板で作って完成。
ちなみにコタツのヒータ上部には元々断熱のための板があったんだけど、ホームセンターでそれっぽいモノが見つからなかったので、使っていたコタツを分解してそれを流用してる。

高足コタツ完成
↑今回新たに買ってきた椅子と一緒だとこんな感じに。家族にも概ね好評だけど、、、なんかテレビが低くね?みたいなことになり、今度はテレビ台を作ろうかという流れに。次はテレビ台なのか〜?


コタツの足を長くしたい(2)

コタツの足を長くしたい
↑これの続きね。買ってきた木材をいよいよ組み立てるわけなんだけど、、、
いきなりドリルの径を間違えて穴あけたりトラブル続きで途中の写真撮ってる余裕なかったよ。

組み立て後
↑まだヒーター部分あたりは途中だけど一応机の形になったところ。

天板を乗せた状態
↑元々使ってたコタツの天板を乗せた状態。

天板側基準でビス止めしていったので、完成後に天板ががたつくことはなかった(まあまぐれだけど)。足の長さが違うので多少がたつくことは想定してたんだけど、予想外にがたつかない。床がフローリングじゃないことが幸いしたな。フローリングだときっちり足の長さを調整しないとダメだったろうけど、とりあえず大丈夫っぽい(ホントまぐれだけど)。


コタツの足を長くしたい

日曜大工の第二弾ってことでちょっと高いコタツっぽいものを作ろうとしてるんだけど、、、かなり難航してる。

コタツ検討図
↑作りたいのはこんなの。今使ってるコタツの足を長くしたいってだけなんだ。足を継ぎ足すなんてできないので天板以外を自作することにしたのよ。
4本の足周辺の固定方法はいろいろあるみたいだけど、のこぎりを使いたくないので上のように決めたんだわ。

木材調達しにいつもの近所のホームセンターへ。
今回は注意深く選びに選んだよ!片っ端から木材を手に取ってなるべくキレイかつ曲がったりねじれたりしてないのを探したのよ。前回はそういうのを知らずに買った木材が妙にねじれていて組み立て時に泣きを見たからね。

1x4材、2x4材を切ってもらったまではよかったんだけど、、、最後の足(75x75mm)を切ってもらおうとしたら、ホームセンターにある機械では切られないとのこと。よく見れば機械に最大40mmまで、とか書いてる。
そんなわけで仕方なく、ホームセンター内にある工作室、およびのこぎりを借りて切ることに(無料)。電動ののこぎりも有料だけど借りられるみたいなんだけど、使ったことないし、おっかないのでここは普通ののこぎりでいくことに。

ホームセンターの工作室
↑お借りした工作室はこんな感じ。
ホワイトウッドとはいえ75mm角の木材をのこぎりで切るって、、、めっちゃ疲れるのよ。
おまけに、のこぎりでまっすぐ切るなんて難しいのはわかってたんだけど、、、ホント斜めになっちゃうんだよね。
足は4本なので4回切る必要があったんだけど、3回目の半分くらいで様子を伺いにやってきたホームセンターの店員さんが今時間あるからって言って代わりにのこぎりで作業してくれたんだ。握力もなくなってきて疲れてたからもうすっごいありがたかった〜
予想はしてたけど、切り口は結構斜めになってる。店員さんはサンドペーパーでこすればOK、と言ってたけど、、、

今回購入した木材
↑今回購入した木材。
いざサンドペーパーでやってみると、大変な作業だわ。まっすぐにも平らにもならないし。あー、先が思いやられる。


  TopPage  



Copyright ©頭と尻尾はくれてやる!. Powered by FC2 Blog. Template by eriraha.