Opengl GLSL-铸造问题和奇怪的缺陷
我来这里是想获得关于我的GLSL代码的一个奇怪行为的帮助,当我将浮点值转换为int时,自从我启动GLSL以来,我从未见过这样的错误 实际上,我正在尝试使用GLSL在CPU上实现网格蒙皮 我使用ATI Radeon HD 4850(Gainward),并在Windows XP上使用OpenGL 2.1 因此,在CPU端,我收集骨骼索引和权重,并将它们扔到具有顶点属性的着色器中 然后我将骨骼矩阵与权重相乘,并使用结果计算法线和gl_位置 在那里以前都很平常 当我必须从骨骼索引中检索骨骼时,会出现问题 我使用的是一个简单的圆柱体网格,有4块骨头;我通过一个统一变量从Cpu发送骨骼,问题似乎不是来自这些骨骼矩阵,我在着色器中对它们进行了硬编码,错误仍然存在 顺便说一下,与maya渲染相比,形状是正确的 此外,每个顶点的骨骼指数仍然相同:0、1、2、3;它们通过VBO以GL_UNSIGNED_INT类型发送;但是在着色器中,uvec4似乎不起作用(ivec4也不起作用),因此我必须使用float vec4和cast with int() 下面是我的顶点着色器代码:Opengl GLSL-铸造问题和奇怪的缺陷,opengl,casting,glsl,Opengl,Casting,Glsl,我来这里是想获得关于我的GLSL代码的一个奇怪行为的帮助,当我将浮点值转换为int时,自从我启动GLSL以来,我从未见过这样的错误 实际上,我正在尝试使用GLSL在CPU上实现网格蒙皮 我使用ATI Radeon HD 4850(Gainward),并在Windows XP上使用OpenGL 2.1 因此,在CPU端,我收集骨骼索引和权重,并将它们扔到具有顶点属性的着色器中 然后我将骨骼矩阵与权重相乘,并使用结果计算法线和gl_位置 在那里以前都很平常 当我必须从骨骼索引中检索骨骼时,会出现问题
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下降到1500 FPS
我认为是线路本身减慢了环路的速度;但是,如果我离开这条线,从正常和gl_位置计算中删除mat,FPS速率将上升到2000
另一种奇怪的行为,如果我计算的话
vec4 test = ProjectionMatrix*ModelViewMatrix*(mat*vec4(v_pos, 1.0f));
循环结束后,计算正常gl_位置,无需mat乘法
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));
我认为这是一个硬件缺陷,或者我做错了,我不知道
但我确信问题与cast int()有关
顺便问一下,为什么uvec4和ivec4不起作用
有没有人在英伟达遇到过这种行为?我在谷歌上什么也没找到
我希望你能帮助我
谢谢:)您的错误是查看每秒帧数的性能,而不是每帧时间(timedelta)。2000 fps和1500 fps之间的差异非常小。2000fps表示每帧0.5ms。1500 fps表示每帧0.6 ms。fps和每帧时间之间的相关性不是线性的。有效fps为1/timedelta。由于时间窗口非常小,所以fps越敏感。假设你有10000 fps,它在10000 fps和5000 fps之间波动。这将为您提供一个介于0.1 ms和0.2 ms之间的时间窗口。此时,任何操作都可能影响时间增量。ivec4和uvec4不是OpenGL 2.1中GLSL的一部分,它是一个扩展(GL_EXT_gpu_shader4),因此您需要使用以下命令启用该扩展:
#extension GL_EXT_gpu_shader4 : enable
在着色器的开头,然后可以在着色器中使用实整数。请注意,此扩展仅在DX 10和更新的卡(您的卡支持)中受支持
扩展是核心OpenGL 3.0的一部分。有趣的是,我知道FPS不是很精确,但实际上这不是主题,如何解释两行代码的区别,它们做的事情完全相同(如果您阅读了上面的代码?)。转换及其有效性如何?哦,这些不是转换。他们是构造器。好的,解决了,我刚刚宣布骨骼指数在CPU端浮动,现在没有减速,但是ivec4和uvec4仍然不工作:(不,只有uvec4。当然是99.99%,看到了吗
#extension GL_EXT_gpu_shader4 : enable