GAMES105笔记 - 7.Skinning

embedded/2025/2/7 20:38:30/

7.Skinning

    • 算法
      • 线性混合蒙皮Linear Blend Skinning(LBS)
      • 对偶四元数蒙皮 Dual-quaternion Skining(DQS)
      • Blend Shapes
    • 作业

算法

线性混合蒙皮Linear Blend Skinning(LBS)

对于只有一节骨骼的蒙皮:

在初始状态下,已知顶点的世界坐标为x世界坐标,骨骼的根节点为o世界坐标,骨骼的世界旋转为Q。则我们已知:

x世界坐标 = Q x相对坐标 + o世界坐标

由此推得:

x相对坐标 = QT(x世界坐标 - o世界坐标) ①

经过旋转R、位移t之后,求得骨骼的根节点为o’ = o + t,世界旋转为Q’ = R Q。继续求顶点位置x’,则:

x’世界坐标 = Q’ x相对坐标 + o’世界坐标

结合公式①②,得求解公式1

x’世界坐标 = Q’ QT (x世界坐标 - o世界坐标) + o’

在这里插入图片描述


我们取r = x相对坐标 = QT(x世界坐标 - o世界坐标) ,即简写为r = QT(x - o) 。r是relative coordinates的缩写。

求解公式2

x’世界坐标 = Q’ r + o’

在这里插入图片描述


由于Q’ = R Q,那么Q’ QT = R Q QT = R,亦即得求解公式3:

x’世界坐标 = R (x世界坐标 - o世界坐标) + o’


特殊地,对于stance pose(标准姿势,包括了A pose和T pose)下的坐标,Q为单位矩阵,那么r = QT(x - o) = x - o,得求解公式4

x’世界坐标 = Q’ (x世界坐标 - o世界坐标) + o’


对于两节骨骼的蒙皮:

设顶点的序号为i,骨骼的序号为j。

一个顶点可能既受骨骼A的影响,也受骨骼B的影响。

因此,我们需要设置顶点xi的权重wi。在美术流程中,这个过程叫“刷权重”。

那么,顶点xi的位移就是两个骨骼的求解结果xiA和xiB的加权平均。

其中,顶点i相对于骨骼j的相对位置rij = QjT(xi - oj)。

在这里插入图片描述

因为是加权平均,所以这个算法叫“线性”混合蒙皮。


我们可以对公式进行二次整理,如果只使用R和t求解,省去Q’和o’的计算的话,我们可以得到简化后的公式:

在这里插入图片描述

其中Rj是相对旋转,tj是相对位移。


优点:计算简单,因此在工业上最常用。

缺点:会出现Candy-Wrapper Artifact,转骨骼180°之后蒙皮会拧成一个点。

原因:插值过程中,公式左边对旋转值求和,旋转值左乘的几何意义在于对坐标原点进行旋转。但是,驱动顶点的每个骨骼的原点是不一样的。如果都直接左乘旋转矩阵,而没有在右边提前减去原点的坐标,那么几何意义上的原点就是混乱的,它无法与公式右边的位置求和对应上,那么结果就是错的。

解决方法:1. Multi-linear Skinning,2. Dual-quaternion Skining

在这里插入图片描述

LBS论文 SIGGRAPH Course 2014 — Skinning: Real-time Shape Deformation

对偶四元数蒙皮 Dual-quaternion Skining(DQS)

思路:我们可以把一个旋转表示成四元数,进阶地,我们也可以把一个旋转和一个位移表示成对偶四元数。然后,对对偶四元数做slerp,即可得到平滑的效果。

对偶四元数,简称对偶数,它是四元数的进阶。

对于四元数,x = a + bi,其中i2 = -1。对于对偶数,x = a + bε,其中ε2 = 0,其他定义与四元数一致。

那么,四元数q也可以写成q = q0 + ε qε

对于任何一个旋转,都能转化成一个单位四元数。类似地,任何一个刚性变换(包括了刚性旋转和刚性平移),都能转化成一个单位对偶四元数。

在这里插入图片描述
如果说LBS是对三维坐标点做加权平均,那么DQS就是对对偶四元数做加权平均。


缺点:

对于关节弯曲处,DQS会凸出来一块。

在这里插入图片描述

优点:

LBQ和DQS都是只需要知道骨骼和权重、不需要知道别的信息、就能计算的算法。

QDS论文 https://users.cs.utah.edu/~ladislav/kavan08geometric/kavan08geometric.pdf

Blend Shapes

上面我们提到的LBS和DQS都属于基于骨骼驱动的形变,即Skeleton Subspace Deformation(SSD)。基于骨骼的形变总是有缺陷的,尤其在生物体上,对于肌肉的形变,在肩膀、或者手肘关节处,在弯曲、或者旋转时,很容易出现违和的现象。另外,刷权重这种事,还是不够直观,权重的数值需要艺术家反复地调、去猜,这个过程很无聊。

在这里插入图片描述

还有一种形变思路是,基于姿势驱动的形变,即Pose Space Deformation(PSD)。它的思路是:通过插值两个样例姿势,得到中间的姿势,进而得到整个动画。如果不止有两个姿势,而是五个,几十个,那么我们可以为此构造一个空间,这个空间叫Blend Space。我们需要根据当前的姿势,去计算每个已知动作的权重,然后做更大规模的加权插值,然后求得一个形变效果比较好的姿势结果。

首先,我们理解一下这个问题。我们可以把blend space想象成是一个高维空间,每个已知的姿势就是空间里散布的点。这些点肯定是有一定的关系的,因为生物体的骨骼不是一个可以随便扭的关节树。对于当前的姿势,它也是高维中间里的一个点。我们的目标是,求这个点 与 其它已知点 的关联性,或者说,在空间里的距离。这个点和另一个点越近,说明另一个点的权重越大,姿势就越像那个样例姿势。我们称这个求解过程叫Scatterd Data Interpolation。

在这里插入图片描述

接着,就是要解决这个问题。如何计算每个姿势的权重,有以下两种思路:

  1. 数学方法
    用数学的方法,找到这些散布点的数学关系,然后求解。
    其中,比较经典的方法是RBF(Radial Basis Function,径向基函数)Interpolation。径向基函数满足如下性质: ϕ ( x ) = ϕ ( ∥ x ∥ ) {\displaystyle \phi (\mathbf {x} )=\phi (\|\mathbf {x} \|)} ϕ(x)=ϕ(x),即:其函数值只取决于输入点和某个不动点(如原点)之间的距离。让我们把“输入点”理解为当前姿势,把“某个不动点(如原点)”,我们要想知道当前姿势最像哪个样例姿势,就求RBF,RBF的值越大,姿势越像,亦即权重越大。
    更具体的求解方程请移步大佬的博客:基于径向基函数(RBF)的函数插值。我没上手写过代码,我实在是解释不下去了…
  2. 机器学习方法
    一训一个不吭声,训练出一个喂姿势能吐出权重的神经网络。

值得一提的是,虽然这些算法有多么的聪明强悍,但最后的效果还是很依赖样例姿势的质量。而样例姿势,要么靠艺术家手k调整,要么靠三维扫描。

在实际应用中,这个思路衍生出来的解决方案叫Blend Shapes。blend shape主要用于数字人的脸部动画中。先记录人类的各种表情,然后通过blend shape的方法,让人脸逐渐从一个无表情的脸,blend到一个有表情的脸。在Maya、3D Max、UE等主流DCC软件中都有blend shape这个功能。

Q:修正姿势的时候,应该整体一起考虑,还是只考虑局部?
A:(我的个人理解:)只考虑局部的话,性能更好。但整体一起考虑才是最好的效果。因为,其实人体的每一块肌肉都是相连的,比如你再扭脖子的时候,屁股上的肌肉可能也被带动了,只是它的变化非常微小。但人体角色的真实感正是由这些细微的变化体现出来的。

PSD论文 https://www.scribblethink.org/Work/PSD/PSD.pdf

作业

作业官方链接:https://github.com/yvpengli/GAMES105-HW/tree/main/labS

LBS:

    # M是关节数量,N是顶点数量for n in range(vertex_translation.shape[0]):x = np.zeros(3)for j in range(4):m = skinning_idx[n][j]w = skinning_weight[n][j]r = (T_pose_vertex_translation[n] - T_pose_joint_translation[m]) # 因为是T pose,所以Q为单位矩阵x += w * (R.from_quat(joint_orientation[m]).as_matrix() @ r + joint_translation[m])vertex_translation[n] = x

以上代码只能跑到3.3FPS

LBS优化:参考大佬的作业 https://github.com/DIOYF/GamesPersonalHW/blob/main/games105/LabS_task.py

这个作业要考虑和解决的问题太少了。 在工业上,LBS还需要考虑bind pose、处理法线和贴图的更新、考虑GPU和CPU的特性取舍、考虑PC端和移动端的性能取舍。

如果后面有机会我还会再写一篇蒙皮算法的博客。(又挖了个猴年马月才能填的坑


http://www.ppmy.cn/embedded/160380.html

相关文章

Java中JSON和对象的相互转换

Jackson jar包下载地址:https://repo1.maven.org/maven2/com/fasterxml/jackson/core/ Person p new Person("aaa", 18);// 创建ObjectMapper对象om ObjectMapper om new ObjectMapper();// 将对象转为JSON String s om.writeValueAsString(p); Syst…

构建高效Facebook广告矩阵:精准营销与广告投放的全新策略

随着社交媒体广告成为企业营销不可或缺的一部分,Facebook作为全球最大的社交平台之一,已成为企业营销的重要阵地。在Facebook上成功的广告投放,往往不只是依赖于单一广告,而是通过构建一个精准的广告矩阵来提升品牌曝光、增强用户…

网络安全风险量化值 网络安全风险控制

网络信息安全管理要素由网络管理对象、网络威胁、网络脆弱性、网络风险、网络保护措施组成。 由于网络管理对象自身的脆弱性,使得威胁的发生成为可能,从而造成了不同的影响,形成了风险。 网络安全管理实际上就是风险控制,其基本过…

记录 | WPF基础学习Style局部和全局调用

目录 前言一、Style1.1 例子1.2 为样式起名字1.3 BasedOn 继承上一个样式 二、外部StyleStep1 创建资源字典BaseButtonStyle.xamlStep2 在资源字典中写入StyleStep3 App.xaml中写引用路径【全局】Step4 调用三、代码提供四、x:Key和x:Name区别 更新时间 前言 参考文章&#xff…

【Docker】未来已来 | Docker技术在云计算、边缘计算领域的应用前景

欢迎来到英杰社区: https://bbs.csdn.net/topics/617804998 欢迎来到阿Q社区: https://bbs.csdn.net/topics/617897397 📕作者简介:热爱跑步的恒川,致力于C/C、Java、Python等多编程语言,热爱跑步&#xff…

《ISO/SAE 21434-2021 道路汽车--网络安全工程》标准解读

1 范围 略 2 归一化引用 略 3 术语定义 相关项: 实施车辆级功能的组件或组件集; 例如 安全气囊打开系统 组件: 逻辑上和技术上可分离的部分;例如 微控制器 资产: 具有价值或对价值有贡献的对象;例如 密钥 网络安全…

Vue canvas画图画线例子,数据回显与隔离,点拖拽修改

组件 <template><divstyle"display: flex; height: 342px; width: 760px; border: 1px solid #000"><divstyle"position: relative; height: 100%; width: 608px; min-width: 608px"><canvasid"mycanvas"ref"mycanva…

DeepSeek各版本说明与优缺点分析

DeepSeek各版本说明与优缺点分析 DeepSeek是最近人工智能领域备受瞩目的一个语言模型系列&#xff0c;其在不同版本的发布过程中&#xff0c;逐步加强了对多种任务的处理能力。本文将详细介绍DeepSeek的各版本&#xff0c;从版本的发布时间、特点、优势以及不足之处&#xff0…