• 动画系统


    动画系统

    1、精灵动画(sprite animation)是最基础的动画,主要用于实现2D动画。在3D游戏中,远离摄像机的物体也会使用到精灵动画,如远处的杂草、观众。

    2、刚性层阶式动画(rigid hierarchical animation)。此法中,角色由一堆刚性部分建模而成。刚性层阶技术最大的问题在于,角色的身体会在关节位置产生碍眼的“裂缝”。

    3、每顶点动画(per-vertex animation),一个蛮力技术。此法中,动画师为网格的顶点添加动画。这是一种数据密集的技术,因为每个顶点随时间改变的动作信息都要存储下来。

    4、变形目标动画(morph target animation)。仅制作相对较少的固定极端姿势(extream pose)。在运行时把两个或以上的这些姿势混合,就能生成动画。变形目标技术通常用于面部动画(facial animation),因为人脸具有非常复杂的解剖结构。

    5、蒙皮动画(skinned animation)。此技术含有每顶点动画及变形目标动画的优点,允许组成网格的三角形做出变形。也有刚性层阶式动画的高效性能及内存使用量特性。骨骼是由刚性的“骨头”(bone)所建构而成的。称为皮肤(skin)的加油三角形网格会绑定于骨骼上,其顶点会追踪关节(joint)的移动。蒙皮上每个顶点可绑定至多个关节,因此当关节移动时,蒙皮可以自然地拉伸。

    6、相比原始的每顶点动画,大多数动画技术也可被视为一项压缩技术。

    7、骨骼是由刚性的关节(joint)层阶构成。骨头一词名为副实,技术上来说,骨头只是关节之间的空位。骨骼的关节形成层阶结构,其中一个为根。骨架包含关节,关节通常依次放置在数组中,第0个元素即为根关节。

     1 struct Joint
     2 {
     3     Matrix4x3 m_invBindPose; // 绑定姿势之逆变换
     4     const char* m_name;      // 人类可读的关节名字
     5     U8 m_iParent;            // 父索引  
     6 };
     7 struct Skeleton
     8 {
     9     U32 m_jointCount; // 关节数目
    10     Joint* m_aJoint;  // 关节数组 
    11 };

    8、一个关节的姿势(pose)定义为关节相对某参考系(frame of reference)的位置、定向和绽放。通常用SQT(缩放、四元数、平移)来表示。绑定姿势(bind poase),有时候也叫参考姿势(reference pose)或放松姿势(free pose),或T姿势(T-pose)。我们有时用局部姿势(local pose)描述相对父的姿势。

    9、有些游戏引擎不容许关节绽放。有些引擎会假设,若使用绽放,其必须为统一绽放,即3个维度上的绽放都相同。内存中表示关节姿势:

     1 struct JointPose
     2 {
     3     Quaternion m_rot; // Q
     4     Vector3 m_trans;  // T
     5      F32 m_scale;     // S, 仅为统一绽放
     6 };
     7 
     8 struct SkeletonPose
     9 {
    10     Skeleton* m_pSkeleton;
    11     JointPose* m_aLoclPose;
    12 }; 

    10、把关节姿势表示为模型空间或世界空间会很方便。这称为全局姿势(global pose)。我们可以扩展SkeletonPose的数据结构,以包含全局姿势。

    struct SkeletonPose
    {
        Skeleton* m_pSleleton;   // 骨骼 + 关节数量
        JointPose* m_aLocalPose; // 多个局部关节姿势
        Matrix44* m_aGlobalPose; // 多个全局关节姿势 
    };

    11、游戏角色必须拆分为小粒度的动作,这些个别的动作称为动画片段(animation clip)

    12、动画师会在片段中指定的时间点上设定一些重要而少量的姿势,这些姿势称为关键姿势(key pose)或关键帧(key frame),然后计算机会插值计算中间的姿势。动画引擎能够在片段间任何时间内采样,不一定要在整数帧索引上采样。

    13、1s动画以每秒30帧采样,其时长是30帧,并含有31个采样。若片段是非循环的,N个帧动画有N+1个独一无二的采样。若片段是循环的,那么最后一个采样是冗余的,因此N个帧的动画有N个独一无二的采样。

    14、要令片段好好地循环,片段最后的角色姿势必须完全和最初的姿势匹配。那么也即意味着,循环片段的最后一个采样是冗余的。因此许多游戏引擎会略去循环片段的最后一个采样。

    15、要同步两个或以上的动画片段,而它们的持续时长又不相同,归一化时间就很适用。使用局部时钟来同步多个动画时会导致多个动画协调的问题,使用全局时钟可以缓和动画同步问题。

    16、每个动画片段是为特定骨骼设计的,若一组骨骼基本上是相同的,那么过于细节的骨骼的抛弃可以实现骨骼动画的复用。

     1 struct Animation Sample
     2 {
     3     JointPose* m_aJointPose; // 关节姿势数组
     4 };
     5 
     6 struct AnimationClip
     7 {
     8     Skeleton* m_pSkeleton;
     9     F32 m_framesPerSecond;
    10     U32 m_frameCount;
    11     AnimationSample* m_aSamples; // 采样数组
    12     bool m_isLooping;
    13 };

    17、元通道(metachannel)数据是在动画每一帧所提供的额外的数据。较常见的一种特殊通道是在多个时间眯上储存事件触发器(event trigger)。又例如,当左脚或右脚接触地面时,便可以播放一个脚步声及一个“尘雾”粒子效果。

    18、把三维网格顶点联系至骨骼的过程称为蒙皮(skinning)。每个顶点可绑定一个或多个关节。若只绑定一个关节,它就会完全跟着关节移动。若绑定多个关节,该顶点的位置就等于把它逐一绑定至个别关节后的位置,再取其加权平均,每个顶点的权重因子之和为1。因所有关节权重和必须为1,所有最后一个权重可以略去。

    19、通常游戏引擎会限制每个顶点能绑定的关节数目。典型的限制为每顶点4个关节。原因如下,首先4个8位关节索引能方便地包裹为一个32位字。此外,每顶点使用2、3、4个关节所产生的质量很容易区分,但多数人并不能分辨出每顶点4个关节以上的质量差别。

    1 struct SkinnedVertex
    2 {
    3     float m_position[3];    // (Px, Py, Pz)
    4     float m_normal[3];      // (Nx, Ny, Nz)
    5     float m_u, m_v;         // 纹理坐标(u, v)
    6     U8 m_jointIndex[4];     // 关节索引
    7     float m_jointWeight[3]; // 关节权重,略去最后一个
    8 };

    20、我们需要一个矩阵,该矩阵能把网格顶点从原来位置(绑定姿势)变换至骨骼的当前姿势。我们称此矩阵为蒙皮矩阵(skinning matrix)蒙皮矩阵也是在模型空间定义的。我们可以把模型空间的绑定姿势位置转换至关节空间,再把关节移至当前姿势,最后把该顶点转回模型空间。蒙皮矩阵=绑定姿势美逆矩阵*当前姿势矩阵。

    21、我们须计算一组蒙皮矩阵Kj,当中每个矩阵对应第j个关节。此数组称为矩阵调色板(matrix palette)

    22、每个顶点最终会由模型空间变换至世界空间。因此有些引擎会把蒙皮矩阵调色版预先乘以物体的模型至世界变换。这是个很有用的优化,因为渲染引擎渲染蒙皮几何时,每个顶点能节省一个矩阵乘法。

    23、对多单顶点绑定多关节的情况,我们可以计算顶点分别蒙皮至每个关节,产生对于每个节点的模型空间位置,然后把这些结果进行加权平均来求出最终位置。

  • 相关阅读:
    codeforces-1194 (div2)
    单链表1(悲剧文本)
    迷宫(深度搜索)
    皇后问题
    关键路径
    [NOI2015]软件包管理器
    [USACO13JAN]岛游记Island Travels
    仓鼠找sugar
    [SHOI2012]魔法树
    [HEOI2016/TJOI2016]树
  • 原文地址:https://www.cnblogs.com/tekkaman/p/3639315.html
Copyright © 2020-2023  润新知