LoginSignup
5
2

More than 3 years have passed since last update.

WebGLで整数頂点バッファーを使う

Last updated at Posted at 2019-05-02

WebGLではWebGLRendering​Context​.vertex​Attrib​Pointer()でバッファーオブジェクトの使用方法を指定します。vertexAttribPointertype引数にはgl.SHORTなど整数のデータ型を指定できますが、シェーダー側では浮動小数点数としてしか受け取れないので、使用する際には以下のようにシェーダー側で型変換する必要があります。

gl.bufferData(gl.ARRAY_BUFFER, new Int16Array([0, 1, 2]), gl.STATIC_DRAW);
...
gl.vertexAttribPointer(0, 1, gl.SHORT, false, 0, 0);
頂点シェーダー
#version 300 es

layout (location = 0) in float i_index;

vec3[3] POSITIONS = vec3[](
  vec3(-0.5, -0.5, 0.0),
  vec3(0.5, -0.5, 0.0),
  vec3(0.0, 0.5, 0.0)
);

void main(void) {
  gl_Position = vec4(POSITIONS[int(i_index)], 1.0);
}

WebGL2からはWebGL2Rendering​Context​.vertex​Attrib​IPointer()を使用すれば以下のようにシェーダー側で整数として受け取れるようになるので、型変換の必要がなくなります。(わかりづらいですがAttribの後にIがあります)

layout (location = 0) in int i_index;

型付き配列の精度に応じてvertexAttribIPointertypeを決定します。例えば、Int16Arrayの場合はgl.SHORTを、Int32Arrayの場合はgl.INTを使用することになります。

gl.bufferData(gl.ARRAY_BUFFER, new Int16Array([0, 1, 2]), gl.STATIC_DRAW);
...
gl.vertexAttribIPointer(0, 1, gl.SHORT, 0, 0);
gl.bufferData(gl.ARRAY_BUFFER, new Int32Array([0, 1, 2]), gl.STATIC_DRAW);
...
gl.vertexAttribIPointer(0, 1, gl.INT, 0, 0);

符号なし整数を使用する場合は16bit、32bitそれぞれ以下のようになります。

gl.bufferData(gl.ARRAY_BUFFER, new Uint16Array([0, 1, 2]), gl.STATIC_DRAW);
...
gl.vertexAttribIPointer(0, 1, gl.UNSIGNED_SHORT, 0, 0);
gl.bufferData(gl.ARRAY_BUFFER, new Uint32Array([0, 1, 2]), gl.STATIC_DRAW);
...
gl.vertexAttribIPointer(0, 1, gl.UNSIGNED_INT, 0, 0);

シェーダー側では次のようにuintで受け取ることができます。

layout (location = 0) in uint i_index;

サンプルのソースコードをgistに置いておきました。
https://gist.github.com/aadebdeb/5f2e70095762e24ab5f132925f67e3cd

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2