Using shaders to apply color in WebGL

 

前のデモンストレーション で正方形を作り出すことができたら、次に明らかなステップは、それに色をつけることです。これは、シェーダーを変更することで実現できます。

頂点に色を適用する

GL ではオブジェクトは頂点のセットを用いて構築され、各頂点は位置と色の情報を持っています。デフォルトでは、他のピクセルの色 (および位置など、その他の属性すべて) は線形補完法を用いて計算され、自動的になめらかなグラデーションを生成します。前に使用したバーテックスシェーダーでは頂点に色の情報を適用していませんでした。バーテックスシェーダーとフラグメントシェーダーで各ピクセルに白色を固定で割り当てており、正方形全体が白一色で描画されました。

例えば、四隅が異なる色 (赤、青、緑、白) である正方形にグラデーションを作成したいとします。始めに行うことは、4 つの頂点にこれらの色を設定することです。これを行うには、まず頂点の色の配列を作成し、次にその配列を WebGL のバッファに格納します。これらは、以下に挙げるコードを initBuffers() 関数に追加することで実行します:

  var colors = [
    1.0,  1.0,  1.0,  1.0,    // white
    1.0,  0.0,  0.0,  1.0,    // red
    0.0,  1.0,  0.0,  1.0,    // green
    0.0,  0.0,  1.0,  1.0     // blue
  ];
  
  squareVerticesColorBuffer = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, squareVerticesColorBuffer);
  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
}

このコードは 4 つの値が 4 組含まれている JavaScript の配列を作成することから始まります。各組は、それぞれの頂点の色を示します。続いてこれらの色情報を格納する WebGL バッファを新たに割り当てます。そして、配列を WebGL 浮動小数点数に変換してバッファに格納します。

これらの色情報を実際に使うためには、バーテックスシェーダーはカラーバッファから適切な色情報を取り出して更新される必要があります:

    <script id="shader-vs" type="x-shader/x-vertex">
      attribute vec3 aVertexPosition;
      attribute vec4 aVertexColor;
    
      uniform mat4 uMVMatrix;
      uniform mat4 uPMatrix;
      
      varying lowp vec4 vColor;
    
      void main(void) {
        gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
        vColor = aVertexColor;
      }
    </script>

ここでの各頂点に関する重要な違いは、頂点の色情報として配列中で対応する値を設定していることです。

フラグメントの着色

復習として、以前はフラグメントシェーダーを以下のようにしていました:

    <script id="shader-fs" type="x-shader/x-fragment">
      void main(void) {
        gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
      }
    </script>

各ピクセルに補完された色を取り入れさせるため、シェーダーは vColor 変数から値を取り出すように変更する必要があります:

    <script id="shader-fs" type="x-shader/x-fragment">
    	varying lowp vec4 vColor;
    	
      void main(void) {
        gl_FragColor = vColor;
      }
    </script>

これは単純な変更です。これにより各フラグメントは固定値ではなく、頂点からの相対的な位置に基づいて補完された色情報を受け取ります。

色情報を用いた描画

次に、シェーダープログラムの色属性を初期化するコードを initShaders() ルーチンに追加することが必要です:

  vertexColorAttribute = gl.getAttribLocation(shaderProgram, "aVertexColor");
  gl.enableVertexAttribArray(vertexColorAttribute);

そして、実際に色情報を用いて正方形を描画するように drawScene() を変更することが可能になります:

  gl.bindBuffer(gl.ARRAY_BUFFER, squareVerticesColorBuffer);
  gl.vertexAttribPointer(vertexColorAttribute, 4, gl.FLOAT, false, 0, 0);

ここで、WebGL 対応のブラウザで サンプルを見ていただくと、以下のようなものが (黒く塗りつぶされた領域の中央に) 表示されるでしょう:

screenshot.png

ドキュメントのタグと貢献者

最終更新者: ethertank,