如果禁用 VertexAttribArray,WebGL 2.0 整数属性会抛出类型错误
WebGL 2.0 Integer attribute throws type error if VertexAttribArray is disabled
我刚刚花了几个小时来隔离我不理解的 WebGL 行为。
让我们假设一个具有整数属性的顶点着色器:
precision highp int;
in vec4 vtx_pos;
in vec3 vtx_nrm;
in ivec4 vtx_int; // <- integer attribute
void main() {
// blah blah...
}
与以下着色器属性绑定:
var p = gl.createProgram();
gl.bindAttribLocation(p, 0, "vtx_pos");
gl.bindAttribLocation(p, 1, "vtx_nrm");
gl.bindAttribLocation(p, 2, "vtx_int"); // <- ivec4 on array #2
最后是以下AttribPointer配置:
gl.vertexAttribPointer(0, 4, gl.FLOAT, false, 28, 0);
gl.enableVertexAttribArray(0);
gl.vertexAttribPointer(1, 3, gl.FLOAT, false, 28, 16);
gl.enableVertexAttribArray(1);
gl.disableVertexAttribArray(2); // <- here is the devil
使用此配置(禁用 VertexAttribArray(2)),浏览器会抛出属性 2 的类型错误:
Chrome: GL_INVALID_OPERATION : glDrawElements: vertexAttrib function must match shader attrib type
火狐:drawElements: Vertex attrib 2 requires data of type INT, but is being supplied with type FLOAT.
我的理解是,当 VertexAttribArray 未使用正确的 vertexAttribI 指针显式启用时,WebGL 默认认为它是 "supplied as FLOAT",因此,抛出类型错误。
我不明白的是:为什么它检查提供的 disabled VertexAttribArray 类型,逻辑上,提供 nothing ?
除了将 VertexAttribArray 启用为虚拟对象之外,是否有一些魔法可以避免此错误?
引用 GL ES 3.0 §2.8:
The resulting attribute values are undefined if the base type of the shader attribute at slot index is not floating-point (e.g. is signed or unsigned integer).
WebGL 2.0 eliminates undefined behaviour here and mandates that an error should be produced.
所以,默认情况下非数组属性的值确实是一个浮点向量。如果着色器中的实际属性是无符号整数值的整数,则应通过 vertexAttribI4*
family 的调用手动指定其值,即:
gl.vertexAttribI4i(2, 0, 0, 0, 0);
我刚刚花了几个小时来隔离我不理解的 WebGL 行为。
让我们假设一个具有整数属性的顶点着色器:
precision highp int;
in vec4 vtx_pos;
in vec3 vtx_nrm;
in ivec4 vtx_int; // <- integer attribute
void main() {
// blah blah...
}
与以下着色器属性绑定:
var p = gl.createProgram();
gl.bindAttribLocation(p, 0, "vtx_pos");
gl.bindAttribLocation(p, 1, "vtx_nrm");
gl.bindAttribLocation(p, 2, "vtx_int"); // <- ivec4 on array #2
最后是以下AttribPointer配置:
gl.vertexAttribPointer(0, 4, gl.FLOAT, false, 28, 0);
gl.enableVertexAttribArray(0);
gl.vertexAttribPointer(1, 3, gl.FLOAT, false, 28, 16);
gl.enableVertexAttribArray(1);
gl.disableVertexAttribArray(2); // <- here is the devil
使用此配置(禁用 VertexAttribArray(2)),浏览器会抛出属性 2 的类型错误:
Chrome: GL_INVALID_OPERATION : glDrawElements: vertexAttrib function must match shader attrib type
火狐:drawElements: Vertex attrib 2 requires data of type INT, but is being supplied with type FLOAT.
我的理解是,当 VertexAttribArray 未使用正确的 vertexAttribI 指针显式启用时,WebGL 默认认为它是 "supplied as FLOAT",因此,抛出类型错误。
我不明白的是:为什么它检查提供的 disabled VertexAttribArray 类型,逻辑上,提供 nothing ?
除了将 VertexAttribArray 启用为虚拟对象之外,是否有一些魔法可以避免此错误?
引用 GL ES 3.0 §2.8:
The resulting attribute values are undefined if the base type of the shader attribute at slot index is not floating-point (e.g. is signed or unsigned integer).
WebGL 2.0 eliminates undefined behaviour here and mandates that an error should be produced.
所以,默认情况下非数组属性的值确实是一个浮点向量。如果着色器中的实际属性是无符号整数值的整数,则应通过 vertexAttribI4*
family 的调用手动指定其值,即:
gl.vertexAttribI4i(2, 0, 0, 0, 0);