シンプルなグリッチ表現を使ったクリエイティブコーディングをしてみた。
ふと思ったのですが、実験的にクリエイティブコーディングをした際に、人に見せられるレベルまで落とし込んでgithubにアップした方が自分の資産や実績にもなるし、なんとなくでもいいので解説をnoteで書いたら備忘録にもなるかなと思ったので、今後はできるだけそうしてみようと思います。
というわけで、以前Twitterなど各種SNSで投稿していましたが、簡易的なグリッチを使ったコンテンツを作ったので、githubにアップしました。(jsは相変わらずCoffeeScriptで書いています。あしからず。。)
githubページも作ったので、実際にブラウザで見ることもできます。ただし、スマホに最適化はしてません。コンテンツはthree.jsを使用しています。
githubページ、実は初めて使った。。
グリッチを使ったコンテンツを3種類作ったのですが、それぞれブランチを切っております。
コンテンツはgulpでビルドできるようになっています。(gulpの使い方は割愛。見たい場合は、ReadMeにあるリンクからたどってください。)
simple glitch transition (plane branch)
これは板ポリ上で2種類のロゴマークがグリッチを起こしながら切り替わるというものです。数秒ごとに自動で切り替わりますが、マウスオーバーでも切り替えることができます。
simple glitch cube (cube branch)
これはキューブの各面にさっきのやつを配置しました。白黒が味気なかったので、色もつけてみました。今度はマウスオーバーで2種類のインタラクションを実装しました。
1つ目は横に伸びる。2つ目は画像がタイル状に並びます。これはvertexShaderからfragmentShaderにUV座標を渡すときに、値をいじって渡しています。
具体的には
// vUvはvaryingで定義 uvはattributeの値
vUv = uv;
// animationValue2はマウスオーバー時に値を0→1→0に変化させている
vUv *= (1.0 + 1.0 * animationValue2);
として、UVの値が0 ~ 2になるようにしています。UVが1以上のときにテクスチャをリピートするには、
// texture: ロゴのテクスチャ
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
を設定する必要があります。
glitch cubes march (master branch)
最後はキューブをたくさん並べて更新させてみました(インタラクションはなし)。THREE.InstanceBufferGeometryを使ってインスタンシングを実現しています。
カメラをTHREE.OrthographicCamera(平行投影カメラ)を使用しているので、3Dでありながらちょっと可愛い見た目になりました。
動きもリズミカルに地面を転がるような動きをvertexShaderで実装しています (詳細は割愛)。
また、カメラも4秒ごとに位置を移動して、色んな角度から見れるようになっています。ただ、リサイズ処理のことをあんまり考えてないので、大きめのブラウザサイズで見ると、途中で切れます。
・・・
肝心のグリッチ部分ですが、処理は大きく分けて3種類です。
1. よく見ると分かる、周期的にy方向に移動している数ピクセルのズレ
2. テクスチャを横方向に短冊状にたくさん分割し、ランダムにx軸方向にずらす (y軸方向もちょっとずらしている)
3. オフスクリーンcanvasにレンダリングしたテクスチャによるのディスプレイスメントマップ的な処理
1はuniformで経過時間をfragmentShaderに渡し、周期的にテクスチャのy方向の数ピクセルの範囲をランダムな値を用いでx方向にちょっとシフトしてます。
2はfragmentShader内でnoise関数を定義して、uv.yをシードにした乱数を発生させ、uv座標をシフトさせています。
3はグリッチが発生している間、0.05秒ごとにオフスクリーンのcanvasに以下のような画像を描画し、それをテクスチャとしてシェーダに渡し、取得した色のrの値をux.xのシフト、 gの値をuv.yのシフトに使用しています。
これによってブロック状のノイズを実現しています。
グリッチってもっといろんな表現方法がありますが、今回は割とシンプル目になってます。こだわったらキリがない気がします。。
・・・
すごい雑な説明になっていまいましたが、これくらいのノリのほうが続けられそうです。
サポートいただければ、レッドブルを飲んでより頑張れると思います。翼を授けてください。