coding, photo, plant and demo

*TokyoDemoFest GLSL Compo #2 TDF7 解説

demo tech 20170309 013818
久々にTokyoDemoFestに参加することができました。2014年以来です。
で、久々に徹夜でGLSLを書いた作品でGLSL Compo 2位を獲得!嬉しいですね。

GLSLで1位を取った@soma_arcさん、3位の@gam0022さんが解説をされていて勉強になったので、自分も簡単ですが技術的なこととか、どう作ったかを書いてみます。

TokyoDemoFest 2017 の GLSL Graphics Compo で3位入賞!
http://gam0022.net/blog/2017/02/24/tdf2017

Tokyo Demo Fest 2017に参加しました
http://soma.hatenablog.jp/entry/2017/02/26/002456

作品について

glslsandbox.com用のglslで、minifyして4KB弱です。
次々とメタリックな謎の物体が変形して、最後に(やや強引に)TDFという文字になり終わりです。

こんな雰囲気です。


TDF7
http://glslsandbox.com/e#38653.0

TDF7 seek bar付き
http://glslsandbox.com/e#39010.0
マウスカーソルのX座標でシークします。左端が始まりで、右端で終わりです。

技術的なこと

ジオメトリ

全編、raymarch + distance field with foldingで作っています。

種となるdistance fieldはTDFという文字のみです。これはお馴染みiq神の
modeling with distance functions
http://iquilezles.org/www/articles/distfunctions/distfunctions.htm
をみながら作りました。



ベースとなるraymarchのコードはglslsandboxで目に付いたシンプルそうなのを採用しました。

それをどう複雑に見せるかですが、foldingを使いました。参考になったのが下記のshader toyのfold関数です。そう、4次元空間でfoldingしているのです。x,y軸を正に畳んで、さらにnc,ndという4次元の法線に従ってさらに畳み込みます。これを一定回数繰り返します。

Polychora (4D)
https://www.shadertoy.com/view/MdsGDH

vec4 fold(vec4 pos) {
	for(int i=0;i<Type*(Type-2);i++){
		pos.xy=abs(pos.xy);
		float t=-2.*min(0.,dot(pos,nc)); pos+=t*nc;
		t=-2.*min(0.,dot(pos,nd)); pos+=t*nd;
	}
	return pos;
}

これで味気ないTDFの文字が、一気に深みのあるジオメトリになります。ウェイパー並みにすごいですね。このデモはほぼ、ここでいうnc,ndをどう変えるかだけで成り立っています。


テクスチャ

視覚的なインパクトを上げるには色使いを派手にするのが一番です。

たまたま当時glslsandboxを開いたら見つけた
http://glslsandbox.com/e#38559.0

をベースにキツい感じになるように調整をしました。

さらに、この関数への入力をdistance functionを変形したものとしました。これで変形に応じて色合いが変わるようになります。

ライティング

光源の位置は当初動かしていたのですが、影の計算が重く手元のGTX980でも60fpsが出なくなってきたので、諦めて光源はカメラの位置としました。これなら影を出さなくてもそれほど不自然ではありません。

視線と法線からディフューズとスペキュラの係数を計算します。スペキュラは強めで硬質な感じを出します。さらに、ディフューズとスペキュラでテクスチャ生成のシードを変えました。シードは位置やディフューズやスペキュラの係数です。もはや物理的には解釈できない味付けですが、これでより複雑な色合いになりました。

正確にはライティングではないですが、raymarchで交点が見つからなかったピクセルには、せっかく計算したのに黒を塗るだけでは忍びないので、raymarch中の最小の距離から適当な色を出して雰囲気を醸してます。

シーケンス

先に述べたように95%はnc,ndをどうするか、です。nc,ndを生成するvec4のパラメータを時間ごとに線形補間でかなり適当に繋げました。あとは最後のTDFの文字でキマった場所に来るように、微調整のパラメータを別途用意しました。

カメラ

ほぼぐるぐる回っているだけで、工夫はありません。

どう作ったか

構想

時間はなかったのですが、コンセプトだけは決めていました。
TDFという文字を最初ぐちゃぐちゃにして出して、?と思わせておいて、最後にTDFと出そう、です。

はい、以前2014年で7行GLSLで優勝した時と同じネタですw
http://glslsandbox.com/e#15404.0

まあね、これは楽なんですよ。まず、最後の落ちが決まっている。で、めちゃくちゃにするのはそんなに難しくないんです。

ただ、前回は2Dだったので今回は3Dでやろう、と。

事前調査

なかなか時間が取れないので、通勤時間にスマホでフラクタル系のblogとかを結構読みました。が、どれを読んだかちょっと思い出せないですが、
http://blog.hvidtfeldts.net/index.php/2011/06/distance-estimated-3d-fractals-part-i
あたりですかね。

あとはFragmentarium関係のblogとかbbsをみて、へえーと思ってました。

Fragmentarium, free fractal worlds explorer, reaches v1.0
http://libregraphicsworld.org/blog/entry/fragmentarium-free-fractal-worlds-explorer-reaches-1-0

へえーと思ってただけで、どのネタを使おうとかまでは気が回ってませんでした。面白半分に見ている感じ。

あとshadertoyとかのよさげなshaderをスマホで読んで勉強していました。これも興味本位ですが。

開発

とかやっていたら、案の定すぐに締め切りが迫ってきました。
もう今晩作るしかねえ、という感じで、TDFの文字をまず作りました。そこから、さて、どうしよう、と試行錯誤するのですが、前述の4次元のfoldingに辿り着くまでに時間がかかりました。

そこからはパラメータ探しで、glslsandboxのmouse.x,yをパラメタに振ってマウスを動かしながら、それに加えソースコードを書き換えながら、良さげな形が出てくるまでひたすら探索。

いけそうな気分になってきたので、テクスチャやライティング周りの作りこみを開始。テクスチャは最初は自力で式を作ってたんですが、どうもいまいちで、前述のglslを見つけてようやく進展したという感じです。

あとは良さげなパラメータをどう繋げてまとめるか、ですが、これが一番キツかったかもしれません。正直、終わりのない改良を繰り返すことになります。mouse.xをtimeに振って、glslsandbox上で順番やタイミングの調整を頑張りました。が、最後はもう明け方、嫁にブチ切れられてギブアップです。

リリース

コードが汚なすぎたので、minifyして提出。

雑感

いろいろまだ粗さが目立ったのと、演出面の作りこみが甘かったです。一番目立つ顔(通称トランスフォーマー。またはTDFで出来た顔なのでTDF Guyとでも呼ぶか)を最後に持ってきて、それがTDFに変形とかでも良かったかな、とか。最後の文字になるまでのつなぎが雑すぎて良くわからん、とか。

日々精進あるのみですね。今年も素晴らしいTDFをありがとうございました。

P.S. 代わりに記念品を受け取っていただきありがとうございました、よっしんさん。