attributeの既定値

閉店ガラガラ

 シャッター商店街、さみしいですね...まあショッピングモール便利ですからね。それはさておき、前回やったようにdisableVertexAttribArrayを使ってシャッターを閉めることも場合によっては大事です。その場合はシャッターに書かれた数を使うことになります。これを既定値と言います。既定値は元から決まっていますが、実は関数により変更できます。それについて学びましょう。

コード全文

作品25のリンク

既定値(カレント)

 普通の描画をしています。位置を指定して、色を指定します。スロットの有効化は、0だけ有効化し、1についてはオプションで使うかどうかを決めています。disableをチェックすると1だけ有効化されず、真っ黒になります。

black

 カラーパレットがあると思いますが、これを使って色をいじることができます。いろんな色にしてみてください。ところでどういう仕組みなのでしょうか。それを決めているのが次のコードです。

    gl.vertexAttrib3f(1, config.color.r, config.color.g, config.color.b);
    // これでもいい
    // gl.vertexAttrib3fv(1, [config.color.r, config.color.g, config.color.b]);

 vertexAttribには1234のfとfvがあるんですが、実は内容的には一緒です。例によってスロットはglslで記述されているアトリビュート変数の「型」を知らないので、小さい方からいくつかの値を指定するだけです。場合によっては全部を指定する必要が無いので、1から4まで用意されています。型は内部で用いられるのでFloat32で固定で、仕様にもFloat32Arrayを使え、とあるんですが、行列の時と同じで、どうやら内部で勝手にFoat32化されるっぽいんで、通常配列で問題ないです。で、挙動ですが、ここにもあるように、fで列挙してもfvで配列指定しても一緒です。まあ許される表記法はなんぼあってもいいですからね。

 それで、これが何を決めているかというと、スロットが使えない場合の値です。もともとの既定値は、それを取得する方法があるんですが、まんまgetVertexAttribといいます。これはスロットに関する設定状況を取得するためのもので、いろいろ取得できます。詳しくは関数紹介で述べるのでここでは割愛します。さしあたり、既定値(カレント)を取得するにはこうします:

console.log(gl.getVertexAttrib(1, gl.CURRENT_VERTEX_ATTRIB));

 デフォルトで実行すると0,0,0,1の入ったFloat32Arrayが出力されます。4-2で三角形が動いたのはこういうことだったんですね。既定値では第4成分は1なのです。

Float32Array(4) [0, 0, 0, 1, buffer: ArrayBuffer(16), byteLength: 16, byteOffset: 0, length: 4, Symbol(Symbol.toStringTag): 'Float32Array']

 変更すると小さい方から関数名の数字の分だけ更新されます。とりあえず基本的な挙動はこんなところです。

 getVertexAttribはスロットの様々な状態を取得できます。この先VAOのところで解析に大活躍します。あそこの記事も重いので、心してかかってください...VAOは便利なのです。

不足した場合の既定値

vertexAttribPointerのところにこんな記述があります。

同様に、例えばバーテックスシェーダーが 4 要素属性の vec4 を予期しているのに gl.vertexAttribPointer() 呼び出しで size を 2 にセットした場合、WebGL は最初の 2 つの要素は配列バッファーを基にセットして、3 番目と 4 番目の値は既定値から取られます。

 ということなので、確かめてみました。色のところで、vertexAttribPointerは今回、描画時に使用しています。ここですね:

    // あえて不足させる実験
    gl.bindBuffer(gl.ARRAY_BUFFER, cBuf);
    if(config.notEnough){
      // 1つ目だけ取られる。
      gl.vertexAttribPointer(1, 1, gl.UNSIGNED_BYTE, true, 3, 0);
    }else{
      gl.vertexAttribPointer(1, 3, gl.UNSIGNED_BYTE, true, 0, 0);
    }
    gl.bindBuffer(gl.ARRAY_BUFFER, null);

 notEnoughのオプションを付けると、フェッチは1つだけになり、rgbのうちのrだけがvec3 aColorに放り込まれます。gとbは何も提供されません。ところでstrideを3にしていますが、こうしないと連続でフェッチされてしまうのでおおまたぎにしないといけないわけです...分かんなかった人は4-1で復習してください。復習はなんぼやってもいいですからね。
 それで、上記のレファレンスに依ればgとbは既定値から取られるはずなんですが...実際はどんなに頑張っても、gとbは0のままですね...そうなるとこの、赤と黒の三角形しか描けないわけです。

red black

 とはいえ、足りない分を既定値で補うのはレアケースですから、あんま気にする必要は無いですね。

 今回はこんなところで。次はいろんなアトリビュートで遊びます。整数と行列が出てきます。行列が不安な人は2-5で復習しておくことをお勧めします。基礎編もいよいよ終わりが見えてきました。

今回登場した関数

vertexAttrib[1234]f[v]
getVertexAttrib