Webgl-translation

提供:Dev Guides
移動先:案内検索

WebGL-翻訳

これまで、WebGLを使用してさまざまな形状を描画し、色を適用する方法について説明しました。 ここで、この章では、三角形の変換方法を示す例を取り上げます。

翻訳

翻訳は、WebGLが提供する*アフィン変換*の1つです。 平行移動を使用して、xyz平面上の三角形(任意のオブジェクト)を移動できます。 三角形[a、b、c]があり、正のX軸に向かって5単位、正のY軸に向かって3単位の位置に三角形を移動するとします。 その場合、新しい頂点は[a + 5、b + 3、c + 0]になります。 つまり、三角形を平行移動するには、各頂点に平行移動距離、たとえばtx、ty、tzを追加する必要があります。

これは*頂点ごとの操作*なので、頂点シェーダープログラムで実行できます。

頂点シェーダーでは、属性 coordinates (頂点の位置を保持する)とともに、平行移動距離(x、y、z)を保持する均一変数を定義します。 後で、この均一変数を座標変数に追加し、結果を gl_Position 変数に割り当てます。

注意-頂点シェーダーは各頂点で実行されるため、三角形のすべての頂点が変換されます。

三角形を翻訳する手順

WebGLアプリケーションを作成して三角形を描画し、それを新しい位置に変換するには、次の手順が必要です。

ステップ1-キャンバスを準備し、WebGLレンダリングコンテキストを取得

このステップでは、* getContext()*を使用してWebGLレンダリングコンテキストオブジェクトを取得します。

ステップ2-ジオメトリを定義し、バッファオブジェクトに格納します

三角形を描画しているため、三角形の3つの頂点を渡して、バッファーに保存する必要があります。

var vertices = [ -0.5,0.5,0.0, -0.5,-0.5,0.0, 0.5,-0.5,0.0, ];

ステップ3-シェーダープログラムの作成とコンパイル

この手順では、頂点シェーダーおよびフラグメントシェーダープログラムを記述し、それらをコンパイルし、これらの2つのプログラムをリンクして結合プログラムを作成する必要があります。

  • 頂点シェーダー-プログラムの頂点シェーダーで、3D座標を格納するためのベクター属性を定義します。 それと共に、平行移動距離を格納するための均一変数を定義し、最後にこれらの2つの値を追加して、頂点の最終位置を保持する gl_position に割り当てます。
var vertCode =
   'attribute vec4 coordinates;' +
   'uniform vec4 translation;'+
   'void main(void) {' +
      ' gl_Position = coordinates + translation;' +
   '}';
  • フラグメントシェーダー-フラグメントシェーダーでは、フラグメントカラーを変数gl_FragColorに単純に割り当てます。
var fragCode = 'void main(void) {' +' gl_FragColor = vec4(1, 0.5, 0.0, 1);' +'}';

ステップ4-シェーダープログラムをバッファオブジェクトに関連付ける

この手順では、バッファーオブジェクトをシェーダープログラムに関連付けます。

ステップ5-必要なオブジェクトの描画

インデックスを使用して三角形を描画しているため、メソッド* drawArrays()*を使用します。 このメソッドには、考慮される頂点/要素の数を渡す必要があります。 三角形を描画しているため、3をパラメーターとして渡します。

gl.drawArrays(gl.TRIANGLES, 0, 3);

例–三角形の翻訳

次の例は、xyz平面上の三角形を変換する方法を示しています。

<!doctype html>
<html>
   <body>
      <canvas width = "300" height = "300" id = "my_Canvas"></canvas>

      <script>
        /*=================Creating a canvas=========================*/
         var canvas = document.getElementById('my_Canvas');
         gl = canvas.getContext('experimental-webgl');

        /*===========Defining and storing the geometry==============*/
         var vertices = [
            -0.5,0.5,0.0,
            -0.5,-0.5,0.0,
            0.5,-0.5,0.0,
         ];

        //Create an empty buffer object and store vertex data
         var vertex_buffer = gl.createBuffer();

        //Create a new buffer
         gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);

        //bind it to the current buffer
         gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);

        //Pass the buffer data
         gl.bindBuffer(gl.ARRAY_BUFFER, null);

        /*========================Shaders============================*/

        //vertex shader source code
         var vertCode =
            'attribute vec4 coordinates;' +
            'uniform vec4 translation;'+
            'void main(void) {' +
               '  gl_Position = coordinates + translation;' +
            '}';

        //Create a vertex shader program object and compile it
         var vertShader = gl.createShader(gl.VERTEX_SHADER);
         gl.shaderSource(vertShader, vertCode);
         gl.compileShader(vertShader);


        //fragment shader source code
         var fragCode =
            'void main(void) {' +
               '   gl_FragColor = vec4(0.0, 0.0, 0.0, 0.1);' +
            '}';

        //Create a fragment shader program object and compile it
         var fragShader = gl.createShader(gl.FRAGMENT_SHADER);
         gl.shaderSource(fragShader, fragCode);
         gl.compileShader(fragShader);

        //Create and use combiened shader program
         var shaderProgram = gl.createProgram();
         gl.attachShader(shaderProgram, vertShader);
         gl.attachShader(shaderProgram, fragShader);
         gl.linkProgram(shaderProgram);

         gl.useProgram(shaderProgram);

        /* ===========Associating shaders to buffer objects============*/

         gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
         var coordinatesVar = gl.getAttribLocation(shaderProgram, "coordinates");
         gl.vertexAttribPointer(coordinatesVar, 3, gl.FLOAT, false, 0, 0);
         gl.enableVertexAttribArray(coordinatesVar);

        /* ==========translation======================================*/
         var Tx = 0.5, Ty = 0.5, Tz = 0.0;
         var translation = gl.getUniformLocation(shaderProgram, 'translation');
         gl.uniform4f(translation, Tx, Ty, Tz, 0.0);

        /*=================Drawing the riangle and transforming it========================*/

         gl.clearColor(0.5, 0.5, 0.5, 0.9);
         gl.enable(gl.DEPTH_TEST);

         gl.clear(gl.COLOR_BUFFER_BIT);
         gl.viewport(0,0,canvas.width,canvas.height);
         gl.drawArrays(gl.TRIANGLES, 0, 3);
      </script>
    </body>
 </html>

この例を実行すると、次の出力が生成されます-