前置き
WebGL アドベントカレンダー 12 日です。
以前、錯視の一種であるスリットアニメーションを WebGL とレイマーチングで実装したことがありました。
参考: 3D みたいだけど 2D なんだけどやっぱりよくみたら 3D なんだけどでもやっぱり 2D なんだけどでもよくよく考えてみたらこれって GLSL 使ったレイマーチングなんじゃね? - Qiita
まあ一種のお遊びで実装した感じだったのですが、思いのほかうまく動いてて、自分が一番びっくりでした。
今回も、錯視のネタでなにかできないかなと思ってネタを考えてみたのですが……
いろいろ考えて結局、ゾエトロープを WebGL で実装してみたらどういう結果になるのかなあというのが前々から気になっていたので、試してみました。
まあ時間があんまりなくて、シュッと作った感じで凝ったことはなにもしてません……
そもそもゾエトロープとはなんぞやというのは以下の Wikipedia の記事を参考に。
実装してみた結果は、以下から確認できます。
https://doxas.org/work/zoetrope/
ソースは GitHub から。
doxas/advent2018: advent calendar 2018 demo
仕組み
なんというか見たまんまなのですが、シリンダーのジオメトリを作ってそこに少しずつ様子の違う絵を貼り付けてやって、高速に回転させてやります。
このアニメーションの元となる絵は、なんか手でドットとか打ってもよかったのですがシェーダで書いちゃうほうが簡単そうだったので GLSL でアニメーション書いちゃいました。
時間の経過によってそのままアニメーションするシェーダは以下から確認できます。
これを、4 x 4 のブロックに区切って合計 16 回、ひとつのフレームバッファに焼きます。
実際には、コードのほうでは 8 x 8 とかもっと細かいテーブルにすることもできるのですが、細かすぎてもなんかあんまり結果は変わらん気がしたので、4 x 4 の 16 フレームでアニメーションが一周するようにしてあります。
こんなかんじで。
それを、シリンダーの各面にぺったんこしてぐるぐるします。
高速化するとブレブレになっちゃう問題
実装する前からなんとなく想像はしていたのですが……
時間の経過に応じて回転するようにしていると浮動小数点の微妙な精度の問題というかブレとかもあるし、たぶんうまくいかないのではないかなと思ってました。案の定、速度を上げていくと徐々にブレが大きくなっちゃいますね……
毎フレーム、どれくらい回転するのかを定数化してきっちり決めてしまえばたぶんブレは少なくできると思うのですが、なんとなくそれはやらずに、ブレブレな感じそのままにしてあります。
画面右側のスライダーを使うと回転速度を任意に変更できますので、気になる方はぐりぐりしてみてください。
こういうの実際に作ってみるとわかるのですが、やっぱり現実世界は素晴らしくよくできてますよね……
いつか私も現実になりたいです……