attributeの既定値
閉店ガラガラ

シャッター商店街、さみしいですね...まあショッピングモール便利ですからね。それはさておき、前回やったようにdisableVertexAttribArrayを使ってシャッターを閉めることも場合によっては大事です。その場合はシャッターに書かれた数を使うことになります。これを既定値と言います。既定値は元から決まっていますが、実は関数により変更できます。それについて学びましょう。
コード全文
既定値(カレント)
普通の描画をしています。位置を指定して、色を指定します。スロットの有効化は、0だけ有効化し、1についてはオプションで使うかどうかを決めています。disableをチェックすると1だけ有効化されず、真っ黒になります。

カラーパレットがあると思いますが、これを使って色をいじることができます。いろんな色にしてみてください。ところでどういう仕組みなのでしょうか。それを決めているのが次のコードです。
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のままですね...そうなるとこの、赤と黒の三角形しか描けないわけです。

とはいえ、足りない分を既定値で補うのはレアケースですから、あんま気にする必要は無いですね。
今回はこんなところで。次はいろんなアトリビュートで遊びます。整数と行列が出てきます。行列が不安な人は2-5で復習しておくことをお勧めします。基礎編もいよいよ終わりが見えてきました。
今回登場した関数
vertexAttrib[1234]f[v]
- リンク:vertexAttrib
- 概要:指定したvertexAttributeArrayのスロットに対する、アトリビュートの型がfloat,vec2,vec3,vec4の場合の既定値を数に応じて小さい方から順に設定する。当然だが、これら以外の型のアトリビュートに対しては効果が無いので注意。
- 構文:
gl.vertexAttrib1f(index, v0) gl.vertexAttrib2f(index, v0, v1) gl.vertexAttrib3f(index, v0, v1, v2) gl.vertexAttrib4f(index, v0, v1, v2, v3) gl.vertexAttrib1fv(index, value) gl.vertexAttrib2fv(index, value) gl.vertexAttrib3fv(index, value) gl.vertexAttrib4fv(index, value)
- 引数:
- index: スロットの番号
- v0,v1,v2,v3: Float32の値
- value: Float32ArrayもしくはFloat32で扱うことが前提の数値からなる配列。関数名の数字に応じた長さでないと失敗する
- 返り値:なし
- 補足:レファレンスにもあるように、行列のアトリビュートの場合は行ごとに指定します。次でやると思います。「行ごと」です。このパートは読むと混乱するので読まない方がいいです。ただスロットを連番で予約するところだけは参考になるので、頭にとどめておいてください。
getVertexAttrib
- リンク:getVertexAttrib
- 概要:vertexAttributeArrayの指定したスロットの各種の情報を取得する
- 構文:
console.log(gl.getVertexAttrib(index, pname));
- 引数:indexとpnameに分けてください
- index: スロットのインデックス
- pname: 欲しい情報の種類(詳細は後述)
- 返り値:pnameによる
- 補足:
- デフォルトの値はそれぞれ次の通り:
- buffer: null
- enabled: false
- size: 4
- stride: 0
- type: gl.FLOAT
- normalized: false
- current: Float32Array([0,0,0,1])
- integer: false
- divisor: 0
- オフセットは無いのかと疑問に思うかもしれない。実は存在するのだが、今回取り上げる機会が無かったので、VAOの記事まで待っててね。当然だがデフォルト値は0である。
- デフォルトの値はそれぞれ次の通り:
-
pnameごとの取得できる情報について。
- gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: 該当するスロットにセットされたWebGLBufferを返す。何もない場合はnullが返される。
- gl.VERTEX_ATTRIB_ARRAY_ENABLED: 該当するスロットが有効になってるかどうかをtrue/falseで返す。
- gl.VERTEX_ATTRIB_ARRAY_SIZE: 該当するスロットのサイズを返す。プログラムはもちろん関係なく、あくまでポインターで指定したsizeの値である。
- gl.VERTEX_ATTRIB_ARRAY_STRIDE: 該当するスロットのstride値を返す。
- gl.VERTEX_ATTRIB_ARRAY_TYPE: 該当するスロットのtypeをgl定数の形で返す。
- gl.VERTEX_ATTRIB_ARRAY_NORMALIZED: 該当するスロットのnormalizedの値をtrue/falseで返す。
- gl.CURRENT_VERTEX_ATTRIB: 該当するスロットの既定値を型付配列の形で返す。
- gl.VERTEX_ATTRIB_ARRAY_INTEGER: 該当するスロットに相当するアトリビュートが整数型で供給されているかどうかをtrue/falseで返す。詳しくは次回説明する。
- gl.VERTEX_ATTRIB_ARRAY_DIVISOR: 該当するスロットの除数(divisor)の値を返す。インスタンシングで使う。