ivec4 作为顶点属性 Opengl ES 2.0

ivec4 as vertex attribute Opengl ES 2.0

我使用 openglEs 2.0。我正在研究硬件皮肤。我尝试将骨骼索引作为 ivec4 传递,但是编译器告诉我不可能将 ivec4 用作顶点属性。我该如何克服这种情况?

这是我的顶点着色器代码。

0(1) : error C7507: OpenGL does not allow attributes of type ivec4
"struct Bone"
    "{"
    "   mat4 transform;"
    "   mat4 bindPose;"
    "};"
    "attribute vec3 vPosition;"
    "attribute vec3 vNormal;"
    "attribute vec2 vTexture;"
    "attribute ivec4 vBones;"
    "attribute vec4 vWeights;"
    "uniform mat4 projectViewModel;"
    "uniform Bone bones[64];"
    "varying vec3 v_normal;"
    "varying vec2 v_texCoord;"
    "void main()"
    "{"
    "   gl_Position = bones[vBones.x].transform * bones[vBones.x].bindPose * vec4(vPosition, 1.0) * vWeights.x;"
    "   gl_Position += bones[vBones.y].transform * bones[vBones.y].bindPose * vec4(vPosition, 1.0) * vWeights.y;"
    "   gl_Position += bones[vBones.z].transform * bones[vBones.z].bindPose * vec4(vPosition, 1.0) * vWeights.z;"
    "   gl_Position += bones[vBones.w].transform * bones[vBones.w].bindPose * vec4(vPosition, 1.0) * vWeights.w;"
    "   gl_Position = projectViewModel * gl_Position;"
    "   v_texCoord = vTexture;"
    "   v_normal = vNormal;"
    "}";

更新:

正如我所知,我更改了着色器代码和客户端代码。这是客户端代码:

glEnableVertexAttribArray(3); // Bones
glVertexAttribPointer(3, 4, GL_INT, GL_FALSE, object->m_mesh->GetVertexSize(), (const void*)offset);

这就是我在着色器代码中访问骨骼索引的方式:

gl_Position = bones[int(vBones.x)].transform * bones[int(vBones.x)].bindPose * vec4(vPosition, 1.0) * vWeights.x;

如果我 运行 此代码在 windows 电脑上。它工作得很好,但是当我用 emscripten 将它编译到网络浏览器时。它给出 gl 错误 1282(无效操作)。

如果我更改为 GL_FLOAT 这会修复 gl 错误,但是,所有骨骼索引变为 0 并且我得到一个 none 蒙皮网格,因为骨骼 0 具有单位矩阵作为 bindpose 和 worldpose 矩阵。

ES 2.0 不支持整数属性。来自 GLSL ES 1.00 规范(这是与 ES 2.0 一起使用的 GLSL 版本):

The attribute qualifier can be used only with the data types float, vec2, vec3, vec4, mat2, mat3, and mat4.

最接近的做法是在着色器代码中使用 vec4,并在需要时将浮点值转换为整数。

如果您在客户端的数据是整数格式,您必须小心您的 glVertexAttribPointer() 调用。作为第 4 个参数传递的布尔值指定是否要对值进行规范化,或者是否应将它们转换为 float 而不进行规范化。在您的情况下,您将希望通过 GL_FALSE。例如,如果您的客户端代码中有字节数据:

glVertexAttribPointer(loc, 4, GL_UNSIGNED_BYTE, GL_FALSE, 0, 0);

ES 3.0 及更高版本支持整数属性。因此,您可以使用 ivec4 作为属性,并在客户端代码中使用 glVertexAttribIPointer() 指定值(注意函数名称中的附加 I)。