我使用的是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 pc上运行此代码。它工作正常,但是当我使用emscripten将其编译到Web浏览器时。它给出gl错误1282(无效操作)。
如果我更改为GL_FLOAT,这将修复gl错误,但是,所有骨骼索引都变为0,并且我得到了无蒙皮的网格物体,因为骨骼0的单位矩阵为bindpose和worldpose矩阵。
最佳答案
ES 2.0不支持整数属性。从GLSL ES 1.00规范(与ES 2.0一起使用的GLSL版本)开始:
您可以执行的最接近的操作是在着色器代码中使用vec4
,并在需要时将float值转换为整数。
如果您在客户端的数据是整数格式,则必须小心glVertexAttribPointer()
调用。作为第4个参数传递的 bool(boolean) 值指定是否要对值进行规范化,或者是否应将它们转换为没有规范化的float值。对于您的情况,您将希望传递GL_FALSE
。例如,如果您的客户端代码中包含字节数据:
glVertexAttribPointer(loc, 4, GL_UNSIGNED_BYTE, GL_FALSE, 0, 0);
ES 3.0及更高版本支持整数属性。因此,您可以在其中将
ivec4
用于属性,并在客户端代码中使用glVertexAttribIPointer()
(请注意函数名称中的其他I
)指定值。