我一直在尝试将
Uint32Array
缓冲区指向 uint
输入变量。
我在网上找到的所有信息都说这应该是可能的,但无论我做什么,我都会遇到同样的错误:
[.WebGL-0x62401b7e200] GL_INVALID_OPERATION: Vertex shader input type does not match the type of the bound vertex attribute.
这是我的顶点着色器:
#version 300 es
in vec4 a_ipos;
in uint a_cdata;
uniform vec2 ures;
void main() {
uint x = a_cdata & 0x7C00u;
uint y = a_cdata & 0x03E0u;
uint z = a_cdata & 0x001Fu;
vec4 pos = a_ipos + vec4(float(x), float(y), float(z), 1.);
gl_Position = vec4(pos.x * ures.y / ures.x, pos.yzw);
}
这是我对 webgl 的调用,将缓冲区指向属性:
gl.bindBuffer(gl.ARRAY_BUFFER, chunkBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Uint32Array(chunkData), gl.STATIC_DRAW);
gl.enableVertexAttribArray(cdataloc);
gl.vertexAttribPointer(
cdataloc,
1,
gl.UNSIGNED_INT,
false,
0,
0
);
看来
gl.UNSIGNED_INT
与uint
不是同一类型。
然而,GLSL 300 ES 参考卡说它是一个 32 位无符号整数。
MDN 同意 gl.UNSIGNED_INT
是 32 位无符号整数。
我不知道我做错了什么。我尝试过使用
gl.INT
和 in int ...
但仍然没有任何效果。将整数的精度更改为 highp
也不会改变任何内容。 (假设 highp
会将整数转换为 32 位,但情况似乎并非如此)。
将类型更改为浮动确实有效。但我使用的任何其他类型都没有。
我也尝试过使用
gl.SHORT
。这是为了放弃 glsl 中的 int
类型可能是 16 位整数的理论。还是同样的错误。
这个问题:WebGL:如何在 GLSL 中使用整数属性
没有解决我的问题。由于答案提供的文档已经过时。根据规范,GLSL 1.00 ES 不允许在属性中使用整数。
但是,GLSL 3.00 ES 规范似乎并不关心,只要类型不是以下之一:
boolean
、opaque
、array
、struct
。
这是一个典型的错误。
type
中的数据
vertexAttribPointer()
指的是数组本身(或缓冲区中的更多)中的数据类型。
vertexAttribPointer()
时,数据(仍然)会转换为浮点数。您可以使用 normalized
来控制它是否标准化,但它仍然会转换为浮点数。
vertexAttribIPointer()
(请注意 I 表示 整数。)
vertexAttribPointer()
// ^ No I so Float
vertexAttribIPointer()
// ^ I for Integer