最近刚开始接触计算机动画,一片空白,尝试做了一下3D蒙皮,发现数学真是差得难以想象,矩阵的什么的全部忘记了,真是接下来该恶补一下基础了……
在这里把遇到的几个问题记录一下。
主要参考书目:《计算机动画算法与技术》《3D游戏》(英国人写的书已经绝版了)《3D游戏引擎设计——实时计算机图形学应用方法》
关节就是一个变换矩阵,在层次储存中,一般会从根节点开始一层层的储存关节矩阵:
所以每个关节储存的矩阵都是建立根关节之上的。
以3个关节为例,转换如下:
—(T0世界矩阵)—>Link0—(T1相对Link0的Link1转换,相对旋转R0)—>Link1—(T1.1相对Link1的Link1.1转换,相对旋转R1)—>Link1.1
另外每个关节的变换无非就是旋转加平移。
故,设有一在Link1.1的坐标中有顶点V,那么将其转换到世界坐标V‘就是:
V‘ = T0*T1*R1*T1.1*R1*V(这里使用列向量)
这个其实就是将局部坐标中的顶点通过这一系列的矩阵变换到世界坐标中。
在蒙皮顶点混合的时候由于我写的程序还是相当蛋疼的,我为了方便导入把一个模型拆成了3个模型,然后把三个模型一一变换到世界空间,这样免去从模型空间到骨骼空间的计算,但是在混合的时候需要根据骨骼来装换顶点到对应的骨骼空间,这些东西都在shader中计算完成。
#version 410 core layout (location = 2) in vec4 a_position; layout (location = 3) in vec4 a_weight; uniform mat4 mv_matrix; uniform mat4 proj_matrix; uniform mat4 b1_matrix; uniform mat4 b2_matrix; uniform mat4 b3_matrix; uniform int bone; //骨骼长度 float bone_len = 47.2441f; void main() { vec4 new_a_position = a_position; vec4 new_a_position1 = a_position; //向上偏移的顶点 new_a_position.y += bone_len; //向下偏移的顶点 new_a_position1.y -= bone_len; //对不同的骨骼做不同的变换 switch(bone) { case 1: gl_Position = proj_matrix*mv_matrix*(a_weight.x*b1_matrix*a_position+a_weight.y*b2_matrix*new_a_position1); break; case 2: gl_Position = proj_matrix*mv_matrix*(a_weight.x*b1_matrix*new_a_position+a_weight.y*b2_matrix*a_position+a_weight.z*b3_matrix*new_a_position1); break; case 3: gl_Position = proj_matrix*mv_matrix*(a_weight.y*b2_matrix*new_a_position+a_weight.z*b3_matrix*a_position); break; default: break; } }
然后是截图:
混合顶点后
时间: 2024-10-16 22:51:08