Game Engine Architecture 11

Game Engine Architecture 11

1、three most-common techniques used in modern game engines.

1)Cel Animation

2)Rigid Hierarchical Animation

3)Per-Vertex Animation and Morph Targets

2、Cel Animation

The precursor to all game animation techniques is known as traditional animation, or hand-drawn animation. This is the technique used in the earliest animated cartoons.

Cel animation is a specific type of traditional animation. A cel is a transparent sheet of plasticon which images can be painted or drawn.

The electronic equivalent to cel animation is a technology known as sprite animation.

3、Rigid Hierarchical Animation,刚体层次动画 / 刚体动画。

a character is modeled as a collection of rigid pieces. A typical breakdown for a humanoid character might be pelvis(盆骨), torso(躯干), upper arms, lower arms, upper legs, lower legs, hands, feet and head.

A typical hierarchy has the pelvis at the root, with the torso and upper legs as its immediate children and so on as shown below:

The big problem with the rigid hierarchy technique is that the behavior of the character’s body is often not very pleasing due to “cracking” at the joints. This is illustrated in Figure 12.2.

4、Per-Vertex Animation and Morph Targets

per vertex _animation_is a data-intensive technique, since time-varying motion information must be stored for each vertex of the mesh. For this reason, it has little applicationto real-time games.

morph target animation is used in _some real-time games._Animations _are produced by blending between two or more of these fixed poses at runtime._The morph target technique is often used for facial animation, because the human face is an extremely complex piece of anatomy, driven by roughly 50 muscles.

As computing power continues to increase, some studios are using jointed facial rigs containing hundreds of joints as an alternative to morph targets. Other studios combine the two techniques, using jointed rigs to achieve the primary pose of the face and then applying small tweaks via morph targets.

顽皮狗的《最后生还者》中,Ellie的面部动画使用提 morph target。

5、Skinned Animation,蒙皮动画。

In skinned animation, a skeleton is constructed from rigid “bones,” just as in rigid hierarchical animation. However, instead of rendering the rigid pieces on-screen, they remain hidden. A smooth continuous triangle mesh called a skin is bound to the joints of the skeleton; its vertices track the movements of the joints. Each vertex of the skin mesh can be weighted to multiple joints, so the skin can stretch in a natural way as the joints move.

Rigid Hierarchical Animation 直接渲染 rigid piece,而 Skinned Animation 渲染的是 skin mesh。

6、Skeletons

In the game industry, we often use the terms “joint” and “bone” interchangeably, but _the term bone is actually a misnomer._Technically speaking, the joints are the objects that are directly manipulated by the animator, while the bones are simply

the empty spaces between the joints.

7、SRT Transformations

SRT transforms are widely used in computer animation because of their smaller size (eight floats for uniform scale, or ten floats for nonuniform scale, as opposed to the 12 floating-point numbers needed for a 4 x 3 matrix) and their ability to be easily interpolatefd.

Game Engine Architecture 11

8、Representing a Skeleton in Memory

struct Joint
{
    Matrix4x3 m_invBindPos;

    const char* m_name; // human-readable joint name
    U8 m_iParent; // parent index or 0xFF if root
};

struct Skeleton
{
    U32 m_jointCount; // number of joints
    Joint* m_aJoint; // array of joints
};

9、Poses

The pose of a joint is defined as the joint’s position, orientation and scale, relative to some frame of reference. A joint pose is usually represented by a 4×4 or 4×3 matrix, or by an SRT data structure (scale, quaternion rotation and vector translation). The pose of a skeleton is just the set of all of its joints’ poses and is normally represented as a simple array of SRTs.

skeleton 的姿势就是其内所有 joint 的姿势 。

10、Bind Pose

This is the pose of the 3D mesh prior to being bound to the skeleton. 3D mesh 绑定前的姿势。

The bind pose is also called T-pose. This particular stance is chosen because it keeps the limbs away from the body and each other, making the process of binding the vertices to the joints easier.

11、Local Poses

A joint’s pose is most often specified relative to its parent joint. Local poses are almost always stored in SRTformat.

many 3D authoring packages like Maya represent joints as small spheres. However, a joint has a rotation and a scale, not just a translation, so this visualization can be a bit misleading.

The pose of an entire skeleton P^skel can be written as the set of all poses Pj, where j ranges from 0 to N-1:

Game Engine Architecture 11

12、Representing a Joint Pose in Memory

struct JointPose
{
    Quaternion m_rot; // R
    Vector3 m_trans; // T
    F32 m_scale; // S (uniform scale only)
};

struct JointPose
{
    Quaternion m_rot; // R
    Vector4 m_trans; // T
    Vector4 m_scale; // S
};

struct SkeletonPose
{
    Skeleton* m_pSkeleton; // skeleton + num joints
    JointPose* m_aLocalPose; // local joint poses
};

13、Representing a Global Pose in Memory

struct SkeletonPose
{
    Skeleton* m_pSkeleton; // skeleton + num joints
    JointPose* m_aLocalPose; // local joint poses
    Matrix44* m_aGlobalPose; // global joint poses
};

13.1、The Joint Pose as a Change of Basis

when the joint pose transform Pj is applied to a point or vector that is expressed in the coordinate system of the joint j, the result is that same point or vector expressed in the space of the parent joint.

Pj 是关节 j 的Pose矩阵。Pj 可以将将 j 坐标下的点转移到 P(j) 下。

14、Clips

game animations are almost never created as long, contiguous sequences of frames. Instead, a game character’s movement must _be broken down into a large number of fine-grained motions._We call these individual motions animation clips, or sometimes just animations.

The term FMV applies to sequences that have been prerendered to an MP4, WMV or other type of movie file and are played back at runtime by the engine’s full-screen movie player.

quick time event (QTE). In a QTE, the player must hit a button at the right moment during an otherwise noninteractive sequence in order to see the success animation and proceed;

15、Frames, Samples and Looping Clips

• If a clip is non-looping, an N-frame animation will have N + 1 unique samples.

• If a clip is looping, then the last sample is redundant, so an N-frame animation will have N unique samples.

16、A Simple Animation Data Format

Game Engine Architecture 11
struct AnimationSample
{
    JointPose* m_aJointPose; // array of joint poses
};

struct AnimationClip
{
    Skeleton* m_pSkeleton;
    F32 m_framesPerSecond;
    U32 m_frameCount;
    AnimationSample* m_aSamples; // array of samples
    bool m_isLooping;
};

17、Relationship between Meshes, Skeletons and Clips

Game Engine Architecture 11

the skins are attached to the skeleton but don’t have any relationship with the animation clips. Likewise, the clips are targeted at a particular skeleton, but they have no “knowledge” of the skin meshes.

Game Engine Architecture 11

To provide the illusion of many different types of characters, it is usually better to create multiple meshes skinned to the same skeleton when possible, so that all of the characters can share a single set of animations.

18、Per-Vertex Skinning Information

Usually a game engine imposes an upper limit on the number of joints to which a single vertex can be bound. A four-joint limit is typical for a number of reasons. First, four 8-bit joint indices can be packed into a 32-bit word, which is convenient. Also, while it’s pretty easy to see a difference in quality between a two-, three- and even a four-joint-per-vertex model, most people cannot see a quality difference as the number of joints per vertex is increased beyond four.

struct SkinnedVertex
{
    float m_position[3]; // (Px, Py, Pz)
    float m_normal[3]; // (Nx, Ny, Nz)
    float m_u, m_v; // texture coords (u,v)
    U8 m_jointIndex[4]; // joint indices
    float m_jointWeight[3]; // joint weights (last weight omitted)
};

19、The Mathematics of Skinning

we would like to find a matrix that can transform the vertices of the mesh from their original positions (in bind pose) into new positions that correspond to the current pose of the skeleton. We shall call such a matrix a skinning matrix.

skinning matrix 将vetex从 bind pose 转换到 current pos。

the position of a skinned vertex is specified in model space. This is true whether its skeleton is in bind pose or in any other pose.

bind pose、any pose 下,vertex 坐标系都是 model space。

20、Simple Example: One-Jointed Skeleton

Game Engine Architecture 11

Game Engine Architecture 11

Game Engine Architecture 11

The combined matrix Kj is known as a skinning matrix.

21、Incorporating the Model-to-World Transform

Game Engine Architecture 11

a technique known as animation instancing that is sometimes used for animating large crowds of characters. In this case we need to keep the model-to-world transforms separate so that we can share a single matrix palette across all characters in the crowd.

当使用 animation instancing 的时候,Kj 不会与 M(M->W)结合。

22、LERP Blending

混合两个 skeleton pose 等于混合其下各个 joint。

Game Engine Architecture 11

Game Engine Architecture 11

interpolating matrices directly is not practical. This is one of the reasons why local poses are usually expressed in SRT format.

23、Types of Cross-Fades

• Smooth transition.

• Frozen transition.

Game Engine Architecture 11

Bezier ease-in、ease-out 公式:

Game Engine Architecture 11

24、Directional Locomotion

1)pivotal movement,轴向移动

2)target movement,靶向移动

Game Engine Architecture 11

25、Targeted Movement

the animator authors three separate looping :one moving forward, one strafing to the left, and one strafing to the right. I’ll call these directional locomotion clips.

26、Pivotal Movement

To implement pivotal movement, we can simply play the forward locomotion loop while rotating the entire character.

pivotal movemnt,简单的情况,播放一个前向动画即可。

Pivotal movement looks more natural if the character’s body doesn’t remain bolt upright when it is turning—real humans tend to lean into their turns a

little bit. A more natural-looking result can be achieved by animating three variations on the basic forward walk or run—one going perfectly straight, one making an extreme left turn and one making an extreme right turn. We can then LERP-blend between the straight clip and the extreme left turn clip to implement any desired lean angle.

更为真实的处理为,类似 target movement,提供三个动画,一个前身,一个左倾,一个右倾。

27、Simple Two-Dimensional LERP Blending

Game Engine Architecture 11

28、Generalized Two-Dimensional LERP Blending

Game Engine Architecture 11

Game Engine Architecture 11

FIFA soccer by EA Sports in Vancouver, implemented within their proprietary “ANT” animation framework.

29、Parital-Skeleton Blending

30、Additive Blending

31、Mathematical Formulation

So given the source pose Sj and the reference pose Rj for any joint j in the skeleton, we can define the difference pose Dj at that joint as follows.

31.1、Additive Blending

Simple example, imagine a target animation in which the character’s left arm is bent at a 90 degree angle. If we add a difference animation that also rotates the elbow by 90 degrees, then the net effect would be to rotate the arm by 90 + 90 = 180 degrees. This would cause the lower arm to interpenetrate the upper arm—not a comfortable position for most individuals!

32、Stance Variation。Additive Blending的应用之一。

Game Engine Architecture 11

33、Locomotion Noise,运动噪声。Additive Blending 的应用之二。

Real humans don’t run exactly the same way with every footfall—there is variation in their movement over time.

34、animation Post-Processing

Once a skeleton has been posed by one or more animation clips and the results have been blended together using linear interpolation or additive blending, it is often necessary to modify the pose prior to rendering the character. This is called animation post-processing.

35、Procedural Animations,animation post-processing 的一种。

1)animator只需要制作汽车往前开的动画,procedural animation 将 quaternion 附加给 front wheel、steering wheel。

2)bushes sway、aside 效果。将 bushes 动画制作为骨骼动画,给他们的 root 施加一个 quaternion。

35.1、Inverse Kinematics

regular animation clip is an example of forward kinematics (FK). In forward kinematics, the input is a set of local joint poses, and the output is a global pose and a skinning matrix for each joint.

Inverse kinematics goes in the other direction: The input is the desired global pose of a single joint, which is known as the end effector. We solve for the local poses of other joints in the skeleton that will bring the end effector to the desired location.

36、Quantization

Game Engine Architecture 11Game Engine Architecture 11
U32 CompressUnitFloatRL(F32 unitFloat, U32 nBits)
{
    // Determine the number of intervals based on the
    // number of output bits we've been asked to produce.
    U32 nIntervals = 1u << nBits;
</span><span>//</span><span> Scale the input value from the range [0, 1] into
</span><span>//</span><span> the range [0, nIntervals - 1]. We subtract one
</span><span>//</span><span> interval because we want the largest output value
</span><span>//</span><span> to fit into nBits bits.</span>
F32 scaled = unitFloat * (F32)(nIntervals - <span>1u</span><span>);

</span><span>//</span><span> Finally, round to the nearest interval center. We
</span><span>//</span><span> do this by adding 0.5f and then truncating to the
</span><span>//</span><span> next-lowest interval index (by casting to U32).</span>
U32 rounded = (U32)(scaled + <span>0.5f</span><span>);

</span><span>//</span><span> Guard against invalid input values.</span>
<span>if</span> (rounded &gt; nIntervals - <span>1u</span><span>)
    rounded </span>= nIntervals - <span>1u</span><span>;

</span><span>return</span><span> rounded;

}

View Code

To handle arbitrary input values in the range [min, max], we can use these routines:

Game Engine Architecture 11Game Engine Architecture 11
U32 CompressFloatRL(F32 value, F32 min, F32 max, U32 nBits)
{
    F32 unitFloat = (value - min) / (max - min);
    U32 quantized = CompressUnitFloatRL(unitFloat, nBits);

    return quantized;
}

F32 DecompressFloatRL(U32 quantized, F32 min, F32 max, U32 nBits)
{
    F32 unitFloat = DecompressUnitFloatRL(quantized, nBits);
    F32 value = min + (unitFloat * (max - min));

    return value;
}

View Code

37、Curve-Based Compression

One of the most powerful, easiest-to-use and best-thought-out animation APIs I’ve ever worked with is Granny, by Rad Game Tools. Granny stores animations not as a regularly spaced sequence of pose samples but as a collection of nth-order, nonuniform, nonrational B-splines, describing the paths of a joint’s S, Q and T channels over

38、Blend Trees

An animation blend tree is an example of what is known in compiler theory as an expression tree or a syntax _ tree. The interior nodes of such a tree are operators, and the leaf nodes serve_ as the inputs to those operators.

39、Constraints

1)Attachments

Game Engine Architecture 11

Such special joints that they can be ignored by the animation blending pipeline are sometimes called attach points.

attach point 是一种特殊的 joint。

2)Reference Locator

每个动画中分别记录一个统一挂点。

3)IK。

The joint whose position we are trying to correct is known as the end effector.

40、

Original: https://www.cnblogs.com/tekkaman/p/10696223.html
Author: Tekkaman
Title: Game Engine Architecture 11

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/548996/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 内核同步问题

    linux内核同步问题 Linux内核设计与实现 十、内核同步方法 [手把手教Linux驱动5-自旋锁、信号量、互斥体概述](https://www.cnblogs.com/yik…

    技术杂谈 2023年6月21日
    085
  • Ubuntu 升级 Linux 内核标准流程

    注意事项 不读本注意事项没资格干这个活! 1,进行此操作前,一定要先创建磁盘快照,出现任何报错,必须回滚。 2,公司生产机避免升级一二级版本号,建议仅安装内核安全更新。 3,对公司…

    技术杂谈 2023年6月21日
    086
  • 【Python 第0课】Why Python?

    为什么用Python作为编程入门语言? 原因很简单。 嗯。。。原因就是,很 简单。。。 每种语言都会有它的支持者和反对者。去Google一下”why python&#8…

    技术杂谈 2023年7月24日
    076
  • PYTORCH: 60分钟

    什么是PyTorch? PyTorch 是一个基于Python的科学计算包,有两大用途: NumPy的替代品,可使用GPUs和其它加速器的强大功能 一个用于实现神经网络的自动微分库…

    技术杂谈 2023年7月25日
    082
  • STL的string和wstring

    STL有字符串处理类——stirng和wstring,但是用的时候会觉得不是很方便,因为它不能像TCHAR一样根据定义的宏在char类型字符串和wchar_t进行转换,总不能因为程…

    技术杂谈 2023年5月31日
    095
  • day3

    链表的定义 class ListNode: def __init__(self, val, next=None): self.val = val self.next = next …

    技术杂谈 2023年7月10日
    073
  • Java开发环境搭建

    ; ; Java开发环境搭建 JDK下载安装 配置环境变量 JDK目录介绍 Hello world及简单语法介绍 Notepad++安装及使用 如何卸载JDK 找到JDK安装目录 …

    技术杂谈 2023年6月21日
    0108
  • Appium知多少

    Appium我想大家都不陌生,这是主流的移动自动化工具,但你对它真的了解么?为什么很多同学搭建环境时碰到各种问题也而不知该如何解决。 appium为什么英语词典查不到中文含义? a…

    技术杂谈 2023年5月31日
    094
  • 为什么阿里Java开发手册不推荐使用Timestamp?

    开发手册 网上解释不推荐用 java.sql.Date、 java.sql.Time的文章有很多,但是解释为什么不推荐使用 java.sql.Timestamp文章没找到。 参考文…

    技术杂谈 2023年7月25日
    093
  • NTT 快速数论变换

    NTT 先学习FFT由于FFT是使用复数运算,精度并不好,而且也无法取模,所以有了NTT(快速数论变换)。 建议先完全理解FFT后再学习NTT。 原根 NTT使用与单位根性质相似的…

    技术杂谈 2023年6月21日
    098
  • 查看k8s 的 dashboard 的token

    kubectl -n kube-system describe $(kubectl -n kube-system get secret -n kube-system -o name…

    技术杂谈 2023年5月31日
    099
  • Ribbon、Feign和OpenFeign的区别

    RibbonRibbon 是 Netflix开源的基于HTTP和TCP等协议负载均衡组件Ribbon 可以用来做客户端负载均衡,调用注册中心的服务Ribbon的使用需要代码里手动调…

    技术杂谈 2023年5月31日
    095
  • Apache Beam WordCount编程实战及源码解读

    概述:Apache Beam WordCount编程实战及源码解读,并通过intellij IDEA和terminal两种方式调试运行WordCount程序,Apache Beam…

    技术杂谈 2023年5月31日
    063
  • 周热点回顾(6.13-6.19)

    热点随笔: · React Suspense 尝鲜,处理前后端IO异步操作 (葡萄城技术团队)· 2 万字 + 20张图| 细说 Redis 九种数据类型和应用场景 (小林codi…

    技术杂谈 2023年5月31日
    092
  • 单点登录(SSO)

    1 基础知识 单点登录机制(SSO)允许用户登录应用程序一次,并访问所有相关的系统,而不需要单独登录它们。 由于 SSO,用户只需登录一次即可使用服务,并自动登录到所有相关应用程序…

    技术杂谈 2023年7月23日
    088
  • [Python]-pdb模块-单步调试

    使用pdb模块辅助python调试。 import pdb 断点模式 在需要调试的语句前设置断点,加入这行代码: pdb.set_trace() 程序运行到这就会进入断点调试模式。…

    技术杂谈 2023年7月10日
    094
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球