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
)。
我使用 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
)。