当我将浮点数转换为 int 时,我来这里是为了获得有关我的 GLSL 代码的奇怪行为的帮助,自从我启动 GLSL 以来,我从未见过这样的错误
实际上我正在尝试使用 GLSL 在 CPU 上实现网格蒙皮
我使用 ATI Radeon HD 4850 (Gainward),并在 Windows XP 上使用 OpenGL 2.1
所以在 CPU 端,我收集骨骼索引和权重,然后将它们扔到带有顶点属性的着色器中,然后我将骨骼矩阵与权重相乘,并使用结果来计算法线和 gl_Position
很平常,直到那里
当我必须从骨骼索引中检索骨骼时出现问题
我使用带有 4 根骨头的简单圆柱网格;我通过统一变量从 Cpu 发送骨骼,似乎问题不是来自这些骨骼矩阵,我在着色器中对它们进行了硬编码,并且错误仍然存在顺便说一下,当我与 Maya 渲染进行比较时,形状是正确的
此外,每个顶点的骨骼索引仍然相同:0、1、2、3;它们通过 VBO 以 GL_UNSIGNED_INT 类型发送;但在着色器中,uvec4 似乎不起作用(ivec4 也不行),所以我必须使用 float vec4 并使用 int()
所以这是我的顶点着色器代码:
uniform mat4 ModelViewMatrix;
uniform mat4 ProjectionMatrix;
uniform mat3 NormalMatrix;
uniform mat4 bones[4];
varying vec3 normal;
attribute vec3 v_pos;
attribute vec3 v_normal;
//the 4 first bones indices of the vertex;
attribute vec4 v_boneIndices0;
//the 4 first bones weights of the vertex
attribute vec4 v_boneWeights0;
void main()
{
/* To compare with bones sent via uniform, i hardcoded the bones matrices in this array; doesn't seem to make a difference
mat4 mattab[4];
mattab[0] = mat4(1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f);
mattab[1] = mat4(1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.816489f, 0.57736f, 0.0f,
0.0f, -0.57736f, 0.816489f, 0.0f,
0.0f, -0.341108f, 1.07319f, 1.0f);
mattab[2] = mat4(0.999949f, -0.00863831f, 0.00528692f, 0.0f,
-0.00400147f, 0.142574f, 0.989776f, 0.0f,
-0.00930377f, -0.989746f, 0.142532f, 0.0f,
0.00201152f, -0.00111439f, 0.865123f, 1.0f);
mattab[3] = mat4(0.799844f, -0.0233416f, -0.599754f, 0.0f,
0.448905f, 0.686556f, 0.571949f, 0.0f,
0.398414f, -0.726702f, 0.559616f, 0.0f,
-1.23581f, -1.4976f, 2.0412f, 1.0f );
*/
//the average matrix of weighted bones
mat4 mat = mat4(0.0f);
for ( int i = 0; i < 4; i++){
//normally, the both lines below are equivalent
//because v_boneIndices0 is always 0,1,3,4
mat += v_boneWeights0[i] * bones[int(v_boneIndices0[i])];
//mat += v_boneWeights0[i] * bones[i];
}
//Here, I multiply the average matrix with v_normal and v_pos
normal = NormalMatrix * (mat3(mat[0].xyz,mat[1].xyz,mat[2].xyz) * v_normal);
gl_Position = ProjectionMatrix*ModelViewMatrix*(mat*vec4(v_pos, 1.0f));
}
当我查看 FPS 速率时会出现该错误;没有剥皮,我得到 2000 FPS
当我使用这条线时
mat += v_boneWeights0[i] * bones[i];
,
我用一些人工制品得到了正确的形状,FPS 保持在 2000
但是当我使用这条线时
mat += v_boneWeights0[i] * bones[int(v_boneIndices0[i])];
(与另一条线相似)形状很完美,但 FPS 下降到 1500 FPS...
我认为是线路本身减慢了循环速度;但是,如果我离开这条线并从正常和 gl_Position 计算中删除垫子,则 FPS 速率会上升到 2000
另一个奇怪的行为,如果我计算
vec4 test = ProjectionMatrix*ModelViewMatrix*(mat*vec4(v_pos, 1.0f));
就在循环之后,计算 Normal gl_Position 没有垫乘法
normal = NormalMatrix * v_normal;
gl_Position = ProjectionMatrix*ModelViewMatrix* vec4(v_pos, 1.0f);
FPS率也上升到2000
就像只有当我结合时才会出现错误
mat += v_boneWeights0[i] * bones[int(v_boneIndices0[i])];
and
normal = NormalMatrix * (mat3(mat[0].xyz,mat[1].xyz,mat[2].xyz) * v_normal);
gl_Position = ProjectionMatrix*ModelViewMatrix*(mat*vec4(v_pos, 1.0f));
我认为这是一个硬件错误,或者我做错了,我不知道但我确定问题与强制转换 int() 有关,顺便说一下,为什么 uvec4 和 ivec4 不起作用?
有人在 Nvidia 遇到过这种行为吗?我在 Google 上一无所获
我希望你能帮助我
谢谢 :)