平民程序 - linghuye's blog

天下风云出我辈,一入江湖岁月催。皇图霸业谈笑中,不胜人生一场醉。提剑跨骑挥鬼雨,白骨如山鸟惊飞。尘事如潮人如水,只笑江湖几人回。

随笔 - 221, 文章 - 0, 评论 - 680, 引用 - 0
数据加载中……

WoW骨骼动画的GLSL实现

在OpenGL.org论坛上不幸被告知VERTEX_BLEND_ARB扩展不属OpenGL核心标准,被ARB卡查掉了,Nvidia也不实现了,所以在OpenGL下要做骨骼动画只好靠Shader了,让CPU计算,效率会很惨,写写Demo还凑和.

使用指令将顶点的骨骼和权重信息作为Generic Attribute属性传入给Shader对象.
GLint indexBone = glGetAttribLocationARB(m_glPrograme, "bone");
GLint indexWeight = glGetAttribLocationARB(m_glPrograme, "weight");
glVertexAttribPointerARB(indexBone, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(MDL_VERTEX), m_arrMdlVertices[0].bones);
glVertexAttribPointerARB(indexWeight, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(MDL_VERTEX), m_arrMdlVertices[0].weights);
glEnableVertexAttribArrayARB(indexBone);
glEnableVertexAttribArrayARB(indexWeight);

在每帧在CPU中计算骨骼矩阵,并将计算好的骨骼矩阵数组传入Shader对象.
GLint indexBoneMatrices = glGetUniformLocationARB(m_model.m_glPrograme, "boneMatrices");
for(unsigned int i = 0; i < m_animSkeleton.m_vecBones.size(); i++)

 CM2Bone* pBone = m_animSkeleton.m_vecBones[i];
 glUniformMatrix4fvARB(indexBoneMatrices + i, 1, GL_TRUE, pBone->m_transformMatrix);
}

搞定,运行,发现wow的兽人模型竟然有128个骨骼,而N6200的shader的Uniform Matrix参数最多只给60个,还得考虑低端机器,玻璃渣是怎么做的?发现DX的实现从来就是送入硬件处理的,节省了额外的顶点内存,加快了速度,确实是不二的选择.
结论:
1.模型中的LOD是硬件LOD,即匹配给各层次的显卡使用的,最小LOD的动画都只需十几根骨骼,这对美工的要求很高.
2.可以直接传入UNSIGNED_BYTE的骨骼权重,让显卡去运算到float的mapping.
3.uniform mat4 boneMatrices[60];显卡能力不同将导致这里实际的60数值不同.
4.低端显卡不支持for循环控制流,要拆开手写.

attribute vec4 bone;
attribute vec4 weight;
uniform mat4 boneMatrices[
32];

void main()
{    
    vec4 blendVertex 
= vec4(0000);
    
    
for(int i = 0; i < 4; i++)
    {    
    blendVertex 
+= boneMatrices[int(bone[i])] * gl_Vertex * weight[i];
    }
    
    gl_Position 
= gl_ModelViewProjectionMatrix * blendVertex;
    gl_TexCoord[
0= gl_MultiTexCoord0;
    gl_FrontColor 
= gl_Color;
    
    vec4 ecPos 
= gl_ModelViewMatrix * blendVertex;
    gl_FogFragCoord 
= abs(ecPos.z);
}

修正:
1.ATI实现的GLSL实在缺德, gl_TextureMatrix不是默认单位矩阵值,而是没有定义, Nvidia下运行正常,ATI不正常.

posted on 2005-11-14 17:38 linghuye 阅读(3481) 评论(2)  编辑 收藏 引用 所属分类: 3D图形学研究MyWarCraftStudio

评论

# re: WoW骨骼动画的GLSL实现  回复  更多评论   

兽人骨骼总数虽然多,但是对于每个顶点来说,会影响他的就那么几个,所以把boneMatrix也当作顶点的attribute,每次计算只会传入影响这个顶点的boneMatrix和相应weight,这样就没问题了。
2013-08-07 15:12 | 路人甲

# re: WoW骨骼动画的GLSL实现  回复  更多评论   

@路人甲
那怎么样传顶点matrix
2013-08-16 13:55 | 路人乙
只有注册用户登录后才能发表评论。