arusu0629のブログ

UnityエンジニアからiOSエンジニアへ

WebGLについて⑪

【前回】 arusu0629.hatenablog.com

ポリゴンのレンダリング

■初期化処理

    // canvasを初期化する際の深度を設定する
    gl.clearDepth(1.0);

    // canvasを初期化
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
  • clearDepth
    →3次元空間を扱う場合に奥行きに関する情報をクリアするために使われるメソッド。clearメソッドに震度に関してクリアするために組み込み定数のgl.DEPTH_BUFFER_BITを使う



■シェーダとプログラムオブジェクトの生成

    // 頂点シェーダとフラグメントシェーダを生成
    var v_shader = create_shader('vs');
    var f_shader = create_shader('fs');

    // プログラムオブジェクトの生成とリンク
    var prg = create_program(v_shader, f_shader);

    // attributeLocationの取得
    var attLocation = gl.getAttribLocation(prg, 'position');

    // attributeの要素数(この場合はxyzの3要素)
    var attStride = 3;
  • attLocationattStride
    →頂点シェーダにデータを渡す際に必要となる情報を保持するのに使用する

attLocation: そのデータが何番目のデータなのかを保持するために使う

attStride: データがいくつの要素からなるのかを保持するために使う


■頂点バッファの生成と通知

    // モデル(頂点)データ
    var vertex_position = [
        0.0,  1.0, 0.0,
        1.0,  0.0, 0.0,
       -1.0,  0.0, 0.0
    ];

    // VBOの生成
    var vbo = create_vbo(vertex_position);

    // VBOをバインド
    gl.bindBuffer(gl.ARRAY_BUFFER, vbo);

    // attribute属性を有効にする
    gl.enableVertexAttribArray(attLocation);

    // attribute属性を登録
    gl.vertexAttribPointer(attLocation, attStride, gl.FLOAT, false, 0, 0);
  • gl.enableVertexAttribArray
    →目的の属性を有効にすることが出来る
  • gl.vertexAttribPointer
    →シェーダにデータを登録する
    第1引数 :何番目のであるかのインデックス
    第2引数 :データの要素数
    第3引数 :データの型
    第4~6引数:基本的にはこの形で、メモリ上の参照を駆使して特殊なデータの受け渡し方をしたい場合に使用することがある

    ※このメソッドを実行する際に対象のVBOを必ずバインドする必要がある


    ■座標変換行列の生成と通知
    // minMatrix.jsを用いた行列関連処理
    // matIVオブジェクトを生成
    var m = new matIV();

    // 各種行列の生成と初期化
    var mMatrix = m.identity(m.create());
    var vMatrix = m.identity(m.create());
    var pMatrix = m.identity(m.create());
    var mvpMatrix = m.identity(m.create());

    // ビュー座標変換行列
    m.lookAt([0.0, 1.0, 3.0], [0, 0, 0], [0, 1, 0], vMatrix);

    // プロジェクション座標変換行列
    m.perspective(90, c.width / c.height, 0.1, 100, pMatrix);

    // 各行列を掛け合わせ座標変換行列を完成させる
    m.multiply(pMatrix, vMatrix, mvpMatrix);
    m.multiply(mvpMatrix, mMatrix, mvpMatrix);

    // uniformLocationの取得
    var uniLocation = gl.getUniformLocation(prg, 'mvpMatrix');

    // uniformLocationへの座標変換行列を登録
    gl.uniformMatrix4fv(uniLocation, false, mvpMatrix);
  • gl.getUniformLocation
    →attribute変数同様にuniform変数のインデックスを取得するために使用される

  • gl.uniformMatrix4fv
    →uniform変数のインデックスにデータを登録して頂点シェーダにデータが正しく受け渡せるようにする。第2引数のブール値は行列を転置するかどうかの値(※trueにするとクラッシュする場合がある)



■モデルの描画とコンテキストの再描画

    // モデルの描画
    gl.drawArrays(gl.TRIANGLES, 0, 3);

    // コンテキストの再描画
    gl.flush();
  • gl.drawArrays
    →モデルをバッファ上に描画する
    ※このメソッド実行時にはまだ画面上にはポリゴンは描画されておらず下記で説明するflushが実行されることでレンダリング結果が画面上に描画される

    第1引数:頂点をどのように利用して描画するかの組み込み定数
    第2引数:何番目の頂点から利用するかのオフセット値
    第3引数:いくつの頂点を描画するかの値

  • flush
    →コンテキストの再描画



■全ソースコード
■実行結果f:id:arusu0629:20180401192012p:plain