はじめに
世界的なデジタル化が進んだ現代社会では、もはやウェブテクノロジーのない生活は想像できないほどです。私たちは仕事や他者とのコミュニケーション、買い物、情報収集、ニュースのチェックなど、膨大な時間をオンラインで過ごすようになっています。それに伴い、企業では顧客や従業員、ビジネスパートナーの交流の場として、物理的な建物に代わってウェブを活用しようという動きが増えています。
デジタルチャネルの重要性が高まるなか、企業はデジタルタッチポイントへの投資を増やし、ユニークで記憶に残るオンライン体験を提供しようとしています。その需要に応えるため、ソフトウェア開発会社は先進的なデジタルツールやテクノロジーを取り入れて、製品やサービスの拡充を進めています。そこでの興味深いトレンドのひとつに、コンピューターグラフィックスの活用があります。とくにウェブサイトで3次元グラフィックスを表示してユーザー体験を向上させる技術として、WebGLに注目が集まり始めています。
JavaScriptのAPIであるWebGL(Web Graphics Library)は、2017年に登場して以来、プログラマーやウェブ開発者にとって便利なツールとなっています。
企業や組織にとって、WebGLには以下のような活用例やメリットがあります。
- 複雑なデータの可視化:データをわかりやすく提示したい政府機関や非営利団体などで役立ちます。
- パンデミック後に重要性が増している、バーチャルショールームや商品ディスプレイへの活用:3次元グラフィックにより、ユーザーは自宅に居ながらにして、自動車から不動産物件まであらゆるものを見学できます。
- オンライン教育・研修に:オンライン教育を取り入れる教育機関が増えるなか、活用の機会が多いと考えられます。
WebGLとは
コンピューターグラフィックス技術のひとつであるWebGL(Web Graphics Library)は、ブラウザ上で2Dや3Dのグラフィックスを高性能に描画するためのJavaScript APIです。追加のプラグインを必要とせず、対応しているブラウザのみでグラフィックスを表現できます。
さまざまなデバイスでブラウザが使用されるようになった現在、WebGLは開発者コミュニティにおいても存在感が増しており、将来的には主要なグラフィックス・プログラミングツールのひとつになると考えられています。
Starでも、さまざまなプロジェクトでWebGLを使用しています。今回の記事では、コンピューターグラフィックスの基礎と、最適化のためのテクニックを紹介します。なお、記事中で紹介するコードは、WebGL上に抽象化レイヤーを提供するThree.jsライブラリを使って書かれています。
基本的な構造
WebGLのプログラムは、「シェーダー」と呼ばれる機能で構成されています。具体的には「頂点シェーダー」と「ピクセルシェーダー(フラグメントシェーダーとも)」が扱われます。
シェーダーの動作原理は、以下のように説明できます。
- ワールド空間におけるオブジェクトの座標が、頂点シェーダーに渡されます。
- 頂点シェーダーが、その座標をスクリーンに投影します。
- 投影されたピクセルが、フラグメントシェーダーに渡されます。
- フラグメントシェーダーが、各ピクセルの色を決定します。
ワールド空間のオブジェクトは、一般に下の図のような「ポリゴン」(三角形の集まり)で構成されます。
頂点シェーダーの例
では、頂点シェーダーの実装例を見ながら、データの受け渡しについて説明していきます。
attribute vec3 position;<br>attribute vec2 uv; <br><br>uniform mat4 projectionMatrix; <br>uniform mat4 modelViewMatrix; <br><br>varying vec2 varUV; <br><br>void main() { <br> varUV = uv; <br> gl_Position = projectionMatrix * modelViewMatrix * position; <br>}
シェーダーで受け渡されるデータには以下の4つがあります。
- 属性(attribute):ポリゴンの各頂点に対して個別に渡されるデータです。最もわかりやすいのは頂点座標ですが、その他にも色やアニメーションのパラメータなど、さまざまなデータが含まれます。
- ユニフォーム(uniform)変数:グローバルなシェーダー変数です。通常は、オブジェクトのすべての頂点に共通するデータ、例えば光源のパラメーターやテクスチャなどが含まれます。
- 可変(varying)変数:頂点シェーダーからフラグメントシェーダーにデータを渡す際に使用される変数です。このデータは、フラグメントシェーダーに渡される際に、WebGLによって補間されます。この処理の詳細は「フラグメントシェーダーの例」の項目を参照してください。
- テクスチャ:シェーダープログラム内でランダムにアクセスできるデータ配列です。一般的には、オブジェクトのジオメトリに適用される画像が含まれます。また、照明、反射、アニメーションなどを適用するためのデータソースとしても機能します。
頂点シェーダーのサンプルコードを見てみましょう。
- positionには、ポリゴンの頂点の座標が入ります。
- uvは、オブジェクトの頂点をテクスチャのピクセルに紐づけるために使われる座標です。
- projectionMatrixは,ワールド空間の座標を、[-1〜1] の範囲のクリップ空間の座標に変換するために使われる射影行列です。ここでは簡単化するために,スクリーン上に投影されるものと仮定します。
- modelViewMatrixは、ワールド空間での座標変換(平行移動、回転、拡大縮小など)に使われる行列です。
- gl_Positionは、WebGLの組み込み変数で、クリップ空間における現在の頂点位置が入ります。
頂点シェーダーのワークフローを図示したのが以下です。
頂点のワールド座標に投影パラメーターを適用した結果が、gl_Position変数に渡されます。
フラグメントシェーダーの例
ここではフラグメントシェーダーの実装例を見ながら、データの受け渡しについて説明します。
uniform sampler2D texture;<br>varying vec2 varUV;<br>void main() {<br> varUV = uv;<br> gl_FragColor = texture2D(texture, varUV);<br>}
コードには、テクスチャーユニフォームと、可変変数var_uvが見られます。これはテクスチャー座標をオブジェクト座標にマッピングするために使われます。
対応する座標のテクスチャから得られた値が、gl_FragColorというWebGLの組み込み変数に渡され、基本的にはピクセルカラーが返されます。
次に、オブジェクトを画素ごとにペイントする過程を見てみましょう。この過程のイメージをつかむことで、頂点シェーダーとフラグメントシェーダーの役割分担について理解が深まり、全体的なパフォーマンスの向上につながるでしょう。
下図はピクセルシェーダーの動作原理です。
頂点シェーダーから渡されたデータをもとに、ポリゴン内のピクセルカラーがスキャンラインに沿って補間されていることがわかります。
各画素でのデータ補間処理は以下のようになります。
- クリップ空間での頂点の座標を計算します。
- ポリゴンの各頂点の色をフラグメントシェーダーに渡します。
- スキャンラインの始点と終点でのピクセルの色を計算します。これは、頂点a〜b間およびa〜c間で値を補間することで求められます。
- 同様の方法で、スキャンラインの始点と終点の間にあるピクセルの色の値を算出します。使用されるのは以下の式です。
(endColor - startColor) * (pixelIndex / lineLength)
StartColor、endColorはラインの始点と終点の色、pixelIndexはライン内のどのピクセルかを示すインデックス、lineLengthはラインの長さを表します。
テクスチャピクセルの座標の計算や、ライティングなど頂点シェーダーからフラグメントシェーダーに渡される他のデータも、同様の手法で計算されます。
上記の方法でモデルにテクスチャとライティングを適用した描画結果がこちらです。
以上のプロセスから考えると、頂点シェーダーでできるだけ多くの計算を行い、その結果をフラグメントシェーダーに渡すことで、ピクセルごとに同じ計算を繰り返す必要がなくなり、その結果、データの補間スピードが上がって、描画のパフォーマンスが向上すると言えます。
まとめ
WebGLは、ブラウザ上でコンピューターグラフィックスを作成するための、柔軟かつ強力なツールです。以下のような分野に応用できます。
- データの可視化(地図、統計データ、医療現場やロボットなどから得られたデータなど)
- 複雑なデザインソリューションの実装
- ゲームの開発
- オンラインのグラフィックエディター
- 画像処理
- インタラクティブなプレゼンテーション
- 仮想現実(VR)/拡張現実(AR)プロジェクトの実装
Starはコンピューターグラフィックスの技術を活用して、お客様のアイデアを世に出すお手伝いをしています。