地球規模での環境課題の解決「バイオエコノミー」を目指すオリシロジェノミクス株式会社のウェブサイト
実装した本人が実装を解説!?
今回ご紹介するのは、バイオテクノロジーの力であらゆる環境問題や課題を解決することを目指す、オリシロジェノミクス株式会社のコーポレートサイトです。
今回のサイトを制作したのは 株式会社スタジオ ディテイルズ のみなさん。
そして実は、WebGL 部分は私が実装しています。
珍しく、自分が作ったということを公言できる事例ということもあって、初めてのことなんですが自分が作った実装を自分のサイトで紹介しようと思います(笑)
せっかく全部を実装したひとが記事を書くことになりますので、今回は 特別編 ということで、その実装の技術的背景などもバッチリ解説しちゃいます。
※スタジオディテイルズさんからは技術解説や制作背景等を書いてもよい旨、許可いただいています。
リンク:
チームとしての到達点の高さが光る
今回のサイトは、背景の WebGL 部分は私が実装したものですが、サイト全体のデザインや、フロントエンド全般の実装は、スタジオディテイルズの関係者の方々の手によるものです。
一緒にお仕事させていただいて感じましたが、とにかく設定している目標地点というか、作り上げようとしているもののレベルの高さが本当に高いところに設定されており、しかも妥協が無いんですよね。それは本当にすごいことだなと思いました。
当記事では WebGL の実装について主に詳しく扱いますが、サイトの制作に関わったみなさんをここで掲載させていただきます。
Creative Director:海部洋
Director:武井遼太郎 / 久保慶護
Art Director:野澤美菜
Desingner:野澤美菜 / 中村彩夏
Lead Frontend-Developer 小見祐介(フリーランス)
Front-end Engineer:辻良平 , 志水 祐紀子 , 三木 亮平
さて、今回のサイトは「1本の線が、核/自然/街/生命/ヒト=社会を創る」という大きなコンセプトに沿ってデザインされています。
WebGL の実装では、このコンセプトを体現すべく、いくつかの技術を組み合わせて演出を行っています。
トップページから各コンテンツページへとそれぞれ導線がありますが、WebGL が背景に使われているのはトップページと、コンテンツページのトップ部分ですね。
WebGL の演出中は、画面の中央に一本のラインが引かれたような形になっており、その上をページごとにモチーフとなっているオブジェクトが移動するようなイメージです。
また、常に背景もこれと連動するようになっていて、花や、街並み、鳥の姿などが描かれます。
画面の中心にあるラインや、線画として描かれるオブジェクトは頂点を連結してラインで描画しています。
サイン波を組み合わせることで有機的に、ランダムに揺れるような動きを再現しているだけでなく、手書き風のジオメトリについては、あえて FPS を抑えてカクカクとした動きにすることで、より手書き感が強く感じられるようにしています。
これらはすべて uniform 変数からシェーダに送られる浮動小数点の値によって調整することができるようになっており、デザイナーさんの意図を極力そのまま表現として画面上に出せるように、また動的にパラメータを変更しやすいように工夫してシェーダが実装されています。
いま調べてみたら、シェーダは7種類使っていました。
静止画では手書き風の質感表現はほとんどわからないですが……実際にサイトに行って、ぜひ動いている様子を見てみてください。
さらに、シーン全体の演出としては、背景をノイズで淡くブルーに着色していたり、水彩絵の具が滲んだような演出を行ったり、結構いろいろな要素を組み合わせた表現になっています。
ざっと概要だけで説明すると……
- 背景のノイズを使ったグラデーション
- 中央を走る長いライン
- ライン上でパルスを発するサークル模様
- 手書き風のラインジオメトリ
- 水彩風のマスク
- マスクを縁取るパーティクル
- マスク部分に描画される塩基配列
などの要素があります。
それぞれがほとんどの場合は異なるシェーダで描かれていて、フレームバッファなども使ってマルチパスでシーンをレンダリングします。
実装の工夫や参考になりそうなテクニック
さて、ここからはもう少し細かく、今回のサイトにおいて使われている演出が、どのような技術的背景で実装されているのか、紹介していきましょう。
なんか上から目線で、しかもちょっと恥ずかしいのがあれですが……
水彩画のようなマスク
各ページで見ることができる水彩のようなマスクは、もともとのリソースは白黒のビットマップで、いわゆるアルファマップと呼ばれるものですね。
今回のケースでは、各シーンごとにアルファマップを動的に切り替えてやる必要がありますが、実際に使っているテクスチャの数は、アルファマップの種類よりも少なくなっています。
これは、アルファマップは情報としては「アルファの情報だけがあればよい」ため、ビットマップを構成する RGBA の各チャンネルのうち、ひとつのチャンネルだけがあれば表現できるためです。
実際にサイトで読み込んでいるテクスチャは、たとえば次の図にあるような感じで、RGB にそれぞれ異なるアルファマップの情報を格納していたり、A(アルファ)のチャンネルにはホワイトノイズが入っていたりと、リソースを節約できるようになっています。
こんなふうに、RGBA の各チャンネルを「ビットマップというより、単に大きな配列のようなもの」として考えられるようになっていると、データを節約したり、動的にテクスチャにデータを焼き込んだりするときに役に立ちます。
プロシージャルなパーティクルの生成
また、今回のサイトでは水彩マスクが画面に表示されるシーンで、そのマスクの輪郭部分を縁取るようにパーティクルが浮遊しています。
これは、どうやって実現しているのか、想像できるでしょうか。
パーティクルが水彩マスクのシルエットの形に!
これを実現する方法は、まあいろいろあるとは思うのですが……
今回のサイトでは、このパーティクルの形状は動的に頂点座標を JavaScript で求めることで生成しています。
仕組みはこうです。
まず、アルファマップを極端に小さな解像度の状態に変換します。今回のケースでは 32x32 の大きさにまで縮小しました。
この状態になると、アルファマップとして使うにはあまりに低解像度すぎますが、この情報を元にパーティクルを生成することになるので……
逆にあまり高解像度すぎると、パーティクルの個数が多くなりすぎてしまいます。今回のサイトの場合は、補助的な演出としてふわふわと控えめに漂っていれば十分だったため、むしろこのくらいの大きさがちょうどよかった感じです。
そして、この上の図にあるように、小さく縮小されたアルファマップを一度 Canvas2D で WebGL 用ではない別の Canvas に焼きます。
そこから ImageData
を引っ張りだしてやれば、アルファマップの濃淡の情報が JavaScript から参照できるようになりますね。
ここで、一気に ImageData
全体を走査し「隣接するピクセルとの差分が一定のしきい値より大きい」という条件で全ピクセルを調査していきます。
もうおわかりかと思いますが、この条件を満たす場合に限り、そこに頂点を生成してやればいいわけですね。
あとは、シーン全体のアングルに合わせて配置し、適切に拡縮してやれば OK です。
パーティクルを描くシェーダ内では、中央に走っている一本のラインと同様に、乱数とサイン波を組み合わせてパーティクルを浮遊させています。
SVG 由来の手書き風ラインジオメトリ
サイト内に現れる、花や街並み、あるいは鳥といった「手書き風のラインジオメトリ」は、スタジオディテイルズさんが用意してくださった SVG のデータが元になっています。
そのままブラウザでプレビューしたのが以下の画像ですが、今回の SVG ラインは一筆書きで全部のラインが繋がっているわけではないので、自力で SVG から頂点情報に加工する Node.js のスクリプトを書いて、頂点情報に変換しました。
この SVG 由来のジオメトリは、頂点属性として乱数を同時に持たせるようにしてあります。
この乱数に由来する情報を利用して、手書き風にカクカクと動くアニメーションをシェーダで実装しています。
たとえば、頂点はひとつあたり attribute として vec4
の全てに乱数が詰まった頂点属性を持っていて、それぞれの要素ごとに異なる乱数が入った状態でシェーダに送られてきます。
これらの乱数の値の大小により、いかに大きく揺らぐか、いかにすばやく揺らぐか、いかなる方向に対して強く揺らぐかなどが、乱数によって決まります。
これにより、いかにも手書き風な、不規則なアニメーションを実現しているわけですね。
背景に描画される塩基配列
水彩模様などをよーく観察すると、そこに遺伝子の塩基配列のような模様が見えているのがわかるかと思います。
この塩基配列の模様は、最初は静止画でやるか~ みたいな話もあったのですが、30 分くらいでなんか使えそうなシェーダが書けたので、それを使いました。
元になっているシェーダはこれですね。ただし、以下のリンクからプレビューできるシェーダは iphone などのスマートフォン用に最適化していないので、閲覧中の環境によっては、以下の画像のようには見えないかもしれません……
このように動的にシェーダで模様を生成することによって、塩基配列が流れていくような、独特なアニメーションを実現しています。
上記でも少し書いたように、スマートフォンなどの一部の環境では、そのままではうまく模様が生成されないことがあります。これはモバイルデバイスの多くが、浮動小数点の精度などで PC と比較して不利というか、やや精度が落ちてしまう場合があるためです。
実際にローンチされている本番用のサイトのほうは、この問題に対応するように作ってあるので、ちゃんと模様が出ていると思いますが…… これをどうやって実現するのかは、アルファマップを解説した部分にヒントがあります。
動的に乱数を求めるのがアウトになる場合があるのなら、動的に求めなければいいのです。そのために、アルファマップの合成した画像のうちの、アルファのチャンネルにホワイトノイズが仕込んであったわけですね(笑)
WebGL が輝くとき
さて、せっかく自分が作ったサイトなのだからということで、いつもよりも多めに、技術解説なども踏まえてお送りしましたが参考になりましたでしょうか。
今回のサイトに限りませんが、ウェブサイトの制作で WebGL を利用する場合には、「WebGL を使って何を実現したいのか」であったり、「なぜ WebGL を使う必要があるのか」がとても大切だと個人的には思います。
今回のケースは、最初にいただいたデザインの原案を拝見した段階で、WebGL を使わないと表現できない部分が多そうだなというのは感じました。それはこの記事で紹介したような、主に動的な表現を行うために、WebGL 以外の選択肢では実現が難しいというのが感じられたためですね。
WebGL は、それを使うことそのものが正解というわけではなくて、やはり WebGL を使うだけの理由や、到達すべきゴールがあってこその技術だと思います。
そういう意味では、やはりサイト制作に関わったたくさんの人達の努力や研鑽のおかげで、WebGL が無事にその役割を果たすことができたのだと、言えると思います。
当記事で紹介した技術など踏まえつつ、サイト全体のフロントエンドの実装や、デザインにもぜひ注目してご覧になってみてください。