GAMES 图形学系列笔记(三十三)

GAMES105-计算机角色动画基础 - P7:Lecture06+ Learning-based Character Animation (cont.) - GAMES-Webinar - BV1GG4y1p7fF

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

ok好那我们就开始上课了,现在是诶还有一分钟哈哈,不过时间也差不多了,对我们今天是啊games 105的第七节课,虽然是第七节课,但实际上我们讲的还是第六节的内容,因为这个上节课我们还是还是上了111。

一部分内容,虽然说我们这这节标题是learn based learning,based current mation,但是我们上节课讲了大部分内容,其实是相对来说不是基于神经网络的啊,角色文化。

而是主要是基于一些相对来说稍微早一点的,这种工作,主要是基于一些统计模型的,特别是基于高斯模型的这种呃,这种对运动进行建模,然后对运动进行生成的一些一些技术,当然那些工作就是说虽然是在我们展示过程中。

就是我们这个论文的展示,其实有很多比较好的效果呃,但是实际上在真正应用应用方面,其实还是有很多的困难,因为特别是像高斯模型里面有很多超参数,这些超参数在使用的时候,通常很多时候是需要手工去进行设置的。

这个其实会带给我们的使用,带来非常大的一个困难,但我们其实也是近2年啊,看到一些新的工作,其实带来了很就是特别是对动画方面,其实带来很多的这种进步啊,我们也看到一些新的方法,实际上从这个实用性上。

要比以前的这些方法要好很多,因为我们发现a红方只需用那个pytorch,写一个神经网络,然后用一些数据训练一下,然后就能得到还是不错的效果,那这个其实是我觉得是比以前的方法,要好好一点的地方。

当然为什么我们讲前面的方法呢,实际上我们我我个人是觉得,就是实际上像这种方法,就是他的思想就是基于这种基础的这些想法,其实是是一致的,只不过我们换了一种另外的工具,把同样的这样一个东西把它表示出来。

那我们今天主要讲的内容其实是啊,基于这个,动画的这样一个话题啊,当然我们今天主要是稍微多讲一讲,关于这个基于神经网络的呃,一些新的这些这些这些方法的一些简单介绍,那当然我们这个作为这门课的要求来说。

实际上我们也不会说,要求大家去真的去训练一个神经网络,这个其实稍微有点有点有点有点多,但是呢当然如果大家有兴趣的话,我们今天只是讲一讲一些论文的一个呃,大概的想法,但是大家有兴趣的话呢。

其实最好还是去读一下论文啊,当然也可以,其实最近很多的论文,有一些比较好的这种博客呀,或者知乎的这个帖子啊,或者解读啊,其实讲的也是很不错的,我觉得也是可以给大家一个很好的,这样的一个印象啊。

那当然关于我们的第二次实验啊,第二个作业大作业,第一个大作业其实已经交完了,那第二个大作业呢,我其实看到助教今天已经准备好了,我们应该今天晚些时候就会放在了,我们的那个github上。

我们的这个就提醒大家有这样一个作业啊,然后也是欢迎大家继续啊挑战啊,因为这个就是有一部分涉及第一个啊,作业的部分呢,我们可能就直接给答案了,因为呃因为就假设大家已经会写了。

然后当然有一部分新的内容是否涉及到我们,前面,主要是前面前面关于数据的这部分的方法,其实就内容相对少一点,ok那我们开始主要讲今天的内容,我们今天内容其实比较少,就是因为这个预告里我看到了。

另外一部分是关于这个蒙皮啊,但我其实可能因为今天一方面是过时间关系啊,另一方面也是这个进度安排的问题,呃所以说我们今天不会讲蒙皮的部分,然后蒙皮和这个嗯人脸动画的话,我们会放在下一节课去去做简单的介绍。

当然还是说我们这边这门课,主要是讲角色动画的,就是其实主要还是讲骨骼动画嘛,所以说蒙皮的技术相对来说,我们只会介绍一些基础的部分啊,这是下节课的内容,我们这节课,决动画的第二部分。

那时间上节课我们其实也是稍微提了一下,我们的目标是什么,我们其实还有一专门,有一节是讲基于数据的角色动画,那当然这个区分其实没有那么严格了,它其实也是基于数据的,因为我们都从数据里去学一个模型嘛。

那当然我做这个分,我就是在我来说,可能把这两个分成两个不同的部分,主要是在于说基于数据那部分呢,我们着重于是说对于数据的一个重放的一个重,组的这样的一个一个操作。

比如说非常典型的motion graph,它是对一些动作片段的一个重组,那还有像比如说这个motion matching motion martin,其实它也是一个重组,但它重组的力度会更低一点。

它不是一个motion clip,而是一个motion frame,我们其实上节课也是强调过,就是说啊,它不是对数据的一个简单的一个重组连接,这个模型是什么呢,我们可以从统计的角度讲来说。

就说我们给了一些数据,这些数据点,那这些点每一个点代表一个动作或者一段动作,那我们有很多个这样的动作之后呢,我们可以假设这些数据是从就是它分啊,遵从同样的一个概率分布,这个概率分布是什么意思呢。

其实简单理解就是说它代表了一个动作,是真实人能做出来动作的概率,那我们去上节课有一个例子,就是说如果说我们随机做一个动作的话,那其实你这个人会乱飞,就完全看起来不像一个人,或者说我们大家做第一次作业的。

这个love一的那个ik,你会发现,其实好多动作,你看起来不像是一个真的人会做的动作,所以这都是一个不真实的一个结果结果,那我们如何来判断一个真实,那我们是假设真实的动作,它是满足一个概率分布的。

那就是这个概率分布函数,就代表了他这个动作是真实的概率,那当然这个概率分布函数我们是不知道的,我们其实是没有办法,因为它很复杂,给出这样一个东西,那我们就只能通过一些数据,我们给出大量的数据之后。

我们希望能够学到这么一个概率密度函数,这个概率密度函数,当我给出给他一个新的动作之后,比如这个动作用x来表示,那么这gala密度函数能够告诉我们,这个动作是一个真实动作的这个可能性。

其实我们关于概率的部分,这部分的这个用的这个语言,其实是非常不精确的啊,就是说嗯,就是说实际上我们应该我们讲解的过程中,其实主要还是通过一个啊,概念性的这样一个介绍啊,说明说明这是一个问题。

但是实际上这个数学上,其实这个公式可能不是那么精确,只是但这也是稍微提醒大家一下,那当然这里边其实我们刚才也提到,就是说这里边每一个我们给出了若干个数据点,很多数据点,那这里每个点呢。

对于我们这一个特定的问题来说,它其实代表了一段动作,一段动作是什么,一段动作,就是说其实想一想,我们刚刚最开始讲那个b位置,讲那个动作捕捉,讲这个动作的表示,我们其实说动作或者一段动画。

它其实是一系列的真一系列的姿态,在时间上排列起来,形成一个很长的一个这么这么一段序列,那这样一个序列其实每一个这样一个块,就这一个列其实是一个向量,就这基本整整体来说,我们可以看成一个矩阵嘛。

那每一列式也是一个向量,那个向量代表了一个姿态,那这个姿态其实有很多种不同的表示方法,比如说我们常见的,就比如我们在讲变位置的时候,我们把它表示成根关节的位置,加上每个关节的旋转。

或者每个关节的朝向构成的这样一个向量,它朝向我们可以表示成比如说关键旋转啊,比如说可以表示成欧拉角,或者表示成这个轴角,或者表示成6d呃,向量这样的形式,当然还有其实一些其他的形式。

我们其实这个姿态也可以用,只用关节的位置来表示,实际我们看到很多相关的工作,他们其实是用位置来表达一个啊姿态,就比如说我做出一个举手的动作,那么其实我可以算一下我的肩膀,我的手腕每个地方在哪里。

那他整个把这个位置叠在一起,写成一个向量,那其实代表了一个姿态,那当这两个这两个表示其实各有各的优缺点了,其实我觉得主要是像,比如说你基于位置的表示的话,因为比如说我用驱动一个虚拟角色去运动。

比如说用蒙皮绑定上去,那我通常来讲是需要知道关节旋转,我才能把那个角色给驱动起来啊,这样的话如果说我只是计算位置的话,那我们其实还需要算一个ik啊,把我的位置再转化成关节的旋转。

那如果说我们只有关节旋转的话呢,其实关节旋转它没有一个全局的位置信息,大概在什么时候会有一些问题呢,比如说我需要把两个手放在,比如让手拿一个杯子,或者需要你的脚在走路的时候,你需要在地面上。

或者说比如说两个人一块走啊,比如两个人握手,那我需要两个人的手需要在同一个位置,那这个时候你用关节旋转的话,你缺少一个对位置的一个一个很好的一个计量,那这个时候也会带来一些问题,但这个确实不能。

但实际上从效果来说,可能这两种方法呃,在使用上来说可能是差不多的,就只是说他们俩各自有一些可能的优缺点,但不管怎么样,我们把每一个姿势表成一个向量之后呢,那其实一个动作,那其实就是就是一系列向量构成的。

这么一个这么一个这么一个长条的矩阵,那当我们前面提到的,我们的目标目标是学到一个概率,密闭的函数或者概率分布,那这个概率分布呢,它可以对每一个动作表示大写的x,那每一个动作判断它是不是一个合理的。

这样一个一个人能做的一个动作,那当然实际上,因为我们知道这个其实它本质上等价,于是说我判断这样一个呃一组动作,一组姿势的组合是不是一个合理的组合,或者他其实就相当于这个所有这些姿势,因为每一个姿势。

我们可以认为它是一个呃随机变量,那其实我们其实是判断说整个所有这些姿势的,随机变量的一个一个一个一个联合分布,它是不是一个合理的这样一个值,当然这个除此之外呢,我们其实通常还有一些额外的一些条件。

比如说比如说我们想知道一个,比如说告诉一个人,你往左走,那我其实想要知道这个他这个人做出来的动作,是不是在向左走,同时又是满足人的这个这个姿态,那除此之外,其实人还有一些其他的一些一些。

我们无法很明确的表达了一些一些特征,比如说比如说老人走路,你说什么样的,像是老人走路,那其实这个老人走路就是一个老人这件事情,时间是一个是一个约束,就是我们其实是希望我们生存的动作。

是在这样一个条件之下得到了一个很好的动作,所以说实际上这个带来的是一个在统计,概率上来说,是叫一个叫应该是叫做这种条件概啊,就是条件概率密度,就是他的条件是说我们比如说你要向左走,或者说你是一个老人。

或者是一个儿童,那其实他可能走路,或者我高兴的时候,或者是一个悲伤的时候,那我其实可能做同样的动作,我的代表的这个姿势是不太一样的,那这里面其实我们会基于一个条件,那个条件是用一个z来表示。

那等会来讲它可以代表一些需要用户控制的量,比如说告诉你该往哪个方向移动,或者是一些控制用户不是很控制的量,比如说当前角色的一些状态等等等等,ok,那当然我们前面只是说,我们训练了这样一个模型。

那这个模型可以去判断一个动作是不是合理的,那我们知道,其实如果说我们有一个概率密度函数,那我们其实是可以,在这个基于这样一个概率密度函数,它所代表的这个概率分布,我们去采采样。

那我们如果说我们这个概率密度函数,确实训练的很好的话,那我没采到一个样本的动作,应该就是一个合理的动作,并且它能够满足我提出的这些啊前提条件,那在这个时候下嗯,我们的这个这个采样一个过程。

实际上我们可以写成一个函数映射的过程,就是我们给出了一个控制条件,比如说一个控制参数,或者是一个,比如说一些隐含的一些当前角色的状态,那么我通过这个他这个这些条件,去生成一段动作。

那其实它代表了一个函数,它的这个函数就是把这样一个控制信号,映射成一系列的姿态,来形成一系列的动作,那当然这个方向实际上我们前面解释说,ok我们是把一整个动作,把动作的一整体看作成一个变量。

或者看到一个x,但通常来讲,实际上我们可以把它看成,从另外一个角度去看这件问题,就是说我们知道一个一串动作,就是一系列的姿态的这样的一个组合,那实际上我们同时比如我们正常往前走的时候。

我们知道其实我当前的或者我下一个时刻,我的姿态我其实是怎么说呢,我其实是从我基于我当前的这个,或者我过去的一些姿态来决定的,或者怎么说呢,就比如说我当前是在在教室里坐着。

那我下一下一秒肯定不能跑到外面去,因为这个这个有时空的一个距离的限制,那这种情况下实际上就说明什么呢,说明的是为了实现一个比较好的一个,或者比较自然的一个动作,时间是要求什么呢,要求是说我每一个姿态。

在在我们前面已经走过的这些这些姿势之后,他的下一个姿势是一个合理的姿势,所以首先这个从这个条件概率的角度讲述,就是说,实际上我们本质上还是希望,能够让我们每一个姿势,因为我们所有的姿势构成一个动作。

我们让所有的姿势构成一个动作,它整体的一个这个联合分布,是一个合理的一个动作,那这个基础之上呢,实际上我们可以应用一些这种概率,概率论上的一些技巧,比如说我们可以用这个乘法原则,或者叫这个链式法则。

我们可以把它写成改写一下形式,可以成一个大概类似于这样的形式,那这个形式里其实可以看到,就是说除了第一个第一帧这个姿态之外,后面的每一帧就后面每一帧,比如说t第七针,它其实是由前面的若干针共同来决定的。

或者说在具体点,就是说比如说我下一只给我往前走,我下一步的这个状态其实是由我当前这个状态,一定程度上决定了,当然还有一些其他的条件,就比如说我现在往哪走,比如说我们的这个身体的状态等等。

所以对于这后边这部分来说,就是后面这部分其实它告诉我们是一个概率,也是一个概率分布,但是一个条件概率,他条件概率就是说当我们给出了过去若干针,我的这个角色姿态之后,我当前这一帧它是一个合法合理的。

或者是比较自然的一个姿态的这样的一个概率,那同样的,如果说我们要知道这个概率,反过来我们也希望从它里面进行采样啊,其实这个过程我们同样也可以把它表示成,一个啊一个一个一个一个函数的形式。

这个函数就是说它根据它的输入,就是过去若干帧的这样的一个姿态,加上一些我们额外的一些控制变量,或者是一些隐变量,然后呢他们能够去算出,根据所有这些信息,算出我下一帧的这个。

这个下一时刻的我的状态应该是什么,那当然这里其实还有一个条件,就是我们这里在这里,其实这个这个假设是比较泛化的,就是说实际上我说ok,我下一步是跟我过去20年所有的动作都相关。

那这个想想其实完全是不合理的,因为正常来讲我做动作,我往前走,我做一个决策,可能也就两秒之前或者一秒之前到了,就已经非常非常非常非常多,是已经非常多了,所以实际上通常来讲,我们在做这种动作合成的时候呢。

我们其实会假设我们这个动作,它有一定的这个马尔可夫性,就是马尔可夫性的说明是什么呢,就是说马可夫性是一个,就是就是所谓叫无记忆的一个一个性质,就是说我们下一时刻,比如说x t。

他的状态是可以完全由过去一帧的状态来决定,或者再再再再准确点说,就是如果说我们知道了当前x t减一,当前角色这个姿势,那么角色下一时刻的姿势就不会受到过去,任何一个时间则是受到影响。

就是他只跟上一帧的有关,然后他不会跟这个再往前这个时刻有关,那如果说我们假设这个动作有这样的,马可福星的话,那其实这个整个的这个概率密度函数,其实可以再化简一点。

然后而且我们需要去求的这个生成的这个函数,这个f其实它的形式也会更加简单一点,就是这种情况下,我们其实这个时候f它带来的含义,或者这个p代表含义,就是说我给出过去一帧的姿态,我下一帧是什么姿态的。

它是它是真实的这个这个概率,然后或者下面这个这个app其实代表的是说,我根据我当前的一个姿态,加上一些控制的信号,我去计算下一时刻,我的角色的姿势应该是什么样子,那这个过程会不断的叠加了。

因为如果说我们算出下一时刻的姿态之后,如果我们算出下一次他的角色的姿态之后呢,我们可以通过当通过下一时刻继续叠加,算出再下一个时刻的这样的状态,我们就可以不断的叠加下去。

那这样其实可以生成一个完整的动作,ok那当然这其实就是我们这通常来讲,我们会关心的两种不同的这种看法,一种方法就是说我们把动作整体放在一起,我们其实不,我们先暂时就是认为这个就是我我用这个app。

我们给出一些变量之后,它可以一次一次性的生成整个的动作,那这个过程实际上两个动作相邻动作之间,两个相邻帧或者相邻时刻,这个姿态之间的关系,其实是隐含在这个app里边的。

所以时间很现在很多工作有一些工作吧,其实它是基于这样的一个这样的一个表示,他可以直接生成所有动作,另外一种就是刚才我们说到了,就是说我们认为这个动作,可能他只跟过去一些相关。

那我们其实可以把它写成一个这样一个,类似于条件密度函数的一个形式,那接下来呢我们其实可以知道在生成的时候呢,我们可以只根据当前这一帧,然后加上一个条件来生成下一帧,那这个时候f其实相当于是显示的。

对这个相邻两帧之间的关系做了一个,做了一个建模,那这是一个另外一种方式,但其实通常来讲,对于我们这个实时的应用来说,比如在游戏里边,那通常来讲我们其实希望的是后面这一种,为什么呢。

因为用户的输入这个z还是经常会发生变化的,我就推摇杆,我向左推,右向右推,那我其实是用户时它可以随时改的,那这个时候我们需要怎么去生成一个新的动作,那这个其实是希望他能够立刻响应,那就是说我可以。

我可以利用这样的一个形式去上生成,那前面这个在什么地方很有用的,比如说我我我给你一句话,或者我给你个剧本,我希望你爱了个剧本,生成一段表演,那这个时候实际上相当于这个,我其实这个交互是不需要实时进行的。

那这个时候如果这种前面这种表示,其实会更好一些,为什么呢,因为后面这种表示实际上它生成这一帧的时候,他其实完全没有考虑未来的一些状态,这个其实也不完全对的,为什么呢,因为比如说我要往前走。

或者前面我看到前面有地上有个坑,那我其实在这个离那坑很远的时候,我可能就要做一些决定了,比如说我该迈哪条腿,或者说我可能要避开那个坑,那这其实是未来的一些信息,这些信息在这个后面这个模型里。

其实是他自己是不带的,我们需要加一些其他的方式把它引进来,那如果前面这个模型的话,相对来说我们会容易把它放进去,因为它是考虑整体的一个一个表现,那当然后面这个模型呢,实际上我们它我们可以通常可以。

把它叫做一个这个自回归的模型,因为本质上自回归嘛,它其实其实的含义就是说用过去的信息,用过去的若干帧的这样的一个变量,这样的一个状态去预测,去计算下一时刻的这样一个状态,那当然其实我们就是最简单的。

如果说我们考虑这个马可夫性的话呢,其实他的这个函数的表现形式,其实就是这个样子,其实非常简单的,就是刚才我们刚才所说的,我知道当前帧的状态,这样一个变量加上控制信号,然后生成下一帧的状态。

那当然这个控制信号我们刚才提到的,就是它可以是用户输入的控制,也可以是一些我们用户不能很容易去定义的,一些演变量,比如说它的心理状态,他的身体状态等等等等,这些都可能不是用户控制的。

然后呢这个f其实是这样的一个映射,当然我们可以暂时先把这个z忽略掉,我们就只考虑这样一个f的映射,就是它的就是含义,就是说它根据当前的这个x,根据刚才这个x去预测下一帧的这个x。

那这是一个非常基本的一个函数,那刚才我们提到了,实际上我们的这个训练过程是说,我们给了一系列的这样的一个样例动作,那就说让一个人在一个动补空间里,然后我让他自己随便做一些动作吧,你做个20分钟一个小时。

只要你累的不行出来,那我们就是他有了大量的这样一个动作,那这个动作构成了一个集合,代表了我们这个训练集,那当然对于我们现在这个训练来说,实际上我们其实并不关心整个动作是什么样子。

因为我们只关心xt和xt演绎,他们俩两两这一对的这个关系,所以实际上我们关心的是说,我们把所有动作拆开,我们只看前后两帧,那他们其实构成了一系列这个这个这个元组,二元组。

那其实这二元组就是前后两针的这样的,一个关系,那我们是通过希望能够从这里面去,学到一些信息,我记得来说实际上就是说什么呢,这个这个函数f它是能够保证,在这个二元组上保持成立。

也就是对于这个我们所有的一个训练集里面,数据不如我们这所有的采集到这个动作,我都可以保证使得f x t减一等于x t,那在这样的一个基础之上呢,当我们给出了一个新的xt减一。

然后它能够预测出一个合理的xt,这其实是我们的训练的目标,那这个其实看起来很很熟悉啊,回想一下,我们以前之前讲那个关键帧动画的时候,我们其实挺像啊,说到了同样的问题,那关键帧动画我们说到什么问题呢。

就是说我们给出了一系列的关键帧动画师做的,那我们希望能够去在这个关键帧的基础之上呢,算出关键帧之间的那些时刻的姿态,那当时我们其实是用到了一些差值的算法,比如说线性差值,比如说这个样条插值。

比如说这种多项式插值,那当然差值的好处,在当时这个差值就是其实还是挺,用起来是比较方便的,当然有一个前提条件是什么呢,就是说相对来说,因为它的它是在时间上的一个一个一个差值。

比如说实际上我的自变量的维度是比较低的,我其实只有异味,那相对来说,一般来说我用差值其实算起来还是比较方便的,但是对我们现在这个问题来说,我们这个姿态的空间通常来说维度是比较高的。

但是这个比较高其实怎么说呢,看你怎么看了,因为从我们角度来说,因为比如说一个人,那可能你的关节数,我们会控制的关节数可能也就20左右,那你这个整体的自由度可能也就60左右,五五十到60。

那这个其实你要说高吗,其实对我们来说是很高了,但可能从有些领域来看,这个这个作用已经非常低了,特别是比如说做做这种几何处理的啊,他们看这个他们一个模型大概上千个点,那就几万个自由度。

那当然看我们这50多个其实比较低的,但实际上50多其实已经很高了,因为你很难去描述,很难去想象这个50多位它是什么样子的,那当然还有一些其他的方式去去做这种高维的,这种差值的。

就是高或者高维的这种这种fitting,这个这个这个叫拟合对,就比如说我们像高斯过程,我们其实上节课讲了一些关于这个用高斯,高斯分布,就是基于各种比如高斯过程呀,或者是混合高斯呀。

其实本质上他也是在做这种做这种差值操作,其实对应的有点像是ibf这样的东西,但是现在比如说我们很常用的一类方法呢,就是所谓的神经网络来做这个拟合,因为本质上来说,其实它就是一个高维的一个拟合过程。

但神经网络是什么呢,我其实稍微简单介绍一下,但是我相信很多很多很多同学,在其他地方也看到过了呃,那神经网络,实际上它是来自于一个对一个真实的这个,神经的一个,或者大脑的这样的一个一个一个一个描述。

或者基于这样的一个生物学的这样一个结构,的一个一个启发的一个结构,那我们知道一个神经元,那高中生物其实也都学过一个神经元,那其实有很多这种树图,然后会有一个轴突啊,当然这个这个具体名字我也记不太清楚了。

好像是大概这个样子,然后这个数图其实是,比如在大脑里有很多很多神经元,这个神经元的互相之间会通过这个视图进行连,接,我进行传递,然后比如说他隔壁的神经元,会把一些信号传递到某一个视图上。

然后另外的神经元可能把另外的信号,传到另外的视图上,然后这些数都接到这些信号之后呢,其实会这些信号会这些刺激会产生积累,那通常来讲,对于这个中间神经来源来说,当它周围所有的这些数图上的这个刺激。

积累到某一个阈值之后呢,它就会被触发,它会发出一个信号,那这个信号可能是通过数度传出去的,也可能通过这个轴突传到后面去,然后传到另外一个神经元,那这时候神经元这个它的某些数据。

接到了这个神经元前面那个神经传递的信号,然后他再去重复刚才这样一个过程,这其实是这个一个正常正常的一个人啊,就是生物体的这个神经元的一个一个基本性质,那对于我们这个人工神经网络来说。

实际上它的基本单位也是这样一个神经元,那当然这个节神经元它本身就有若干个输入了,每一个数其实是一个片,一个一个一个标量,然后每一个标量其实代表了在这个树突上,对这个神经元进行了刺激,那当这个刺激上。

实际上我们也不是直接把它加进去,而是通过一个权重把它加进去,然后这个阈值其实是由中间这个西格玛这样,一个函数来来给出,也就是说其实sigma是,我们通常很快会把它叫做一个啊,叫一个积极反函数。

他意思就是说可能对于不同的基本函数来说,它会带带带带有不同的性质,但它带一个最基本的就是说当我前面这些量,前面这个总的刺激的这个总和,加群和超过某一个阈值的时候,他会把这个输出给给输出去。

那当然可能有其他的结构函数,可能会他给这边有一些有一些很小的数的时候,也会输出,那这个区我们几个函数是定义的,但总体来说,这么一个神经元,其实代表了一个一个一个具体的函数呢,其实就是前面若干问。

所有输入的一个加权平均和,然后加上一个这个这个bias,这样一个这个叫什么来着,bias应该叫,叫一个偏移向量,然后通过这样一个这个一个激活函数,然后得到最后生成的值,那当然我们其实对于神经网络来说。

我们其实有大量的神经元,然后通常来讲,那么每一个神经元其实代表了一个标量,比如说xy是两个向量,那它其实输入里边是有a就有n个神经元,然后输出哎呀我怎么全是y一了,这个这个这个写错了。

应该是输出是y1 ,然后每一个神经元从输出层的每一个神经元,其实都会跟输入层的所有神经元进行连接,然后它所带来的这个输出时间,是跟前面这个一个神经元的那个结构是相同的,那当然比如这里有n个神经元。

m个神经元,把它总体的这个输出方式,其实我们也可以这个形式化的,写成这样一个形式,就是实际上是因为每一个对每一个神经元,它都是一个加权平均加权求和,那总体来说时间是一个啊。

可以写成一个就是把每一个深渊写的,写一个向量之后呢,那其实是一个举人相承的一个形式,那同样的它每一个向量,我们需要对这个把它加上一个啊激活函数,来去算出真正的这个输出的值。

那当这个神经网络其实我们可以增加很多层了,那全是写成一了,ok我们神经网络其实可以有很多层,然后每一层实际上都是从前一层的,所有的神经元接收一些信息,然后把这个信息的传递给后一层的所有神经元。

那比如说像这样的是,其实一个非常简单的一个三层的一个倾向网络,那其实每一层比如第一层,它对应的神经元的这个权证是w1 ,然后偏移是b1 ,然后第二的这个全称是w2 ,平a是b2 ,然后第三个是以此类推。

那对于这样一个神经网络来说,实际上它所代表的一个函数,它所代表的一个函数,可以写成一个这样的一个形式,就实际上是相当于最后一层,首先最后一层的激活函数,是由前一层的这个输出乘上w,然后加上这个b。

然后前一层的输出呢又是在前一层的这个输出,整个w加上b然后依次往前迭代,所以其实本质上来说,它是一个从后往前的这么一个,这么一个复合函数,那当这个复合复合函数里边,首先这个西格玛就是这里的奇偶函数。

通常来讲是我们预先指定的,而且实际上很多情况下他是选择哪一个呃的,影响没有那么大,就是我用一个rio啊,或者是用一个或者用一个什么sigmoid的,其实影响你说有些是有的,但是影响没有。

那没有那么significant,但是这里面其他的几个部分,这个b和w就是这个w代表什么,代表是从前一层到后一层,我在每一个方向上加了权重,然后再比如说b是我的一个基本的基底,的一个bios。

就是这个偏移向量,那这些参数其实会决定了,我给给出一个自变量x之后,我的输出y应该是多少,或者可以把它再稍微简化一点,就是实际上对于神经网络来说,我们其实先不用关心它具体是一个什么结构。

因为刚才我们说的是一个非常非常基本的一个,前向神经网络的这样一个结构,但是不管哪一种结构的话,神经网络它的基本标准配置,就是我每一层都会有一个w,然后每一层都会有对应的b,哪怕是我们很复杂的。

比如说像是这个cn这种结构,它其实本质上也是一个w和b的这样一个形式,那这些w和b比如这里有三层,那就是三个w1 w2 w3 和三个b,他们共同的决定了,我这个f对于某一个输入x之后,它输出y是多少啊。

其实这些w和b其实就对应,于是这个神经网络的参数,所以再回到我们前面这个问题,这样的一个过程,实际上就是说在我们给出了这样的一些一系列,这样一个训练数据之后,我们如何去确定一些这个参数。

我们把这些所有的参数总体来表示,上一个叫做一个用c来表示,我们其实是想要去确定这个theta,然后这个theta首先它能够保证,对于这我们给出训练数据里的这个xt和xt,x t一和xt。

能够满足满足我们这样的一个输入关系,同时呢对于一个新输入的一个x,我们也能够预测它的这个对应的这个值,但当这个东西怎么训练呢,实际上本质上来说,我们其实还是去求解一个优化问题,那这个优化问题是什么呢。

就是说我们给出了一个这样的一个训练集合,那这个可能是来自于序列的动作,这个动作我们是一个人在,可能在一个地方走了20分钟,然后我们去找到希望,去找这么一组参数,神经网络的每一个每一层的各种参数。

然后这个参数能够使我的在训练集上的误差,尽可能的小,那这个误差表示什么呢,这个是这个前面这段啊,前面这一半代表是用来基于当前的x对,这个s t建议啊,然后这个预测跟我真实的只做一个差,那其实代表了误差。

那这里其实我只是简单写了一个二,一个一个范数,但这个范数是什么,其实很多时候在不同问题有不同的解法,比如很多时候我们可能写成一个二范数的平方,然后很多问题里边可能是一个一范数啊。

有些问题可能也许是一些其他的,比如可以写一个无穷范数也是有可能的,那定义好这样一个优化的问题之后呢,那我们其实回想一下,我们讲ik的时候,其实已经用到了这个优化问题,我们本质上来说是希望去求解,就是现。

但是相对来说这个问题,因为这个app本身是一个很复杂的函数,虽然说我们这个神经网络看起来,这个结构表示比较straight,forward比较直接,好像一眼就能看到去,但是因为它对应的这个函数的形式。

具体这个形式其实会非常非常复杂,所以通常来讲就为了求解这个优化问题呢,我们还是很常用的一类方法,就是用这个所谓的梯度下降方法,然后其实特别是对于这种数据量很大的情况下。

我们一般都采用的是所谓的随机技术下降,所以t度下降,它基本是它本身还是一个循环循环更新,这个fa的这个过程就是有点像我们ik的时候,那个那个那个jcb那a的方法,当然他这个他这个他只是说每一次。

因为我们这个数据集,原来数据集可能是很大的,所以每次我是只从数据里选一个小的子集,那这个子集它一个batch,对我们一般说这个batch size,我们这个这个batch的大小。

其实代表了我从这个子集里面随机选了多少个,多少组这样的数据,然后对于每一组数据的话,我们可以计算一个近似的梯度,因为我们这个区真正的梯度,其实理论来说应该是所有数据的这样一个求和。

但实际上我们只能现在只是取了一部分,所以说我们只能算是他的一个近似的梯度,那这个梯度其实公式是一样的,只不过我们是只是考虑,我们采取这个bg里面的所有的所有的点,那接下来呢实际上我们算出这个梯度之后呢。

因为我们其实梯度的方向代表什么,我们前面也提到了,对于一个连续函数来说,它的梯度的方向代表了它增长最快的方向,所以说为了能够接最小化这样一个啊,以后优化目标,所以说实际上我们是需要减掉一个。

就是沿着梯度的负方向,然后乘上一个步长来进行这样的更新,那通常来讲这不长,一般来说不能太大了,因为这个太大就会带来这个优化不稳定的问题,那当然这里其实一个很关键的部分。

就是说这个其实就是这个这个梯度怎么算啊,我们其实i k这方面的方法里面,最麻烦的一个就是这个亚克比矩阵怎么算,那其实我们刚才接线也提到了牙科比决胜,如果一方面你是可以比对艾克来说。

一方如果你能自己想自己写的话,你可以通过比如用基于这个只要没水,基于这个几何的方法,用那个插值的方式去算,或者你不想写的话,诶,反正我们现在有很好用的这些,他们其实本质上来说就是可以帮你做这个。

自动帮你做这个微分,那对于神经网络来说,实际上我们神经网络其实有很大的一个特点,就是刚才我们也看到了,其实三层的神经网络,或者若干层的一层一层神经网络,它本质上是一个复合函数。

所以说你对这个复合函数里的参数求导,其实你是要用一个链式法则去做这件事情,那这个链式法则其实你再进一步的把它简化,就是那个那个求导过程,再进一步的这个归类一下,它其实就就会变成一个非常有效。

非常高效的一个算法,那这个算法其实就叫这个后向传播,bug provocation,当然我们这里不会讲,就不讲细节了,但是大概其实其实你是可以理解的,就是说back propagation。

就说后向传播,本质上是链式法则的一个直接的一个结论,那就是这里就是说那实际上我们大部分的,比如说这种事情啊,像pytorch torflow啊,其实大家都基本来说都是这些思路,就说你做这个后向传播。

你肯定是就是链式法则的这样一个,一个一个一个效果,ok那其实这样的话,就说我们其实已经给一些数据之后,我们其实可以通过这样的嗯,嗯这样随机随机退出下降,我们其实可以学到一个函数,那这个函数f。

它可以去根据我过去的当前的一个时刻的状态,去预测下一个时刻的这个状态,那这个过程我们其实其实有很多的这个,运动数据作为这个我们的训练数据了,比如说我先踩了一段动作,这个动作是向前走的啊。

这个图看起来很熟悉,我们讲那个motion machine的时候,其实用过这个图,ok那我们其实有一个一个动作数据,这个动作数据向前走的,然后我们其实因为我们这个人在这个房间里,随便的随便的跑动嘛。

那其实可能有另外一个数据,他是向左走的,那还有一个数据是向右走的,那我把所有这些数据都放在这个训练集里去,训练的话,你会发现出现什么问题呢,就说我比如说在某一时刻,这个人在这样一个状态。

那这样一个状态之后,我接下来我在数据里边发现他在接下来的状态,可能是有些数据是向左走的,有些数据是向上走的,有些注意数据是向右走的,那这个时候我的这个训练的结果,应该是向哪个方向移动呢。

其实你是无法判断的,就这事其实是一个一个所谓这个随机性问题,就是你的数据里缺少一些约束,在缺少约束的情况下,你会发现往哪个方向,都是都是数据里存在的一些数据,那这会带来什么问题呢。

就是说你很可能你最后学到的一个结果,是一个平均的一个动作,因为你实际你会发现,比如说你这个方向算了一个梯度,这个方向算了一个梯度,这个方向算了一个梯度,这三个梯度的方向加在一起来发现是个零。

那其实其实你最终学到是一个平均的一个方向,所以为了解决这个问题呢,相声我们还是需要一些,就是我们其实说的是,就说明如果你出现这个问题,就是有一些因素是你没有表现在这个x里边的,就是这些,或者再进一步说。

就说这个时候x t减一的xt不是一个单射,它是一个它需要加上一个额外的变量之后,它才是一个单色,那这个额外的变量是什么呢,其实有些是我们可以控制的,我们刚才提到,比如说我们知道这个角色。

我知道我的这个意识告诉我哎呀,我现在先现在应该向左走,那我接下来就知道了,那些他肯定是,这个才是我真正需要去预测的目标,那如果是向右走的,应该是另外一个是你可以预测的目标,那还有一些其他的一些因素。

我们可能很难去很难去建模,那这里其实关键就是说我怎么去找到一个,合适的这样一个z,这个进行其它,避免说我们这个这个这个啊,这个随机性问题所带来的这种退化的情况,其实有几个方有几类的工作。

其实主要是来它引入了一些额外的变量,来解决这个问题,ok那其实最有名的工作了,也不是最有名的,就是相当于是近2年这一系列工作的一个,最早的这么一个工作。

就是这个p f n就fafunction networks,那你座一座是这个nhold,这个当然是以前是那个他是那个他哭,他哭的这个学生,然后后来也是去了玉璧啊,最近好像又又又又换地方了。

然后当时他这个工作其实效果是非常好的,我可以学一个神经网络,然后这个神经网络,我其实只需要根据当前的状态加上一些呃参数,加上一个face的一个指标,我就可以生成非常好的动作。

但这个动作其实现在看来不一定不是非常好了,但至少从他至少从我们看起来啊,就是感觉这个动作首先看起来是reasonable,是一个可看起来是ok的,可以的,然后同时又可以有些响应,当然其实还有些其他。

它有一些各自有他自己的问题了,但是从那个时间,比如说2017年,这是2017款,2017年的工作,其实说实际上怎么说呢,就是在他这工作之前呢,大家其实也没有想到,或者没有人真正能够做出来。

是用神经网络给我训练一个模型,我就能实现这么好的一个动作,因为我觉得这些公司,其实在那个是非常非常有启发性的一个效果,就是他其实两个两个方面就是两两,其实我觉得当时就两个工作非常好,一个是这个。

一个是那个motion,matching,motion market,是一个非常实用的一个技术,那这个其实是代表了,ok,这个方向,其实是真的是可以可以做出很好的效果。

ok那当然这个我们可以稍微再多讲一点,就是它的一些那个底层的一些技术啊,就是说我们刚才提到了,就是为了能够解决这个随性问题,那我们其实也额外的引入了一些参数,来帮助我们解决这个问题。

那这里面其实有两部分,对于这个模式这个p f n来说,它两部分,第一个部分是一个控制参数,那这个控制参数相对来说比较好理解啊,就说比如说前面这个前面这里边,比如说这个人我推着摇杆。

实际上这个下面这个地面这条线,我从这个基于这个用户的输入来算出来,这个角色,他应该在未来走到什么位置的,这样的一个这样一个计算,那这个计算其实他没有用到任何神经网络,这就是一个啊手动设计的一个规则。

然后他把这个这个这些这个地上这些点,把这些点的位置作为它梳理部分,就是前面那个control parameter这个控制变量这部分,然后另外一部分其实也是非常关键的一部分。

就是所谓的face parameter,就是一个像像参数,就是这个相位参数,那实际上就是说这个思想,其实但这个思想其实也是有也是由来已久了,就是说这个其实在以前,比如在我们在做以前做运动控制的时候。

也有很多时候会用到相位这个概念,就是相位啊,就是说实际上它是一个怎么说呢,一个一个一个类比啊,就是有点像,因为相位,通常来讲,我们是讲三角函数里面的那个那个那个偏移,我们把它叫做相位。

但是很多时候比如人走路,比如一个正常人走路,就如果说你不做这种奇怪的动作,就是就是闲着没事就就在那走,那实际上你的动作是有非常强的这种周期性的,那这个周期性其实就是人走路。

比如说有一个状态是双脚都在地上的,一个状态是这个单脚在地,就是这个单脚支撑,一个状态是双脚支撑力,然后又回到单脚支撑一次,以此类推这样的一个状态,然后这个周期,那我们其实可以把它叫做一个这个不太周期嘛。

get cycle,那这个周期,我们其实它是一个不断重复的一个过程,如果说我们把这个周期本身定义成一个,0~1的这个区间的话,那其实我的相位参数可以定一个参数,来表示我当前处于哪个相位。

会处于哪一个这个比如说哪个,比如说如果说我定义右脚啊,左脚落地这一瞬间是零,然后右脚落地瞬间是0。5,然后再左脚落地的时候又是一,那它等价也是零,那我其实就构成了一个循环,那是循环的每一个比如说给出0。

3,那其实代表的是左脚着地,然后右脚可能在空中,这个这个往前摆的这样一个状态,所以时间如果说我们对于一个比较平稳的走路,那其实每个相位其实就对应好了,一个具体的状态的一个一个姿势,当然稍微小跑个题啊。

其实就是这里有一个收集到一个,走和跑的定义的问题啊,大家知道这个奥运会嘛有一个项目叫竞走,其实竞走一个非常重要的一个违例,就是双脚离地哈哈也就是说其实对于走路来说,其实它定义什么叫走路。

我始终有一个脚在地上,至少有一个脚在地上才叫走路,那什么叫跑步呢,我有一个时刻是双脚都离开了才叫跑步,所以说这个其实是稍微稍微稍微有点意思的,一个话题,ok那就像我刚才我说的。

实际上这样一个相位的这样一个参数,它其实是它这个范围我们是可以自己定义的,有可能是01,也可以是02,派也是零到派,这个企业我们我们我们从哪个角度去看它,但本质上它的一个性质是不会变的,就总的来说。

它是一个我们设定好的一样一个一个范围,就比如说我们我们可以说左脚着地,那一瞬间是零,然后到右左脚再次着地的时候是一啊,对内也是零,那这样的话构成一个循环,那比如说我们可以把右脚着地的一瞬间,变成0。5。

这个好处是什么呢,就好说,比如说我有些时候不是一个不是一个,一直往前走的状态,我可能一边走一边向转弯,那有可能这个时候,其实你两个脚落地时间可能是不均匀的,那这样的话时间它会带来一个。

就是它会自动的让我的动作,就是说虽然说这个角的落地时间不均匀,但是在这个时间这个这一小段时间之内,我在某一个相位,他的这个姿势是相对来说比较固定的,就是他这样的话,其实可以就是自动去生成我们不同这个啊。

就是就是说可以我们可以通过这个控制,我这个相位在真实,因为这只是相位啊,就是它并不是一个真实的世界,就是他真实的时间有可能是比如说左边走一步,左边这一步快一点,右边那一步慢一点,这是对应真实时间。

但对于下位时间来说,它是一个一个一个固定的时间,所以其实可以我们通过调整这个相位,和真实时间之间的相对关系呢,其实我们也可以调整,我们真正生成这个动作的这个速度啊,其实他某种程度上。

其实也影响了我这个动作的这个啊,这个这个这个类型,所以这是我们这个对于都不这个步子来说,一个相位的定义,但除此之外呢,其实p fn其实也提出了另外一个,非常重要的一个这个网络结构,因为他们也是试过了。

就说我直接把这个相位,比如最简单,我把这个相位就作为这个参数一部分,把它放看成相同的,等价的一个一个一个一个一个地位,然后我就直接训练一个神经网络,他把这两个东西作为输入,然后直接输入下一帧的状态。

其实这是他们就是实际上这个这个,但是他们也是做了一些实验,反正这东西效果不是很好,他们提出了一个新的方法,就是所谓的叫mix expert,其实mix expert这个想思路其实也是比较。

就是在以前也是见过的,他只是说他们把这个东西用起来,发现效果还是很不错的,那什么是mixed expert,就什么是这种混合专家模型,服装的模型,就是说我们正常来讲,这个我们输入是一个x。

然后给出一个通过一个神经网络或者一个函数,我就预测下一时刻的y,这是我们一般的神经网络,但是呢我一,但是如果说我觉得诶这个这一个神经网络,它的能力可能不够强,那我们其实可以考虑考虑另外一个模型。

就是我们可以有若干个这样一个神经网络,每一个神经网络都会做一个预测,或者有点像什么呢,比如说我去看病,我这个身上有个疑难杂症,然后看了1234,我看了十个专家,然后a专家说你是病a。

然后b专家你是个对a专家说,你这个这个就是一个感冒,你就是回家呆着就好了,然后避开b站,一看时你就要进icu了,抓紧时间住院了,然后再看一个c专家,然后可能每个专家会过一个不同的判断。

那么最终我的病是什么,那我可能是把所有专家的这个意见,做一个加权平均,那我可能就是又不住院,又不又不又不又不吃药,反正就是这样一个状态,但总体来说,这个混合状态模型大概就是这个意思。

就是说我们有若干个专家的网络专家的策略,他们分别给出相同的输入之后,他们做出一个不同的预测,然后这些预测呢,我可以通过某种方式把它结合起来,然后最终得到一个新的,这个我们最终的这个结果。

那这是混合专家的一个一个模型,那基本的一个常见的一个方式,就是说我们每一个状态是f,它都它都有不同的参数,非常比如说有了有n个专家,有大n个专家,然后我们可以把每个专家的输出。

用一个权重把家庭平均起来得到的y,这是一种专家过控模型,那混合专家模型当然还有另外一种,这也是p o n他们当时使用的这种方式,就是说叫他们叫这个waited blanded mix expert。

就是说实际上前面这种专家模型,它是把这个专家的输出作为一个模型,那后面这种呢,其实相当于说我把每一个专家的参数,把它做一个混合,混合了之后呢,把混合之后得到那个参数,我认为它定义了一个新的专家。

那这个专家其实相当于我,我我获得了以前所有专家的这个知识,那这样呢,我希望这样一个专家,能够对我当前的状态做一个更好的预测,所以你可以从公式的角度讲来说,它其实跟前面有点不一样。

原来是所有的输出做做混合,现在是说我把专家的参数做了混合,然后用它来进行预测,这是一个啊混合专家模型的这样的一个嗯,这样的一个一个一个形式,那回到我们前面这个pv的这个问题。

就是说它实际上它定义了这样一个face function之后啊,face function时间代表了我当前这个他是在走路,这样的一个这样一个固态的一个循环中的,哪一个状态,那接下来呢。

其实我们会认为我们这个专家的这样一个,混合的权重,它应该是由face来决定的,对当然这也是,那这个也是就只是我们的一个假设,我们认为假设说我们对于某一个状态,他应该就是由这几个专家。

应该用这种方式去混合得到,那当然这个对于这个pf来说,他们其实用了一个cubic plan的一个方式,来计算这样一个专家权重啊,就相当于比如说这是它有四个专家,那如果说比如说face在这样一个,比如0。

25~0。5,这样一个区间之内的时候,那我其实认为我的这个值是由c呃,1234这四个专家做一个cubic plan的这个嗯,kuma ros,就cut rom样条差值得到的就是我认为这四个点。

这四个专家的参数是这个样条,四个样条的这个差值点,那类似如果说这个five在这个位置,在这个位置,那其实他那个这个顺序其实要改变一下,那其实变成2341这样的一个顺序,他在前面的时候1234。

那这个时候2341,然后再往后的时候可能是那个c123 ,以此类推,所以这样的话其实就是构成了一个什么呢,就一方面来说,我这个角色,我当时这个角色,他在这个走路的每一个阶段的时候,我会用不同的专家。

我强制他用不同的专家来预测这个啊,我下一时刻的状态,其实这种相关方式来说,就是相当于让每个专家更加专的去学,这一个特定的这样的一个face,这样的一个这个相位上的,这个它的姿态的变化程度,在某种程度。

也是也是说让这个专家能够更有效地利用数据,也避免了一些这个这个这个啊,前面提到这种随性的问题,诶,这是这是这个这类方法的一个一个特点。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

那么效果其实刚才也看到了,其实效果还是相当不错的,当然就是也有一些很大的缺点了,就是说呃虽然说看起来这个动作是ok的嗯,但实际上你要仔细看的话,他有些细节,你是它是没有办法去很好的去复现出来。

就先你可以仔细看,你会看到角度上还是有点滑,其次是比如说我做急转弯的时候,比如正常人他会有一个减速啊,然后掉头啊这样的一个过程,那p fn实际上他就比较cheat了,就比较比较这个比较这个作弊一样。

就他就直接人就转过去了,那你就缺少了一些细节,所以这是也是他的一些一些缺点,但总体来说这个作为这个方向的第一个工作。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这个其实效果还是还是相当不错的,那当然实际上后面就是这一系列的工作,其实是在这样的一个基础之上做了,进一步的改进呢,就比如说我们前面提到了,其实这一系列他就是这一系列的工作,其实是很大的一个共同点。

就是他都是把一系列的专家的参数混合起来,然后造一个新专家,用这个新专家去做这个预测,那在这个过程中,其实这个专家本身是一个,另外呢这个权重在p fn里边,这个权重是固定的,它是由这个啊相位唯一确定的。

而相位是一个从0~1不停的,这个这个这个前进的这样一个东西,那其实后面其实和大家会发现这样一个权重,就比如说最基本的我这个人来说,人的走路,我们可以定义这样一个fs,这样一个这样一个向量函数。

但如果狗的走路啊,或者马的跑步,那这个face该怎么定义,那就是非常复杂,甚至于人这个走路也是就是人的动作,走路不是可以定义这个face的,但是比如说我要打篮球,那打篮球其实我的脚步跟我这个接触球。

这个时间可能不完全是对应的,或者说还有一些其他的,比如说跳舞啊,那这个动作就更加过真人,可能单单腿跳一跳,那我的face该怎么定义,其实更加更加复杂一些,所以实际上呢就是后面很详细的工作。

大家做的事情就是说我不再去显示的,去定义这样一个确定的一个ph,一个一个相位的这样的一个权重的啊,混合权重的一个计算,而是我希望这个混合群众呢,是根据我角色的这个当前状态。

加上用户的一些输入的参数来去给算出来,那当然实际上那这部分的话,他们就可以去定义一个新的神经网络,叫做gnetwork,叫做门网络,那他最初的做一件事情,比如说给了一个参数之后,我通过一个门网络。

然后去输出,那通常来讲这个对于这期的工作来说,你才会发现其实你不需要很复杂的网络,就是不管是门网络还是有的专家网络,可能只需要两三层的一个,简单的一个前向神经网络,就足够完成这样的计算。

而且效果也是非常不错的,所以说这个其实也是另外一个,就是也是超乎大家意料的一个一个问题,那当然这里后面就很多工作了,就是说其实从17年开始,有一系列的工作来做这件事情,主要在于什么呢。

就是说我们需要给这个门网络,输入什么样的参数,才能让他预测比较好的这个这个交易专家选中,另外一方面其实也是说我应该给这个函数,就是我们前面也提到了,我们动作其实有很多种不同表达方式嘛。

我们是用关节旋转表达,我们是用这个关键位置表达,我们是不是还考虑关节的速度,还考虑一些其他的一些信息,这些信息可能都会影响最终的结果,那这个其实很多时候是来自于,我们怎么去去构造网络结构。

怎么去调我们的输入参数,那他后面有一些工作,比如说18年的时候,这个工作其实做的事情就是说ok我,我除了这个角色的姿态之外,我们还需要考虑一些脚的速度,我认为脚的速度是非常重要的。

那其实发现诶确实对于狗的这个洞来说,是更加好的效果了,然后后来呢其实比如说我们如果说不只是假了,我们还有手,他打球,我们其实可以分别的对每一个,因为比如说像前面那个走路,我们其实是两条腿。

这个交替行为构成了一个相位函数,那我们其实可以进一步的,我们可以把那两个角分别拆开,我们可以分别对两个角分别定义一个向量函数,或者更进一步的,比如说我我可能有手就打个球。

那其实我对这个手上也有另外一个相关函数,那类似我如果有更多的这个交互的话,我会更多的相关函数,我问问这些所有的这些相关函数,分别做这个参数输入进去,这是20年的工作,20年的工作呢,其实再进一步。

就说我这个我都不需要再对每一个手,单独去定义这样一个想法函数了,我希望我可以从这个数据里边去自动的,用复制变换就学到一个下面函数的一个组合,那么它具体代表哪个手,我们是不关心的。

但总体来说我们它代表了一些手,一些一些一些姿势组合,那这些这些整个这个这叫compound,这个东西叫复合纤维函数,那提供了也可以用作为我这个gtwork的输入。

来去算这个专家混合权重的这个这个啊这个值,那所以其实这是一系列的工作,就是它总体来说是说在这样一个基础之上,我们只希望能够去不断的去调整。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这样的一个参数呢,那它来达到更好的效果,但是今年工作的效果了,其实看来已经非常好了,而且实际上从这个呃,这个这个实际的这个嗯这个啊效果和细节来说。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

其实都比以前好很多,那当然我们前面提到的,其实是说我们显示着去学一个一个函数,它根据我们当前的状态,加上一些用户参数,去预测下一帧的这样一个状态,这是一个训练的过程,但实际上我们前面也提到了。

那这个概率密度函数可以告诉我,这个动作到底是不是真的,ok那我们前面只是稍微偷懒了一下,我没有学这概率敏函数,而是我就是学了前后两帧的这个转移的,一个一个一个一个函数,但是我们如果想。

我就真的只想就想直接学这概率买了,我该怎么办,当然这里其实就是我们不会讲很多的,那我们只是讲一讲大概的一个想法,据说实际上我们真实的动作,它的概率函数,它的化石的图可能是非常非常复杂的。

我们这里是随便画了一个,但是看起来已经很复杂了,那我目标是什么呢,我目标是说从一些数据里边去把这样一个函数,这样一个东西给给给给学出来,要是说我们不知道这个函数的形式之后。

那我们其实怎么去怎么去定义它参数,这是这是非常非常麻烦的一件事情,所以有一类的方法就是所谓的一个生成模型啊,就是生成模型,实际上是说我就是确实就生成模型的目的,本质上就是说我给一些数据之后。

我去学这个px,我能知道这个数据里是什么,但是生成模型常见的一个形式,就是其实也是代表什么呢,就是说这就如果是,即使是我知道一个偏这个概率的函数,是这样一个形式之后。

我们如何从这样一个概率密度函数里采样,也是一个问题,就是说比如大家想的,比如说我是一个正态分布,我我我我我是说让你去,你去取一个根据正态分布取1000个点,那这个其实是大家总是有办法可以取的。

但如果它不是一个正当的,而是一个奇怪的,我们也没法写清楚,它是一个什么函数的一个东西,你该怎么从里边取1000个点出来啊,这其实也是一个问题,所以一般生产网络,它通常来讲是起到这样一个形式。

就说我可以从一个非常简单的概率分布,比如说一个正态分布,大家都比较知道的,正态分布,就是一个就是一个单峰的一个那么一个曲线,我们知道我们采样的时候,其实越靠中间越越小越近啊,越概率越大,越往外越少。

它是一个差不多是一个球形分布的一个东西,然后呢我从任何一个采样,我可以通过一个函数f z,然后可以把它映射到这个这个p的这个空间,大s这个空间,那我可以如果说我这个f z。

其实f z其实对应于是这个这样一个,条件密度分布啊,就是当我给出z之后的x一和条件密度分数,如果这个f z能够训练的很好的情况下,那我实际就代表了我这里面每一个采样,它其实就相当于。

他可以把这样一个原来一个正态分布的,这样一个圆形的一个一个形状,把它变形成一个真实分布的这么一个奇形怪,这样一个形状,当然不同的这种生成模型,其实他训练这个函数的方法其实是有所不同的。

比如说我们现在常见的,或者过去比较成功的几种,比如说最早的非常成功的这个v e,其实也不能说最早其实他跟干是差不多时间的,就variational auto encoder,变分自编码器这种方法。

他基本想法就是说,我其实我其实,因为我要学的是后面这个概率密度分布,但是我其实没办法,开始时我是不知道它是什么,但是我也有一些数据点,因为我们知道,我们数据点肯定是从这个,概率密度分布来得到的。

所以我可以把这个数据点通过一个编码器,把它编码成我的这个比较简单,这个分布上的一个点,然后呢再把这个点通过一个解码器,就真正的fx把它变成我们真正的一个概率函数,那我通过训练的时候。

其实就想要让这个解码器解出来,这个点给我输入给编码器的这个点,这俩点就可能相同,那就完成了一个训练的过程,那另外一个方法就是也是非常有名的,大家都知道的这个干嘛,就是对抗生成网络。

那对抗生成网络其实它并没有编码器这个环节,它是直接ok我从这个引擎间找了一个点,这个比如从这个根正态分布找了一个点,我就直接通过一个解码器,把它映射到我这个这个这个数据空间,然后带数据空间。

我需要判断一下,它到底是不是属于这个数据的分布,那我再额外训练一个这样一个判别器,那这个判别器根据这个输入来确定它是不是,它是不是真的或是假的,或者说他如果是真,表示它是属于这个分布的,如果是假。

表示他不是这个分布,那这样的话通过我通过不断的那个半圆去,通过不断训练那个app,使得这个判别器无法判断它是真或者是假,那其实就代表这个f已经带,已经能够把这个一个z。

我们原来正态分布变成一个非常复杂的分布,就是这个嗯干的这样的一个结构,那还有一些其他的企业结构,其实像前2年非常有名的,像这个标准化流,normalizing flow,他其实本质上跟那个呃跟v e啊。

其实是很相近的,但是它它是不同点在于什么呢,我们前面variation in coder,我们自变分变分自编码器,它其实是需要训练两个函数,一个编码器函数,一个解码器函数。

来实现这个中间这个震荡分布的这个空间,引空间,z的空间,到我们数据空间的这样的一个这个一个设,那对于novelifo来说呢,实际上这两个函数是同一个函数,只不过我要求这个函数本身是可逆的。

那其实一个一个是编码器,那它的逆函数自动就变成了解码器,然后通过这样的同样用这个唯一的训练,我们其实可以类似于得到一个normalize flow,的一个训练,然后最近的非常火的。

那我们今天也看了很多很多这样的一个新的,非常好的结果,采用了这个diffusion model,所谓的这个扩散模型,它本质上也是一个,其实本质上也是这样一个编码解码的过程,只不过呢像v e这个结构。

我其实是通过一次编码,就到了我们这个正态分布空间,然后对于这个defeat model或者这个扩散模型来说,实际上它是通过若干次编码,每次加一点点的这个噪音,每次一点点的编码,然后逐渐的一切。

比如说通过1000次或者1万次这样的迭代,我最终得到了这个空间,然后再通过1万次的这个去掉这个噪音的过程,这个1万次的解码,然后再回到我这个眼空间,他通过这样的话完成这样一个训练。

那这是high level的,我们大概是这样一个idea,但实际上我觉得动画来说,因为这些东西,就它最终都是学到了一个对应的一个,动作的这样一个分布,实际上我们可以用不同的含不同的这个模型。

可以实现大致上差不多的目标了。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

就比如说我们有一些过去,有些比较也是这样的一些经典的工作,比如说像这个用v e那个这个,来实现这样一个控制,然后比如说像这个normalize flow,来去实现这样的一个控制。

那这样的方法其实很好处是什么呢,就是说不管是这样哪一种方法。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们其实回到前面的这个这个基本的概念,就是说我们其实是通过这样的,它是通过我可以在这样一个非常简单的,比如说一个高斯分布里去采一个样本,这个样本是一个随机的一个噪音,然后我可以通过一个编码器。

把这个随机的噪音变成一个合理的动作,这是我们这个生成网络的一个,它的非常好的一个性质,那这个性质之上呢,比如说我想控制一个角色向某一个方向移动,那我其实这个目标会变成,我在这个隐空间里的一个一个轨迹。

那时间就出现在反过来,就是当我给出一个目标之后,我可以想办法在引擎里画出一个轨迹出来,那个轨迹通过我的这个解码器,它会变成一个完成这个目标的一个动作,那具体要怎么怎么去实现这个轨迹。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

能是另外一个话题的,或者通过一些优化的方式来吧来完成一件事情,那当然这个其实像vae和noslow,其实在这个scraph上我们看到一些很好的结果,但是呢其实很遗憾啊。

就是虽然说我们四种不同的常见的这种啊。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

生成模型的这种方式,但是这个干其实好像在动作上面,这个效果一直不是很好,就是大家至少在我没有看到一个像。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

比如像这个像v e啊,像number flow啊,甚至像这个像这个p f n啊,这么好的一个效果,可能也许是干这个模型本身。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在持续这样一个问题上的一个不稳定性,那当然今年我们看到新的工作了,那就是比如说用这个defi model啊,用这个扩散模型来做动作啊,这大家都是做的非常快的,特别是他们或者扩。

特别是扩散模型在这个呃图像生成上的成功,其实我也是带来了很多的这种新的一些想法,那当然大家最想的方向就是说哎我给你一个洞,给你一个语言,比如我给你一段话,我希望你按照这段话生成一个合适的一个动作。

其实跟我们defense model,在这个图像生成上的一些效果,其实是表就是功能是比较相近的,只不过我们把图像变成了一段动作,实际效果上看起来还是不错的,就是但是这个总体来说还是有很多很多。

可以进一步的进步的空间啊,就是看起来是那么回事了,但是这个整体质量还可以进一步提高,ok那其实我们今天讲的是一个稍微有点难度的,可能不是说我们这个比如说我们大二去听,这,如果如果你是大二的学生的话。

你要听的话,可能会发现有些镜头有些东西会比较吃力,但总体来说我们这门这节课,主要是对我们近些年啊,就是特别是基于神经网络的这些方法,我们做一个简单的回顾,就是大家有兴趣的话。

哎咱们知道我们这里其实有些这类的工作,现在已经可以做到这样的一个程度了,或者说我们有哪些方法可以来来做这件事情,那总体来说我们就是从回顾了一下,然后呢我们其实稍微讲的多一点,就是一个非常经典的一个模型。

叫p f n啊,它是怎么构成的,它怎么去生成一段动作,那我们也是稍微回顾了一下,生成模型,在这个这个动画里面的一些几个,非常经典的工作,那当然后面还有新的新新的工作,也是当然大家有兴趣的话。

可以继续关注,我们这这这这这一系列的这个问题,ok那这个就是我们今天的主要内容啊,看看大家有什么问题,啊对ga maker其实是一个很好的一个例子啊,就是它是一个小样本的一个训练,能够生成很好的结果。

对这个我确实没有放进来,对,确实前面那几个工作,就是特别是不需要生成网络的,就是只是单纯的这个最后一个模型的,其实是以他姑咱们组的为主啊,但是实际上还有一些其他的组,比如说像是。

其实我们这个这个领域的好多这个方向的东西,比如像那个韩国的这个这个jk里,他们也做了一些工作,但是他们是用的是rn的模型,只有这一这一期的工作呃,工业上用的多不多,这个我其实不是很确定。

说实话就是工业项目现在用的最多的,肯定是motion matching,这我很sure,matching来说,你就你就直接调就行了,嗯我相信是有用的,就比如说像很多时候你做这种这种。

比如数字人动作生成舞蹈啊,这些其实可能都是相关的,可能有些应用吧,但我但我不是很确定到底有多大规模,a m p s e,这个我们后面会讲,我们今年这个工作,control v e实际上是一个v e的。

一个在控制上的一个版本,就是物理仿真的版本,像s e m p其实是干的,控制版本就是gal嘛,它其实是干,就是这个生成对抗网络的一个一个扩展,就是纯不用物理的话,就主要问题在于。

你不大容易去定义一个很好的一个,这个这个这个这个reward单时间也有用的,就是我们其实上节课讲了一个motion field,就是我们讲motion matching。

它其实是受到motion field的启发来产生的,那这个过程中,实际上他的这个魔神feel的本身,这样一个训练,其实效果也是不错的,但是除此之外呢,其实好像也没有看到一个其他的工作。

其实实际上做这件事是怎么说呢,就是有点overkill,就是一个regression问题,做这么复杂的任务,虚拟偶像中有应用前景吗,我相信是有的,我觉得特别是像defer model这一类的方法。

逐渐出来之后,就是特别是比如基于语言的,其实也就像我们今年做的一些工作,像是从语言生成一个手势,我们今天之前做了一些工作,就这种跨模态生成,我觉得是在虚拟偶像里面应该也是挺相关的,比如说现在新拟偶像。

大家都是比方说我做一个动捕,然后通过这个动捕来驱动一个新偶像,来去做运动,那这是一个比较直接的方法,那当然其实缺点就是我必须要有一个演员在那,希望我们能够把这个东西变成一个真的,一个人啊。

不需要一个演员,而是靠我们的这个看我们这个模型,他去做这个生成,那我可能有些输入,我的输入可能是语言,可能是,但这个语言哪里来,也许是我写一个脚本,也许是一来自一个是这个语言的,一个对话模型等等。

可能是带来一些效果,给大家一些其他的领域啊,我们其实也说过,因为本质上来说,我们上节课其实提到这件事情,就是比如说我做ik的时候,我有一个先验分布,可以帮助我们去保证我从ik的时候,动作是真实性。

那类似的,比如说我们做这种像是比如说动捕,那如果说比如我们只有一个相机单箭头的动捕,我们之前也提到单箭头动捕,它会有很多这种奇异性问题,他如果说没有很好的鲜艳的话,可以帮助我们解决奇迹的问题。

来达到更好的效果,所以都是一些很好的可能性啊,但是实用性现在还目前真实用的话,落地的话可能还是没有见到什么特别好的,像这种这种这种应用,训练模型,动作模型的数据集,那其实蛮多的呀。

这个开源的动捕数据库倒都是现在比较大的,可能是m吧,max,主要是把它们都统一到那个simple sp l模型的,这样一个结构模型,这样一个数据结构上,那是因为常用的比较大的。

像是cm data set,这个用的很老了,还有这种human 3。6,他们做动那个视频动捕的,其实有一个很好的一个数据库,还有像玉碧他们公开这个这个拉饭数据集,也是很好的一些数据集,还有些其他的。

其实数据集,其实总体来说在越变越多的这样一个状态,robust motion between,其实这个我没有讲啊,其实robust motion between,如果你仔细看它的工作的话。

它其实属于这个auto regressive,它是用一个它是用一个那个rnn,就比如psn这一类,它是直接用一个一个follow the network去算下一帧嘛。

但是那个robust motion between,它其实一个r n来来去做这样一个,来去代替这个f,那当然他主要是说就是它的控制信号,我们前面提到的就是比你这里的f,那这些控制信号是是什么。

其实可以是这个,比如说下一个关键帧的位置,那也可以是你的工作信号,那当然今年还有一些新的工作了,就是我们不是用r n了,也不用这个前下神经网络了,我用transformer。

其实我们前transformer是一个很好的一个例子,就是我们前面这里其实是是假设,我们很多讨论都是假设说ok我只考虑,我只考虑当前这一帧,然后算下一帧,但实际上如果你要更复杂的话。

其实可能我需要考虑前面若干针,那其实很多transformer的这样的结构,它其实是类似于这样的一个情况,那也也有些transformer是说我不是用这种,就不是用这种,只考虑前面那一桌干针。

我其实把后面的若干针也放进来一块考虑,那其实也是这种方,但是那种方式来说,他就不太容易去做这种实时应用了,因为它需要考虑未来的状态,行我觉得时间也差不多了,然后那个我们有什么问题的话呢。

我们也可以继续在我们的群里进行这个讨论啊,然后另外像我们刚才说的,我们今天最晚,明天我们那不就第二个作业的这个内容,我会放在github上,然后也欢迎大家来来共同参与啊,然后也是非常感谢好的。

那我们今天的内容就到这里啊。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

GAMES105-计算机角色动画基础 - P8:Lecture07 Skinning - GAMES-Webinar - BV1GG4y1p7fF

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

ok好的,那我们就开始上课了,今天是我们game 105的第八节课,当然是啊like是零七啊,因为主要是我们learning with animation,多讲了一点内容啊。

那我们今天主要讲的部分是关于skinny啊,就是说嗯因为我们前面讲的,或者说我们整个这门课主要关注的部分,其实是啊,卷机角色动画里边的,这个就是骨骼动画的这个部分,然后我们这节课,然而作为一个插入。

我们也是为了让我们这个,其实介绍更加完整一些,我们再多讲一点关于skin的部分,就是说我们怎么去用角色动啊,骨骼动画去驱动一个新角色,去啊去展示我们的运动啊,其实我们大部分情况下,我们讲骨骼动画的时候。

其实这个古国应该是一个抽象的一个东西,并不是一个可见的一个这样,一个这样一个这样一个结构,然后我们实际上真正我们在比如说电影里边,或各种应用里边,我们看到的新角色,其实它都是一些就外面这种蒙皮的形变啊。

带来了这种展示的展示的这种效果啊,所以说我们如何能够去让一个骨骼动画,去驱动一个蒙皮,产生我们想要的形变,那这个布其实是由这个skinning就是蒙皮的啊,绑定啊,蒙皮的这个形变啊。

这种啊这一类的技术来共同的完成,当我们今天主要是涉及到一些嗯比较简单的,这个呃就是主要是讲一讲蒙皮的一些基本概念,还有一些我们非常简单的,或者非常常用的一些蒙皮的一些技术。

然后另外呢其实我们也是额外多介绍一些啊,就是说在蒙皮这个技术啊,在一些呃一些具体的例子啊,比如说这个s m p l model,我想可能有些同学比如说知道的,就是可能这个其实是一个非常重要的一个啊。

人体的一个模型,然后另外呢作为这个蒙皮技术的一个应用呢,我们稍微讲一讲facial animation,就是脸部表情的动画是怎么生成的,当然我们不会讲非常复杂的东西,我们也只是作为一个例子讲一讲。

用蒙皮的这种方法来实现,脸部动画的这样一个技术,那当然我们这门课其实也是参考了啊,也是也是山村,其实也是有一点有一点比较经典的这么一个呃,关于蒙皮的一个siggraph的一个课程。

但是他有兴趣的话可以去看一看这个这个主页,他们有几篇啊比较很好的这个cos note啊,还是可以作为参考,那当然我们其实也说到了,其实我们在第一节课的时候介绍过,就是关于这个角色动画的这个啊流程啊。

其实我们这个动画其实主要是分成两部分,一部分是关于这个蒙皮的这个绑定啊,蒙皮的这个变形啊,然后另外一部分是说这个也是最主要的部分,其实就是我们的骨骼动画了啊,只有说我们骨骼动画呃,它会带来这骨骼的运动。

然后用这样的骨骼的运动去驱动一个蒙皮,产生形变,然后最后再把这个产生形变之后的蒙皮,把它渲染出来,这才是我们最终能够看到的动画。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

那当然实际上这里面有两个概念啊,也经常会比较容易搞混啊,就是一个是riging,一个是skinning,一个是应该叫什么,一个叫绑定,一个叫蒙皮呃,当然实际上这个就经常来讲,这个,有些时候他会。

他会这种互相交换着来用我这两个词,但通常来讲我们讲rigging,但大部分来说是指的是说,我会创建一个可以控制的这么一个啊啊,这么一个控制器啊,就比如说像左边这个视频里边,成这种脸上这些控制器。

那我同时调整一些控制器,它会带来我这个身体的这个这种形状的,比如脸的表情的变化,或者是皮肤的一种形状的变化,那当然是件蒙皮,通常来讲,它其实应该算是一种特殊的一个reading的,一个一个一个啊特例啊。

就是说可能就只说对于我们一般的,比如身体骨骼上的这种这种蒙皮来说,可能通过一些刷权重啊,或者通过一种线性线性蒙皮技术啊,这些方式来使来利用骨骼来实现对这个啊骨骼,这个人人身体形状的这样一个控制。

当然这个更更广义的这种rigging,就更广义的绑定来说,其实也许这个这个人的动作的形变,可能不一定是通过骨骼来完成的,也可能就是通过比起,比如说我一些额外的,不在谷歌上的一些点的控制器啊。

或者是可能一些这种ban的shape来完成,那这些其实都算是rian的部分,而那个skinning的话,相对来说更加更加。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

特指这个骨骼驱动的这件事情,那当然我们在讲蒙皮用,因为我们之前是主要是讲蒙皮的形变,那我们其实还是要稍微回顾一下,关于我们在我们这个蒙皮,或者说我们的这个几何外观该怎么去表示啊。

因为这个就应该说是在games 101,或者说其他的前面几门课里面,应该会不断的提到,我们这里只是简单的提一讲,就是因为我们正常来讲,比如说我们想去看到一个一个一个,一个一个物体。

在这个虚拟世界里看到一个物体,那我们很多比如说我们做渲染的话,我们肯定是需要做,比如说像这种光线追踪啊,或者需要做这种啊这种光栅化呀,它其实主要是对一些几何物体来进行,做这件事情。

然后这个几个物体通常来讲,我们会有一定的表表达的方式,而这里边最常用的一类表达方式,主要还是这种mesh或者是这种点啊,这种叫三角网格或者私媒体网格,或者什么样的某某种特定的网格,这样的表现形式。

那这些网格它主要是啊在我们一个物体的外皮,这个外表面上那放了若干的点,然后直接点之间进行连接,然后直接连接的点构成了一个面,那这些面总体来说构成一个完整的,这样一个物体。

那当然实际上这个可以更加通用化一点,就说网格表示是一种非常常用的表示,但我们也知道,几何表示其实还有很多其他的类型,比如说像nerves这种,像是比如说这种样条曲线差值,或者是基于这种啊。

这种比如说或者甚至一些引致的曲线等等,就是通常来讲,我们一般来说希望我们的这样一个几何表示,它能够提供一些控制点,那这些控制点的位置,也会干预到我这个外形的形状去变化,所以总的来说。

对于这样一个几何的这个嗯表示来说,通常来讲我们会说我们上面会有若干个点啊,这些点它的位置就是所有这些点的位置,共同的去构成了这个物体的形状的一个表示,那反过来其实我们也知道。

实际上为了能够去改变物体形状的,这个直接就造成这样让物理这个形状发生变化,那我们其实也是说我们去改变这些特点的位置,就可以完成这件事情,当然这个就当然对于对于这个网格来说。

那我们其实就改了就是顶点的位置,但是对于一些其他的表示,比如说像是刚才我说的nerves或者贝塞尔曲线,或者样条曲线等等,其实你可能改的是一些控制点,那些控制点不一定直接是在那个表面上。

但实际上他们也会起到改变我们这个形状的,一个作用,那当然我们其实有一个非常从,非常简单的例子来看啊,就是说比如说这是一个人啊,这是一个人的模型,我们就简单的把一个非常小的一段给拿出来。

大家可以表示简单的表达成这样一个形式,那这里面大概我们只有这里有十个点,然后十个点它构成了热干的面,然后呢我们其实在蒙蔽诶,不好意思,然后实际上在我们这个绑定的时候,我们实际上是在里边穿上啊。

在他们这个里面放上一个骨骼,那这个骨骼呢,我一般来说会把它放在这个蒙皮的中间啊,这样的话其实呃其实正常来讲是,因为人也是这样,就是从解剖解剖上也是,其实也是这个样子的。

就是我们一般来说骨骨头肯定是在肉的里边的,那在这个基础之上呢,我们其实是希望这个嗯骨骼,比如说我们在移动手的时候,那其实你的这个身体的这个骨骼,随着我们前面的这种动画的这种啊计算。

那其实这个骨骼的位置会发生一些移动,那蒙皮的变形的这个目标,其实是说,我们希望在这个骨骼发生形变的,这样一个基础之上呢,我们这个他身边的这个骨骼,旁边的这些蒙皮的这个顶点。

也能够随着我对骨骼的移动来产生移动,那这个其实是我们对这样的话,我们可以不断通过驱动骨骼,来改变这个蒙皮的位置,那从而进二人,然后让我们这个真正的角色,他做出我们想要的动作来产生合适的形变。

那当然估计这个过程中,我们其实是有一个就是关于蒙皮的,一个非常从数学表达来说,就是说我是希望能够根据我骨骼的这样的,一个位移啊,所有的这些变换,然后在这个基础之上。

我们该怎么去计算这个随着骨骼移动的这些,这个点就是蒙皮上的点的位置,这其实是我们要要蒙皮啊,skinny需要就是蒙皮蒙皮计算需要做的事情,然后在这个里边,其实我们可以再稍微把它这个变换,再稍微具体一点。

就比如说我们可以假设变换之前,冰箱之前这个角色,他的骨骼大概是这样子一个状态,然后他的这个全局的旋转是q啊,那他们这个骨骼的这段骨骼的关节,是放在一个点o的地方,那通过这个变换之后呢。

他这个关节的位置移动到一个新的点o撇,然后骨骼的这个朝向,那你之前是q那经过一个旋转r之后呢,其实变成q撇,那我们知道其实q撇应该是r乘以q,那对应的这个o撇应该是o加上t,那这样的结构。

那接下来那个x撇,这个计算其实相对来说就比较简单了,因为本质上来说它就是一个坐标变换,那这个坐标变换呢,就是说我是把x原来是在这个b这个移,这个移动之前的,这个谷歌的坐标系下的一个表示呃。

把它转换到一个新谷歌下的,就是就是新的这个谷歌移动之后的,那个坐标系下的一个表示,所以总体来说,我是应该是先把这个x转换到这个,原来谷歌这个q的坐标系的及物坐标系之下啊,通过一个减掉一个圆点。

然后乘以这个朝向的这个这个,need的这样的一个形式,然后呢,在在在外面再乘上这个目标股和这个朝向,然后加上目标骨骼的这个坐标啊,坐标原点的位置,那就完成这样一个变化,那这个其实是非常简单的。

或者我们可以再进一步再把它写啊,写的在这个呃抽象一点,或者是在这个代换一下,我们其实可以用一个r来表示这个点,x就是这个蒙皮上的点,他在这个骨骼的局部坐标系下的一个坐标啊,其实或者说你可以认为是说。

从这个关节点到这个目这个骨骼上,sorry蒙皮上这个点,它的这个向量呢,在局部坐标系的一个表示的位置,那从这个局部坐标系的表示,实际上在我们整个,至少在我们只有一个骨骼的情况下。

这个这个这个局部坐标系的表示,是不会发生变化,不管是我们这个骨骼是怎么移动的,那我们总是可以在一个单谷歌移动,移动到一个新的位置之后呢,我们其实可以再把这个局部坐下的表示。

再把它转化成一个全局坐标系的表示,那就完成了这样的一个计算,那当然这个其实看起来比较简单,比较非常直观,因为本质上就是一个这个就是一个局部坐标系,到全新坐标系的这么一个转换,一个坐标转换的这么一个过程。

那我们为什么要就是在这里稍微强调一下,这件事情呢,主要是因为有一个在那个蒙皮绑定里边,有一个非常重要的一个概念概念,就是ban pose,那有时候也叫reference pose。

有时候也叫这个这个叫什么rest pose,就是类似的各种名字差不多,但是总体来说是表示同一个意思,其实我们之前也提到过,就是说我们其实很多时候我们的骨骼,比如我们经常创建的时候。

可能是在一个t pose或者是一个apos,或者是一个奇怪的pose,这局你有什么软件,然后呢我们的这个角色的模型,很多时候我们会把它创建成一个apples啊,那这样的话因为它模型它总体来说做起来说。

这个人姿势看起来更加自然一些,那所以说通常来讲,为了能够把这两个东西建立联系,我一般来说我们会把这个骨骼,把它旋转到一个跟蒙皮这个蒙皮的这个网格,和这个模型差不多的一个姿势,然后在这个姿势之下呢。

我再去计算这个蒙皮上的每一个点,相对于骨骼的这个关节的这个这个距离,这些位置,然后各种信息,那这些局部的信息呢其实是非常重要的,因为我们后面在不断的在计算,这个蒙皮绑定的时候,其实非是要经常用到的。

因为从刚才我们这个计算也可以看到,实际上我们随着骨骼的移动,这个每一个网格上的点,它的位置,实际上始终,我们是希望是通过用这个这个局部的一个啊,坐标系的表示来做这个转换。

所以说实际上这个ban pose给了我们,给了我们一个什么信息呢,其实就给了我们每一个关节,在每一个这个蒙皮或者这个模型上的点,它应该在这个我每个骨骼下,它的局部较细的表示应该是什么样子的。

就我们就给出ban个pose之后呢,呃bank pose之后呢,我们其实可以通过这个全局到局部,坐标系的转换来完成这个计算,ok这是一个骨骼的一个非常简单的情况,但如果到我们很多时候。

比如说大部分情况下,我们不会考虑一个骨骼,而是考虑很多很多构成了一个整体,那比如说假如说我们现在稍微复杂一点,比如说我们只有两个骨骼,其实大概是可以,比如说大概就是胳膊这样一个这么一个空间。

那这里边这里有整个一个锅子啊,整个胳膊的这样的一个啊蒙皮啊,上面有若干个点,那这里面有两个关节啊,其实前上面这个是这个肩膀,下面这个大概是一个这个肘关节,那在这样的一个基础上呢。

唉那这个基础上我们可以再稍微定义一些量啊,就比如说这个第一个关节,肩膀那个关节我用oe来表示,那整个肩膀其实就是第一个第一个骨骼啊,第二啊,然后整个小臂是这个这个这个b2 ,就是第二个骨头。

然后这时候我们整个胳膊其实是一个整体,那tlb上面有若干个点,那这些点到底其实它既不属于骨骼,也不属于谷二,它可能属于这两个骨骼的这个整体,那我们在这个点上,比如说我们在这个胳膊上。

我取一个点x那这个点其实我们前面说,如果说我们认为当前这个姿势是一个bad bose,的情况下,我们其实可以应用这个姿势来计算这个点,相对于这个上面这个第一个骨骼和,相当于第二个骨头。

他们这两个的这个局部坐标系一下,这个x的表示,那其实也代表了是从这个两个骨骼的原点,分别到这个坐标系的这个这个这个相对的位置,那这个其实可以很容易计算,那在基础之上,如果说我对这个骨骼这一段胳膊。

我让他这两个关节发生了一些旋转,比如说让这个前面那个胳膊往上转一点,然后下面这个胳膊和下面那个关节向下转一点,那其实大概会形成这么一个形状,那那这个就是随便转了一下。

那他原来这两个胳膊在我们绑定的ban pose里边,它的这个朝向分之q2 和q1 ,然后这个原点的位置也都是oeo 2,那我们转换完之后呢,我们经过这个身体的旋转,但是在某一个姿势之下。

他们朝向我们认为现在是带撇的q一撇,q撇,然后还有o一撇和o2 撇等等等等,那在这种情况下,因为我们在整个缸体的啊,如果说我在我这过程中,我们其实是认为这个每个点,就之前这个x这个点在两个坐标系。

两个骨骼坐标系的局部的这个位置是不变的,那么这两个谷歌,因为它两个旋转的方式是不一样的,所以他们将来未来的场向也是不一样的,那在哪这两个不同的朝向坐标系之下呢,你是可以发现原来是同一个点,也是同一点。

x你通过两个不同的这个股的坐标系,这个进行变换,你会发现它会变成了两个点,其中这个点在这个第一个goob坐标系下的位置,在新的位置,我们是可以通过这个坐标变换来计算出来。

那类似的这个点在第二个谷歌的这个,坐标系下的位置,我们也通过同样的,可以通过一个另外一个坐标的变化来进行完成,那当然这里就有一个问题啊,其实这两个点原来是一个点,但是现在分成了两个点,这会带来一些问题。

主要是说如果说这个就是,我们原来mesh应该是一个整体,那我们现在把一个点拆成了两个点,那么就可以直接就可以看到这个这个mesh,就我们这个蒙皮它其实就从中间裂开了,那就不算是一个完整的一个一个形状。

所以实际上那个为了整个正确的计算呢,我们其实还是需要把这两个点,再把它恢复成一个点,那这个时候呢我们通常一种非常简单的方法呢,就是说我因为我用两个骨骼分别计算出了,这个点,在这个动作之后。

它应该在什么位置,但这两个骨骼其实对这个这个关节,就这个点影响的影响力可能是不同的,就比如说这个骨骼一开始的时候,它其实是离这个骨骼这个关节更加近一点,离这个关节更加远一点啊,或者说时间可以想象一下。

这是小b啊,小b上的一个点,应该可能受到这个胳膊的观影响更大一些,那那那为了能够体现这一点,那我们其实就是可以通过一个权重啊,两个w,这个w一代表了这个这个第一个,谷歌对这个点的影响的这个程度。

然后w2 呢代表第二个对这个点明显的程度,那么最终这个点的位置呢,实际上就是两个骨骼分别计算出来的,这个嗯呃目标点的位置,然后通过一个影响力,那最后得到了我们这个点的位置。

那如果说我们这个角色有更多的骨骼,比如说这个一个非常完整的一个角色,那这个可能有有有20多个或者更多的,这样的骨骼结构,那实际上同时这个这个嗯蒙皮上的一个点,那他可能会受到很多不同的啊骨骼的影响。

其实特别典型的就是腰上这个这个点,因为你们知道,比如说我弯腰,那其实我弯腰的时候,可能我整个脊柱都会,脊柱上的所有的关节可能都会弯曲,那这些关这些弯曲呢,都会多少的显影响我肚子上。

这个肚子上点的这个位置,所以说这个在这个过程中,我们如何去当,比如说我们这个角色换了一个新的位置的时候,那我们该如何去计算啊,同样还是这个点,他在这个他在不同的一个姿态之下。

原来这个腰上这个点现在会移动到哪里啊,那这个其实变得比刚才变得更加,复杂一点的问题,但是因为整个计算过程还是一样的,就是说我们如果说我们认为这个姿态,是一个绑定姿态,一个ban pose。

在ban pose下,我们其实大部分情况下,我们ban pose是需要把这个骨骼移动到一个,跟这个蒙皮啊这个对齐的这样的一个位置,那在这个这样的一个位置下呢,我们其实可以比较容易的去计算。

我们这个每个骨骼,每个点sorry蒙皮上,这个点相对于骨骼的每一个关节,那当前的这样一个朝向的下的这个局部,最霸气的这样一个一个一个坐标表达,那算出这个之后呢,那我们把这个橘色的这个关节。

整个这个骨骼系统,把它变化到一个新的姿势之后,那其实我们还是利用刚才的这个这样一个变换,我们是可以得到我们这个点的位置,应该是说每这个原来这个点在每一个关节,他可能会受到所有的关节影响。

他受到在每个关节之下,就是从这个从这样一个姿势,变到另外一个姿势呢,其实我们每一个关节可能都会发生一定的这个,全局上的一个一个位移,一个形变啊,sir一个变换,那在这个变换之下呢。

我们其实每一个就这个点会在每一个变换之下,分别移动到不同的位置,然后把这所有的这些位置通过加权平均,那最终得到的就是这个关节啊,这个点在我们这个新的这个姿态下,这样一个位置。

那当这个过程中其实是非常重要的一个一个量,就是这个所谓的这个蒙皮权重了,因为这个它代表了,说这个点受到了哪些关节的影响,并且这些关节对这个点的影响不大,那当然这个蒙皮权重。

实际上是一个非常是一个额外的话题,就是我们该怎么去定义这样一个蒙皮权重,除此之外呢,其实我们这个角色,他其实其实肯定是上面有很多很多点,同时来讲是可能有几千个点,那每一个点实际上在在ban的pose下。

我们其实原来我们这个下标,只有下面是我们没有下标啊,我们现在如果说我们考虑到所有的点的话,那我们其实可以给每个点一个下标,那这样的情况下,实际上我们需要对每一个点分别计算出这个点。

相对于所有每一个关节它的局部位置,然后在我们去算这个蒙皮,这新的萌新的姿势下的,这个蒙皮点的位置的时候呢,那我们其实也是需要去做很多次的,这样的一个呃坐标坐标的变换,然后最后再加点平均啊。

得到作为每个点的这样一个位置,那当然这样看起来其实计算量还是蛮大的,因为如果说这个点有几千个的话,那我其实前面初始化的时候,需要计算几千个点乘以几十个关节,那就上万个这样的一个参数需要去计算。

当然我后面会看到,其实这件事情啊,我们其实不需要真的去计算这么复杂的一个,这么多的一个量,我们其实可以啊,可以通过一些这个一些变换啊,把这个整个这个计算把它简化很多,ok那其实我们前面提到的这种方法。

就特别是利用啊一个局部坐标,然后在每一通过把每一个点的局部坐标啊,通过把每一个点嗯,让每一所有关节的,这个在不同姿势下的这个变换,把它变换到一个新的位置,然后再把这所有的一个新的位置。

用我的蒙皮权重把它加权平均之后啊,算出这个点的新位置,那只能整个这个过程虽然说起来有点费,比较费劲,但实际上它就是一个这么一个非常简单的,一个公式的一个形式,那这个公式我们可以看到。

这里面所有的变换其实都是线性的,其实也是一个线性的,所以整体来说,这是一个非常简单的一个线性的一个啊,混合的一个方法,这个方法其实有一个非常简单,就是非常常见的一个产品名字,就是这个r b s。

那所谓的这个线性混合蒙皮啊,啊这个这个中文其实有点不太好翻,通常来讲就是l b s,那我们就指的其实就是这种方法,那当我们前面也提到,这个l b s其实有几个非常重要的。

其实主要是有三个非常重要的这个概念啊,第一个是bad pose,bad pose我们也提到了,就是说我们通常讲,要把这个骨骼跟这个蒙皮对齐,然后对齐之后呢,我们其实在这个以这个为基准。

去计算后面的这个这个形变,那这个基准的pose呢就是ban pose,但是bn pose情况下,其实那个骨骼的旋转不一定是零啊,这跟t pose不太一样,我们之前讲t pose的时候。

我们是假设他每个关节的旋转是零,但当然这只是我们这里的假设,当然有些可能你在其他地方看到的名词,可能也不太一样,有可能你看到一个tp,他们实际上抵制的是bad pose嗯,但至少在这里。

其实这个只是说我们是把这个骨骼,旋转到这个姿势,所以它有可能是一个啊旋转不为零的一个状态,那当然它根据段朝向,你总是可以把它转换到一个局部坐标系,来进行表达。

然后另外一个非常重要的部分就是skinning with,就是我们的蒙皮权重,这个其实很大程度上,决定了我们这个蒙皮形变的这样一个质量,那还有最后一个就是skintransformation。

这个实际上是在我们真实的去做形变的时候,比如说我们见到一个新的姿态之后,那我们通过一些计算,特别是通过这样一个加权平均的这样一个计算,实际上最终算到的这个蒙皮上每一个顶点,他的这个变换的这个值啊。

那这个其实就我们这个蒙皮变换的这样一部分,那当然整体来说嗯,我们的这个角色,我们这个这个rbs其实是一个非常非常常用的,一个蒙皮的一个技术,就是说实际上我们大部分的看到的,这个应用里边。

其实基本来说都是lbs,一方面来说这个很简单,另外一方面来说,实际上它也是也是非常的这个高效的,并且对我们gpu也是比较友好的,因为主要是也是因为他整个整体来说是一个,非常线性的一个形片嘛。

我们其实可以比较容易的在,就是非常高效的来实现,那另外一方面呢,其实如果是在考虑到gpu,通常来讲我们在模拟形变的时候,可能会有一些啊约束一些要求,就比如说木,正常来讲,实际上我们这样一个蒙皮。

它是可以,每一个点都可能射到所有的关节的影响啊,所有的骨骼的运动的影响,其实想一想,其实嗯也是,其实想想也是合理的,就比如说我可能比如说摸着我的腰,比如说抬下手,那有可能是我这个腰也是会有受到一些影响。

因为本质上来说你的肌肉,整体人的这样一个肌肉系统是这个互相耦合的,所以说实际上就是真的是哪怕你抬下手,有可能的脚都会发生一些变化,那当然对于这个,但是其实也是一,但是即使这样子的话。

其实我们大部分远离这个当前这个点,比较远的那些关节,对当前点的影响其实相对来说是更小,就是可能会想到不可以忽略的这样一个状态,所以实际上为了能够比较高效的去进行进行,计算呢。

我们其实通常来讲呃可能会有一些约束,就是就是说我可能要求每一个点受到最多啊,比如说四个骨骼的影响,那这样的话其实从gpu的实现上,它更加快一点啊,这其实是,但实际上这个这个r b s其实比较通用的。

那么其实你可以可以受到所有的关键影响。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

ok那这里当然有一个问题啊,前面也是提到了,我们这个skinning weets就是蒙皮权重啊,这其实是一个非常重要的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

就是他对我们的这个呃最终效果就是形变嗯,蒙皮的效果影响是非常大的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

其实这里其实可以看到,因为这是一个就是在一个呃,就是一个动画师正在刷权重的这么一段,这个录屏啊,其实用这个就是说其实可以看到。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

比如像大腿这里,这里其实有一个看起来,现在看起来不太好的一个形变。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

那这个其实可以通过这个调整,不断调整权重来找到一组比较合适的这个目标,选中,让它这个形变啊,至少在某一个范围内看起来是比较合理的,但实际上这个刷权重,应该是一个专门的一个工种。

其实它应该是跟绑定是放在一起的,如果能在有些有些地方那沙雕动,其实他很多时候他做的事情,就是说我给一个姿势啊,然后我刷一下我的这个权重。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

因为我每次去改这个权重,应用前面这个计算,每次我改这个权重,实际上它都会在同样一个姿势之下,我只要改这个权重,其实它会影响我整个蒙皮的形状。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

所以说我可以不断的调整我的姿势,然后在每一个姿势下去改一个,去尽量的调整这个权重,使得我当这个整体的形变,再有一些,大部分我们这个需要关心的一些姿势上,他那个看起来是比较自然的。

那这个就是完成这样一个工作,那当然当然这个过程其实是非常麻烦的,因为主要是你首先肯定这个嗯要对,就是这个工画师他需要对审美啊,需要有相当好的审美啊,就是你要还,另外还有相当好的技术。

能保证能够实现他想要实现的效果,另外实际上也说嗯,其实我们每一次计算这个权重,我们知道其实这个权重是某一个顶点,相对于所有骨骼的,那其实反过来就相当于实际上对于每个谷歌,我都要刷一遍权重。

才能让这个整体的这个表达是自然的,所以说整体来说,这个这个这个工作其实是比较比较耗时,比较麻烦的一个一个过程,那当然其实有很多一些想法。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

一些研究,就说我们能不能把这个方法简化一下啊,能不能靠自动的方式,然后给出一个骨骼模型之后啊,给我一个蒙皮模型之后,那你能自动把这个权重给我算出来,当然这其实是一个研究问题,就是实际上没有。

现在还没有特别统一的这样一个方法,说哪个方法就一定能解决所有的问题,当一些比较老的方法了,比如说这种像这个pinoco,这其实很很很早的一些工作,现在因为现在blender,就是至少在2。730之前。

就blender,他其实提供了一些这种自动绑定的功能啊,那其实最主要还是基于这种比较老的这个,pinoco这样的这样的方法,那这类方法其实就以前的一些想法,就是说比如说我知道,比如说我这个手臂对吧。

手臂那手臂上比如说小臂上的点,他应该受到我这个小臂整体的影响大一点,但是受到大臂的影响应该小一点,那这个小的,那这个过程其实从影响力其实是相对来说,是从比如小臂,大臂一个比较相对来说比较平滑的一个过渡。

所以说以前一些些方法,就是说那我可以参考一下,有点借鉴一下,比如说热扩散的这种思路啊,就比如说我在小臂上这个骨骼上,这个关节上放一个热源,那这个预热源其实它会它会扩散嘛,那扩散出去之后呢。

那如果说这个相对来说温度比较高的地方,那应该就是受我影响大的地方啊,温度比较低的地方,就是我印象比较小的地方,那其实如果说不在每个关节上分别放一个热源,那我觉得大家可以看到。

那么有关节受它影响的范围大小类似近似,它大概代表了一个骨骼的一个权重的大小,当然这是以前一些这个纯几何的一些思路,那么现在一些新的方法的可能,比如说像这种。

像这个以前这neo skinny 2019年的sram,那主要就是基于数据的,估计这五个权重的这样的一个,一个一个神经网络啊,这个其实也是近2年我们常见的一,些一些研究方向,但这不同的方法里边。

可能我数据的数据集,怎么去这个提取它的特征,那这其实是一些比较复杂的问题,但总体来说,这是一个很很很很非常有用的一个话题,但是确实也没有什么,现在怎么说呢,就是也没有。

现在还是一个非常好的一个研究问题啊,就是也是没有完全被解决掉,那当然这个蒙皮权重是一方面,另外一方面就是说在我们计算好,知道蒙皮权重之后呢,我们需要去计算每一个顶点,它的这个蒙皮的这个形变啊。

那我们其实前面已经已经给出了这样一个公式,l b s这个公式,那他就是说我每一个顶点的位置应该是啊,这个顶点在在绑定字啊,在ban pose下这个局部的表示这局部坐标,然后在一个新的pose下。

把它转化成转化到全局坐标的这样一个位置,然后把这个所有的这个顶点坐标值,得到这样一个新的位置,那这是lbs的一个基本的公式,那当然当然在这个里边,我们知道,因为绑定姿势是一个确定的姿势。

就是他先不管我这个人怎么动啊,他的绑定姿势是固定的,因为一开始我就已经把他定好了,那在这样一个在这样的一个基础之上呢,那我们其实可以稍微做一点代换嘛,比如说把原来这个绑定姿势这个计算公式嘛。

带到我们原来这个这个嗯我们这lbs里面去,然后呢,其实这样代换之后呢,我们其实可以稍微做一下整理,因为可以看到里边,那这里跟i跟x相关,跟a相关的其实只有这一项,那其他的项其实都是跟j相关。

这是我们的骨骼的这样一个位置,那通过这样的变化呢,我们其实可以把它把,比如说这样可以得到q j跟q j t啊,这其实代表了什么,代表是说我在一个新的姿势之下,然后每个骨骼它的全局朝向。

相对于我在绑定姿势下,那个全局朝向的这个差别大概是这么一个东西,然后后面这个也类似,它其实代表了这样一个嗯,这样一个相对的这个位移关系,所以我们可以把它写在一起啊。

这个比如这个前前面那个相对的旋转写成r,然后相对位移写成t,那大概写成这样一个公式,那么可以进一步的把它们进行a不好意思,我们可以进一步把这个稍微把再把变形一下,因为前面这一步,前面这里不。

其实w和r我们去写成这样的一个形式,我们可以利用这个结合律,因为这里面只有xi xi是下标,是跟j无关的嘛,那我们其实可以把它提到外面去,然后把这个公式呢写成这样一个形式,那这样的形式就比较有意思了。

其实你可以看到实际上我们蒙皮绑定啊,就是那个l b s这样一个蒙皮,他实际做的事情是什么呢,他实际做的事情就是说对于我每一个顶点,对于一个每个顶点i,我们想去计算它的新姿势下的一个位置。

那我实际做的事情是什么,我实际做的事情是说我把这个新的姿势下,每个骨骼相对于bad pose下,那个骨骼的这个相对这个旋转,把所有这个旋转,用我的蒙皮旋转做一个加权平均,然后把对应的所有的这些位移。

用蒙皮权重加一个做一个加权平均,那这样的话,其实他们俩分别构成了一个矩阵和一个位移,那这个矩阵乘以我原来绑ban pose下,那个顶点的位置,然后加上这个位移,就得到了新的一个位置。

那这个其实就是我们刚才也提到了,其实我们就说虽然说我们这个公式,一开始公式推导里边我们用了这个局部坐标,那但实际上最终我们在实际计算的时候,我们其实不需要这个局部坐标的,因为这个局部坐标可能会非常多。

因为是每个顶点在每个关节下的局部坐标,那这个数量非常大,那实际上我们最终可以推导得到这样的一个,这样的一个形式,但实际我做的事情就是,只需要把每个关节的这个啊变换做平均,然后再乘以我这个预言。

ban pose下那个那个顶点的位置,就完成这样计算,那这样其实整体来说,计算量还是相对来说不是那么大的,那当然这里就是还是这个稍微再多讲一点,多解释一点时间,就刚才我们是lbs。

其实我们可以把它写成这样一个形式,那这个形式里边这个xi xi那其实是绑定ban pose,对于ban pose下的那个mesh那个蒙皮,它里边每个顶点的位置,全局位置。

然后这里这里的两个这个前面是一个群啊,一个啊矩阵,ok不思,前面是一个矩阵,后面是一个位移,分别是带对应了在两个不同的姿势,那一个是bkpose,一个是我们当前角色的姿势,在这两个姿势之下啊。

我们这个每一个骨骼,它的全局的这个啊,旋转和全局的这个这个这个这个位移啊,然后我的一个家庭平均啊,这其实实现了l b s这样一个效果,那当然这里其实可能有些同学已经发现了,就是实际上我们前面这一版。

后面这一半其实无所谓的,因为它就是一个平移的一个加权平均,但是前面前面这一半其实是很容易出现问题的,因为我们前面讲旋转差值的时候,已经说过这件事情,就是这里r是一个矩阵,一个旋转矩阵。

那如果说这个把旋转矩阵进行线性插值,它是很容易出现差之后结果不是一个旋转矩阵,这样一个问题,就比如说一个非常简单的例子,如果说这个旋转第一个是一个单位阵,那第二个是一个转了180度的一个矩阵。

那这两个矩阵r一和r2 ,如果说我用0。5来进行加权的话,你会发现他们俩的平均值,现在就是用0。5的加权嘛,就是它的平均值,那刚好是一个上面是两个是零啊,最后一个是一的一个它都是一个起一针的。

都不是一个旋转矩阵,都不是一个可可可逆的矩阵,那这样的话,其实前面那个矩阵就会变成一个,不是一个旋转阵,而是一个这个任意的一个矩阵,那这个时候带来什么问题呢,如果带来一个非常经典的就是lbs。

就是线性混合蒙皮的一个非常经典的,一个一个一个走样,就是一个一个区一个一个问题啊,就是这个所谓的candy rapper,就是啊应该叫糖纸啊,或者叫就大概是这种感觉吧。

就是说比如说这样一个东西这么一个形状,这是一个胳膊,如果说把后面这个关节,然后转眼80度,然后在线性蒙皮的这样一个条件下,你会发现它会中间会拧起来,形成一个形成凹陷,那实际上如果在一个震动角色上。

你也可以很容易看到,比如这是一个啊,我就这个找了一个角色,应该是remi,就是那个maximum mixo的一个角色,那这个这里他这个胳膊时间我就不管怎么样,不是不管是不小心也好,还是故意也好。

总之我把它转了1000000度,那就可以看到非常明显的这个这个胳膊肘,这个地方它是凹进去的啊,这个其实是一个不太好的一个效果,那当然为了能够解决这个问题呢,其实就是因为lbs。

这是一个l b s的一个先天的一个缺陷,因为这个其实是本质上就是一个线,因为我们在线性的去插值一个刚性旋转啊,一个刚性变换,或者说那这样一个线性的差值,是不能保证这个得到的结果,还是一个刚性变换的。

那这是一个非常重要的一个,一个就是从原理上就有这样一个缺陷,那当然能够为了能够解决这些问题的,其实就是其实前几年嘛就是可能十哎呀,15~20年前,其实这些这个其实这个领域还是很多人。

就是还是有很多很好的工作的,就比如说我们已经有些工作是说ok,我觉得这个嗯,他这个出现这个这个candy rapper的这个问题,其实可能是,因为我们是做了一个单线性的一个差值。

那我们其实可以进一步的把它改成一个,多线性差值来减少这个变换带来的影响,那当然这个mac linux给你其实有一套的这个嗯,有一系列的工作来解决这个问题,那当然我们这里就不讲了。

大家有兴趣的话可以去读读这个paper,这个这个cosy的课程,还是讲的比较比较详细的,那我们今天主要是提的这个另外一个思路哈,就是一个所谓的非线性变换,或者特别更加重要的是非线性理非线性变换。

里面这个啊基于队友虽然数的啊,这样一个蒙皮技术,那d q s这个其实也是很常用的,一个一个一个蒙皮变换的一个方法,那这里其实实际展示的效果就是,原来这个如果对于一个绑定姿势,是这样的一个一个骨骼啊。

外面的蒙皮如果是l b s,如果是线性变化的话,你知道它转180度,它就会变成这样一个姿势,但如果是d q s的话,你会发现它其实相对来说是更加合理一点,就虽然说我们先不管它是不是真是不是对的。

但至少看起来应该是合理的,就比如说正常来讲,这个东西转180度之后,那我其实应该看到的话,那是我的蒙皮,其实大概也是转悠耳朵啊,那所以说这个其实是更加合理的一种方式,当然这个时间我们还是要回顾一下。

就是回到前面那个问题,我们知道这个问题就是刚才我们说的那个,就是这个退化的情况,就是中间缩成一个点,这个情况他出在哪儿了,其实很大一个成问题是在于前面的部分啊,因为后面这部分因此不管怎么插值。

它都是一个合法的一个一个一个位移,但是前面这个问题我们知道它是一个旋转矩阵,旋转矩阵必须是对称阵啊,sir必须是正定啊,哎呀老臭了,必须是一个正交阵o那这三战是一,其实是一个非常强的一个性质。

就是我随便对他做线性差值的话,它是不再是正常阵,那当我们在那个前面讲啊,旋转的表示的时候啊,首先我们还特别讲过这件事情,就是为了能够解决这个问题啊,那我们其实提出了很多不同的这种,差值的方式啊。

提升有一种一些差距,就比如说sl啊,就是我们知道这个对于旋转矩阵,我们不能直接做线性差值,我们需要在那个query啊上面做slb,那可以完成这个工作,或者说其实可能我可以表示成一些其他的方式。

比如说表示成欧拉角啊,比如说表示成这个轴角,那我就可以直接插值,插值之后也是一个合法的旋转女神,那这样行不行啊,这样对不对呢,只要你试过就知道了,这件事其实是不对的。

就是我只去单独的把这两个部分分别进行插值,特别是前面这部分,我就不管用什么简单的方法,我对它进行插值,时间很有可能出现一个非常非常差的效果啊,就是本来应该是一个,整个就是用lbs算出来的结果。

他这个人还是看起来是一个正常的一个状态啊,就虽然说这个可能有些artifact,有些这个carly rapper的问题,但整体这个角色看起来自然的,但是如果说我只是简单的对这个旋转的部分,进行插值。

那其实经常插出来的结果,就是说你会发现在这个影响在交界的地方,它会出来一个非常奇怪的一个一个位位移,那这个其实出现这样一个姿势的话,本质上是因为这个蒙蔽上的点,被你旋转到一个新的非常非常不对的地方。

但是出现这样的一个效果,那为什么会出现这种情况呢,其实主要问题在于这里有一个概念是什么呢,是那个center rotation,就是旋转中心的这样一个一个概念,就是说我们当我们写一个rx。

比如我们写r乘以x的时候,当我们写r乘以x,如果r是一个旋转矩阵,那实际上我们隐含了一个条件,是说实际上我们是围绕着原点坐标,原点啊,因为如果说我们要对着另外一个点,进行旋转的话。

实际上你需要做的应该是什么,应该是r2 乘以x减掉那个点,那差用r旋转,然后再加上那个点啊,那这才是你的对另外一个点的旋转,所以说实际上前面这一块,我们相当于是对坐标,坐标原点做的一个做了一个旋转。

那在这种情况下,我们简单对它擦差值的话,其实插出来的全都是,相对于坐标原点的这样一个变化,那这种变换实际上大部分情况下,它是跟后面这个位移的差值是不能配合很好的,就是因为这个配合的不好。

就会造成你这个最后这个位移就会乱掉,那这是一个非常重要的问题啊,所以说实际上像比如那个迪克斯啊,其实是为了解决这个问题来提出的一些方法,然后我们这里稍微再啊在这个改一些符号啊。

因为为什么后面这个表达方便,那我们知道这个旋转矩阵r它是一个soo 3的,一个就是所有的旋转矩阵构成群,是一个soo soo 3群啊,这应该是一个啊,应该是一个,哎呀我忘了中文叫什么。

但是就是soo 3这么一个,我们可以用s3 来表示这样一个句,然后类似的我们任何一个位移啊,任何一个变换变换是什么,变换是一个r2 乘以x加上t啊,这样的就相当于把一个就是r。

只是把一个这个点睛旋转的那r加上t,实际上我是把一个东西把它旋转之后,在移动了一点啊,所以说实际上这个移动,我们可以写成一个这样的一个形式,就是写成一个这样一个矩阵,这样一个矩阵乘以x一啊,就是乘以x。

那时间得到效果其实就是r乘以x加上t,那这个矩阵其实应该是一个啊,应该是本来是应该,应该是应该是一个棋子坐标的一个变化,那当这里关键就是说嗯比较重要的部分,就是前面这个旋转矩阵,还有我的位移。

实际上是做了这样一个,先旋转再位移的这样一个操作,那么可以稍微简化一点啊,就只是为了记录方便,我把它写成这样一个形式,那就说记录了我整个这个位移的过程啊,这个变换的过程里边有一部分是旋转。

有一部分是平移啊,能够成为这样一个东西,那这个所有的这些旋转加上平移的组合,构成了一个啊刚性的一个旋转群啊,刚性变换群或者说s3 ,它就是代表了,就是在这样的所有的这种变换之下。

我这个物体比如它原来是一个正方形,我变换之后它还是一个正方形,而且大小不变啊,因为它是就是刚性的变换,构成这样一个区,我们前面提到了在sol 3上的一个差值,就是我们在旋转进行插值。

那我们其实有很多种不同的方式,特别是比如说r是一个旋转矩阵的时候,那我们其实一种一种方式说,我可以直接把旋转矩阵每一项进行插值,拿差值之后,你会就本来我们旋转,应该大概是分布在这么一个圆周上。

才是一个合法的旋转,但是呢我们在中间做个差值的话,你会发现中如果线性差值的话,那中间这个点会不落,不是落在这个圆周上,那这时候可能就是有时候会出现一些问题,那我们前面介绍的像是比如说slp啊。

其实非常重要,就slb他做的事情,其实就是说,我不是在这样两点直接连线上进行插值,而是在这样的一个圆周上进行插值,那这个差值其实可以保证,我这个点始终是落在圆周上啊,并且能保证他这个始终是一个合法的。

一个一个旋转,那类似的时间我们前面做这个差值,其实很出问题的原因也是因为s3 好,我们大家也可以想象,它是一个类似于圆周的这么一个结构,那这个结构上,如果说我们直接做两个变换之间的差值。

那其实它也不能保证啊,这个点是落在这个圆周上的,他肯定不会落在圆周上啊,那这种情况下,实际上这个点这个点会出现一些,特别是比如说两个点,两个变换分别在这个圆锥的两边的时候。

那其实它中间有个点是非常非常退化的,其实就刚好对应的,比如说ky rapper,实际上就大概是这样一种情况啊,它会插值到一个退化的一个点,那我们其实是希望能够做什么样的差值呢。

就是类似于我们对旋转的差值,我们是希望这个差值的方法,是保证是沿着圆周进行差值的啊,这样会可以保证我这个差值点是在这个一,始终是保持在这个圆周上啊,那这样的话是可以始终保证,我在任何一个t时刻啊。

差值的时刻或者混合的方式,可以保证这个混合出来的结果,始终是一个啊合法的一个刚性的宣传,就它还是属于s3 的这样一个范围,那当然这是我们想要做的事情,那当然对于这个旋转来说。

我们当时介绍了一个非常重要的一个量啊,coery就是四元数,然后在四元素基础之上呢,我们其实也介绍了什么,介绍了snp,或者其实不用slp,我们哪怕是先做一个直线差距。

然后再做一个这个一做这个再把它project,再把这个这个投影到圆周上,其实都是一个合合理的一个一个一个解法,当然如果说我们是希望能够把这样一个slurp,和这个coturning的这样一个概念。

把它扩展到一个同时又有旋转又有差值啊,sir同时有旋转又有平移的这么一个啊,这么一个transformer的一个一个,刚性变换的这样一个场景里面去,那这个其实是一个就是一个,就是dq s所做的事情。

所以dcs,那当然全称就是实际上dio dual turning skinny,就是队友四元数的这个磨皮的磨皮技术,dq s,那他其实主要的一个非常重要的一个思路,就是说。

类似于我们可以把一个旋转表达成一个coery,表达成一个四元数,我们其实是可以把一个旋转加平移的,这样一个刚性变换表达成一个dual cut 0,就一个对偶四元数,然后在队友四元数进行所谓的差值的操作。

那其实就可以很容易地实现我们想要的效果,当然我们这稍微多讲一,就是稍微介绍一下什么是对偶四元数,那首先介绍一下什么是对偶数啊,对偶数实际上你可以再回想一下,我们当时怎么最开始说怎么定义一个负数啊。

负数的话我们定义是说一个负数x,它的定义是a加上b乘以i,那i是一个复制单位啊,它单位就是这个i是什么东西,其实我们我们不用特别关心,因为它本质上就是一个标志,我们只是认为这个标志满足一些性什么性质。

这个性质就是i的平方等于-1啊,这是这个复数的定义,那类似的对偶数的定义,它其实也是取了一个标记,一个记号,这absnoon,那我们是要求这absaloon的平方等于零,然后同样把x写成这样的形式。

那这个时候x是一个对偶数,当然这个其实是以大类的这个数学概念,因为整体来说应该叫应该叫应该叫超超负数啊,数啊就是在那个复数之上定义的数,其实都是属于这一类,但是都有数,那定义是特别注意的地方。

就是说这个absence的平方等于零啊,这是一个对偶数的一个基本的一个定义,然后剩下的其他定义,其实可以直接从这个复数进行搬过来了,a加b f也是a加b i那共轭啊,其实就是把这个负数的这部分。

这个有标记的部分主要是正的变成负的,那是共轭,那乘法,那其实原来我们在复述的时候,实际上是是把它展开,然后再合并同类项,那本来还有i的算了,这个写错了,应该是i他还有i的部分,那就是ac啊。

a d加bc啊,然后前面ac是不含i的部分,然后这个负减掉bd是因为b乘以d,然后后面有i方,i的平方等于-1吗,所以说前面这个啊这个是值还要写错了,那前面这部分对于对偶数来说,时间是结果是一样的。

但唯一不同点在于哪呢,原来这个前面这一项是没有那个负数里边负的,bd这一项,因为什么呢,因为i的平方等于-1,但是absent的平方等于零啊,所以说就没有这一项啊,其实可以类似的,可以从这里去推导出来。

那如果说我们考虑到这个嗯,队友的队友输的这样一个这样一个定义,那我们其实可以进一步的,把我们的四元数给扩展一下,那原来四元数的表示就是一个coin啊,就是四个数表示一个啊。

四个四个x y z w表示一个四元数,但它实际上对应的是一个旋转轴,加上一个旋转角这么一个形式,那对于一个四元数来说,我们可以把原来这个对偶数里面的,a和b两个标量,我把它直接代换成两个四元数。

那构成的这个东西就是对偶四元数,那这里边其实q0 和q都是两个四元数,然后只不过在q的前面,我加了一个,加了一个这个队友的这样一个单位啊,那构成了一个队友虽然数,所以首先一个队友四元数。

因为一个四元数里面有四个参数,所以一个队有四元数,时间有八个参数啊,分别是在这个队友的两边,那其实类似于我们前面对于四元数的这样一个,定义的这样一个推导,我们其实对于队友。

虽然书也可以有很多类似的性质啊,乘法其实跟前面的那个对偶数的乘法其实很像,因为主要是就是需要考虑的,就是说我们这个absm的平方等于零,这个性质我们可以很容易地把这个两个数啊,把它写成这个对偶数的形式。

然后做一个乘积作为一个合并同类项目,那其实也可以得到类似于这样的形式,那当然对于队友虽然数来说,其实有一个非常有意思的一个特性,就是说我们一般说负数就是复变负数,它的共轭只有一般来说就是一个。

就是我现在把那个单位那个部分,把它给变成-1啊,就变成公共了,然后四元数的共轭也是也是也是一一对应的,其实因为四元数我们有三个三个这个虚数的积,i j k,然后我们其实讲虽然数共轭的时候。

其实就是i j k或者它的向量的一部分,然后取个相反数来实现它的共轭,但队友虽然说来说,我们一般其实它是有三个共轭的,第一个共轭呢其实是四元数自己的公恶啊,就我只对四元数共轭,这里没有写出来。

但实际上这个q0 的星啊,其实代表着说,我把四元数的这个i j k的部分啊取负啊,其实代表四元素的功能,然后另外一部分是对偶数的共轭啊,那其实就是只是把队友的这个前面去取你啊,取成负数。

然后最后还有一个就是说,同时对对这个对偶数和这个四元数,同时取共轭啊,大概是这么一个形式,但不管哪一种共轭时间可以证明他都会满足啊,有点类似于比如说这种矩阵求啊,矩阵求逆啊,或者矩阵求这个转置啊。

这样一个类似的一个性质,就是q1 q2 的共轭啊,等于q2 的共轭乘以q的共轭,它有这样的一个代换的过程,那到这样一个定义之下,公握的这样的一个定义之下呢,实际上一个四啊。

队友虽然数的长度或者它的这个nm,它的发型啊,范数啊,其实是它对应于次元数的那个共轭,乘以它本身,那得到的是一,其实这个算数本身啊,再开个根号,它其实是对应的是一个对偶数啊,是一个对偶数。

因为前面是一个标量,后面这个其实也是一个标量,它是一个对偶数,这是一个对偶四元数,它的这个nb它的范数或者它的长度,那接下来既然我们已经定义了这个长度,那我们其实可以类似于。

我们定义单位四元数的时候那个概念,我们知道单位四元数其实就是任何一个四元数,除以它的长度,得到的是一个长度等于一的一个四元数,那就是单位四元数,那对于队友四元数来说,我们同时有同样的一个量叫做队友啊。

单位队友虽然数,那其实也就是任何一个四元数除以它本身,或者再或者反过来说,因为我们知道一个次元数,它的长度或者它的范数表示成这样的一个形式,那么为了能够让这个参数的范数等于一,它实际上是要求。

首先前面这个四元数是一个单位四元数,就是这个十,就是时不时先担心担任十部这样一个实数,这样一个角色,这个四元数它应该是一个单位四元数,同时后面这一部分要满足这个队友部分,和这个实数部分。

他俩的点乘应该等于零啊,这是我们这个对有资源数是单位资源啊,单位对有资源数的一个一个要求,那在这样的一个定义之下呢,我们其实是可以知道有另外一个结论啊,也不是我们可以知道我们会有这样一个结论。

就是类似于四元素,我们知道任何一个三维的旋转都可以唯一啊,不是唯一的,都可以转化成一个单位四元数,表示那类似的任何一个刚性变换啊,构成了这样一个变换,任何一个这个变换都是可以转化成一个单位。

对偶四元数啊,这是一个一个结论,那这个变换大概是可以这样子,就是比如说我有这个变换t j x这是我的变换,它等价于是说我对x首先用r做一个旋转,然后之后加上t这样一个平移。

那这个平移其实可以表达成一个队友,也就是实数的部分,以及bq absolon,那这个实数的部分,其实对应的是我这个r就这个旋转,或者说这个前面那个四元数,其实就是r这个旋转所表示的,四元数的那个形式。

那后面这个t在这个队友的部分,其实可以用这样的一个1/2 t,乘以r来算出来,那这里当然这个t是已知的,因为它是一个它是一个这个平移啊,就是xyz的一个向量,那这个向量实际上我们是可以。

表示成一个纯四元数,什么叫纯四元数,就是说w x y z嘛,四元素四个量,其实前面那个w就是它的那个这个,这个标量项应该是零,然后这个时候后面的xyz那构成了一个纯色元素。

所以实际上就是说我们在可以后面这个队友,四元数里的那个队友,像我们是可以通过一个纯t的所对应的,纯四元数乘以r这个四元数啊,通过四元数的乘法来进行得到啊,这是我们这样的话把这个一个旋转的一个变换。

刚性变换r a t把它转换成一个单位都有,虽然说这样一个形式,可以通过这样的方式进行转换,那类似于同样类似于我们四元素的这个,这个应用啊,使用方式啊,我们知道四元数,比如我用四元数去旋转一个向量。

那实际上他是做了一个,类似于那个三明治一样的这个乘法啊,首先是四元数乘以向量,然后再乘以三数的这个公好,那实际上我们是这个虽然数的乘法,那对于队友虽然数来说,其实有一个类似的一个结论。

就是如果说我想对一个向量v啊,对它进行一个刚性的一个变换,那这个刚性变化我们已经表示成一个对偶,虽然数的情况,那这个时候变换之后的这个v啊,其实也是类似于这个虽然数的这样一个这样一,个乘法,不好意思。

那当然这里其实要求是什么呢,就是说这个v啊,就是我们在变换之前,其实在,因为整体的一个计算是都有四元数的运算,所以我们需要把一个向量v转化成一个队伍,四元数啊,这个v所对应的。

原来这个向量v所对应的都有四元数,实际上是一个啊,前面这个十部是一个一啊,后面这个对偶像是一个纯纯啊,虽数这样一个形式,然后这里面那个q这个这个心啊,这其实是一个我们刚才提到的第三个那个工作。

我知道队友队友虽然是有三个工作啊,其实第三个就是说,我同时对这个队友的部分去负,然后同时也对这两个部分的四元数,单独去做它的共轭啊,形成这样的一个东西,所以说如果在这样一个定义之下。

实际上这个它的这个计算过程,其实跟次元顺利算过程是非常一致的,那同时从前面这个表示啊,其实我们可以得到一个跟四元数,一个类似的结论,这个结论是什么呢,就是说四元数里边,我们知道任何一个旋转可以有两种。

可以表达这两个不同的四元数啊,这两个四元数互相为对方的这个相反数就取负,那对于队伍虽然说来说,其实我们可以得到同样的结论,就是任何一个刚性的变换,我们可以表达成两个队友四元数啊。

然后这两个队伍四元数呢又互相是这个相反数,这是我们这样一个这么一个结论,因为这个结论本质上来说是因为r2 的,这个就是四元数本身的那个那个变化来决定,比如说我们比如说q,如果说副q的话。

其实这里就是对应的是负的q0 ,然后和负的q absong,首先负的q0 和q0 应该都是对应于r的,都是一个旋转,那这个,啊ok然后这个这个如果是负的啊,负的q的话,你想想想,ok这个稍微有点麻烦。

从这个角度来看,但实际上如果说你看到前面变换这部分,其实你可以表明一得到,就是如果说前面是一个负q,后面也是一个负q的话,那其实最后乘出来的结果,应该是还是原来这个这个旋转,所以总体来说的话。

我们其实是可以知道这样一个队伍四元数啊,它有同样的一个性质,就是q和副q代表是同样一个它一个变换,那这个时候实际上类似于这个cturing,类似于我们的这个这个四元数,我们其实是有这样一个概念。

就是说实际上这个这种表示,是原来s3 或者soo 3的一个double cover,就实际上我们相当于每一个表示,每一个点就s3 或者s o3 里的每一个变换,我们都有两个互相为相反数的这样的一个。

一个一个队友,虽然数或者虽然书的表示那什么,就是其实其实这种double cover会带来一些好处,就说如果是一个简单的一个cover,就比如说这是这样一个情况,我们知道t一如果和t2 。

它可能是放在一个大圆的两面,那这个时候如果是t1 t2 直接做差值的话,它会差值当中一个点,这个点是说,我们这个点可能是这个整个这个一个,全零的一个点,那这个点实际上是非常退化的。

我们是没办法把它找到一个合理的映射,把它变成一个合法的一个选项,这个一个变换,但是对于这种double cover,就是这种双层的覆盖的情况下,比如说我们如果说q一和q2 ,在这个大圆上离得非常远。

比如说q一在这里,然后q2 在他的对面,正常来讲,如果说在这种情况下,如果q一和q2 直接做线性插值的话,它会穿过零点,那零点附近其实是一个极点,那这个点其实是没有任何意义的。

而且我们也很难把这个零点去,把它映射到一个圆柱上,一个合法的一个点,但是因为考虑到q一和q2 ,他俩是对应点的两个,两个表示,两个点表示的是同一个旋转,或者同一个这个钢琴变换,我们实际在做差值之前。

我们一般来说会把这两个点把它挪到,通过这个求这个对应点,求求求这个求负的这个操作,把它挪到对面的位置上,那这样的话其实可以保证我是任何两个变换,在这个圆周上的距离是小于啊,这样半个圆周的。

甚至右其实可以要求它是小于啊,差不多小于1/4个圆轴,应该是那在这种情况下,我们任何两个这个点进行差值,我们其实是可以把它直接做一个线性差值,然后再把线性插值这个点做一个呃单位单位化。

那就除以它的这个长度,然后把它投影到这个单位这个圆的上面去,这个操作实际上是始终是可始终是合理的,因为这个投影唯一的要求就是,下面这个长度是不等于零的。

而我们前面提到的这个double cover就是双覆盖,它是满,始终可以满足我这两个点的连线,是不会过这个中心点,就是这个零点,这样的话,始终它可以保证这个这个投影是合法的。

但如果是不是一个double cover的这样一个表示的话,它是有可能穿过这个零件,特别是比如说刚刚这个rotation旋转,就是旋转矩阵,其实是非常一个典型的,就是它不是一个double cover。

那这种情况下,你是可以看到它两个点,是你可以穿过一个全零的一个点,那这个点是不可没办法他应收回去的,然后这种情况下就是这所以说就是说非常简单,如果当我们把它表达成一个对偶,四元数的情况下。

我们是可以做这样的一个啊映射啊,做一个投影,把它单位化啊,实现一个简单的差值,那这种差值的方式其实就是dcs啊,当然这个原来那个paper里面,他把这种方法叫做dlb啊。

dual concerning the linear本领,但他是带了一个呃单位化的这样一个方式,那这种情况下,这个整个计算是相对来说比较简单的,就是因为本质上这个所有的前面上面这部分。

其实还是一个线性的线性的这个计算,然后当然除了一个数啊,稍微复杂一点,但总体来说是一个比较简单的一个,一个插值方式,当然有一个问题,就是我们前面讲四元数的这样一个差值的时候,我们其实也提到了。

对于四元数来说,我们是需要就是这种差值,其实是首先是它还是可以的,基本是基本上结果还是不错的,但唯一的问题就是你这个差值的过程,比如说我t从零到变到一这个过程,他在圆周上的这个投影啊,不是均匀。

也就是它这个是有一个角色是不恒定,但是虽然说不恒定,但实际上实际试验的效果,就你在大部分应用里边,其实你可能没有那么大的影响,那其实类似有同样的问题,对于对于队友资源说来说,如果直接简单做这个差值的话。

就用这种方式做这个差值的话,就是效果还是还是很好的,但是有唯一的问题,就是它这个差值的速度可能也不是零,阿sir也不是恒定的,所以这是一个一个非常重要的问题,那当然怎么去把它恒定恒定化呢。

我们知道对于这个虽然数来说,我们一个插值方法叫slb spherical linear,interpolation,它是可以保证这个连续性的,就是这个速度是恒定的,但对于stole虽然数量来说。

其实有一个类似的一个操作,一个计算啊,叫esylp,就是scroll lab,就当这个是基于那个scrose theory的,一个一个一个一个一个理论了,我们在这门课里就不再多介绍了。

大家有兴趣的话可以自己去了解一下,那当我们知道最简单的,我们通常讲ldq s的时候,我们实际上指的就是这种材质,这种材质是比较简单的,唯一的就是说我们只需要把一个刚性旋转啊,特别是回归的钢琴旋转在哪。

刚旋转是来自于我们两个啊,每个关节每个骨骼它在当前姿势下的朝向,相对于它开始的时候,那个朝向的这样的一个朝向的差,那构成了这个旋转啊,以平移把它转换成一个队伍次数,然后把每个关节的队伍虽然数。

分别做一个线性差值啊,再加上单位化,那其实就完成了这个decrease这个计算,当然当然队友虽然说其实他效果最好的,就是这种,就是我们知道lbs那个carly rapper的那个问题。

就是我有一个twist,就是我这个沿着自转轴转眼80度,这种就是非常典型的lbs artifg,但对队伍,虽然说它其实结构看起来是比较合理的啊,至少是比较正常的,但是队友四元数有都有四元数的问题。

他问题是什么呢,它主要问题是说当我做这种,比如说我把胳膊肘弯起来,这种这种这种姿势的时候,你会发现它这个胳膊肘的这个部分,这是其实是对我虽然说一个就d q s。

一个非常经典的也是他的这个artifact,就是它的这个缺陷的一个问题,当然这个问题实际上有些时候还是挺严重的,特别是我这个blending with,这是一个非常非常有意思的一个比较。

就是同样的我对不同的这个布兰妮位置,首先就是说这个这个点它的权重过度有多光滑,你会发现这个过渡越光滑的时候,其实这个artifact会更加明显一点,就是对同样的旋转不同的位置,那linear的不好。

其实可能变化不是那不是那么大,但是这个dcs的时候,它其实这个隆起也会变得比较明显,所以这是其实是队友虽然数的一个一个,特殊的问题,所以不管是lbs还是dk s。

其实它都是都是不能不能完全解决所有的问题,就是它有各种有一定有一些优点,那也有一些缺点啊,这个缺点其实看情况,我们可能也是需要去避免的啊,这是一个这一个另外一个啊问题,但是不管这个哪一种方法。

其实dq s和lbs其实都是什么呢,就是说它是一个不需要额外的信息的啊,那就他唯一需要的就是当前角色姿态,加上一个权重,那这个权重其实是跟字,不好意思,这个权重其实是跟姿态是无关的。

就是他其实在一开始就定义好了,不管我做了什么姿态,他都是这个权重,当然还有些其他的思路啊,就比如说回到我们前面那个问题,我们知道lbs的一个缺陷,这个缺陷是什么呢,是哪里来的呢。

就是说比如说我们原来是原来这样一个蒙皮啊,里面有骨骼,骨骼没有画,这还有两个点p和q,那如果说把这个骨骼把它旋转成这么一个形状,那我们知道p的p的位置,因为被这个骨骼把它转到了一个批片。

被左边这个国赚到了p两片,然后最终那个嗯lbs权重啊,就当这里稍微简化了一下,我们把原来那个r就用t来表示了,做这个混合之后,实际上最终这个点应该是p撇和撇撇撇啊,中间这个位置。

那当然这里其实有些时候出现一些问题,就比如说在这种情况下,你可以看到它它这个点就是比较先进啊,陷进我这个这个胳膊肘里面比较多啊,那这个时候呢,因为这本身是我一个线差值带来一个缺陷。

但如果说我们想要去得到更好的效果,比如说我想让它不要伸进来整,我想把这个p点,我希望差值之后啊,它能够在这个位置可能会更好一些,那这个时候我们该怎么办呢,几种方式就是说因为这个点落在这个位置。

是因为我在原来这个关节顶点上啊,就原来这个蒙皮顶这个顶点分别做了变换,然后差值得到这个点,那如果说我们想要修,那其实一个想法就是说我我不,我我在做变换的时候,我在做这个混合的时候。

我不是对原来蒙皮上的那个点做这个变换,然后再混合,而是把这个原来的蒙皮让让它往外突出一块来,然后突出一个,比如出一个delta,一个一个一个小位移,然后把这个小位移之后的这个点,通过两个骨骼分别变换。

它其实变换到这个位置和这个位置,然后如果说我们就认为,这两个位置的中间的差值点,是我对应于p点的那个蒙皮的插值点,那这个结果看起来就比较光滑了,ok所以这个关键的问题就是说,我是希望能够根据某一个姿势。

初始的这个位置之后,它能够让我比如说最简单的,比如lbs的差值都能得到比较好的效果,它肯定应该是跟我的这个旋转角度是相关的,因为我们知道如果旋转是零的话,没有任何缺陷的。

它只是旋转变大的时候才会产生这个缺陷,然后这个变化应该是随着旋转中变得越来越大,那个区号越来越大,首先通知是跟我这个位置相关,其次是要跟这个fa相关啊,就是跟我这个旋转角相关,这个r b s。

那当然这里有个问题,就是说这个delta这个函数我们该怎么定义啊,这是当然是一个非常重要的一个问题,但是灰烬当然其实有一类方法来定义这个函数,就是所谓example based,基于样例的形变啊。

其实非常简单的一个一个一个思路啊,就比如说我有两个形变的一个两个两个形状啊,一个是这样一个球形,完整的球形,一个是扁的球形,那我们其实这两个形状做一做差值,我们其实可以实现一个从完整的形状。

变成扁的形状了,这样一个这样完整的形变过程啊,其实我们其实可以用它来仿真,一个一个球落地的这样一个动画,因为本质上落地你就是变扁,然后弹起来再变本,类似于这种形式,但这是两个点的差值,两个形状的差值。

我们可以用一个简单的线性函数,我们不断的用这个线性函数进行进行,进行进行构造,那如果点更多一点,比如说这里有五个不同的形状,那实际上我们在这五个不同形状之间,我们同样的可以做一个,比如说简单的线性差值。

当时我就是概念上的写成这样的形式,但实际上这个形式会稍微复杂一点,因为这个取决于这个形状我该怎么定义,比如说可能也许是这个形状上,每个形状都是用五个点来定义它的形状了,那我其实对应的就是这五个点之间。

用一个位置啊做一个线性插值,那如果这五个是一个五个不同的函数,那我可能差值的可能是对应的函数的参数,那以此类似,但总体来说呢,我们其实是可以构造这么一个空间,那这个空间里每一个点。

我们可以用某种方式计算出它的权重,然后用这个权重权重,把这五个不同的形状做一个差值,来得到一个新的形状,那整个这个空间其实就是一个blend space啊,就是一个ban space,它可以实现在里边。

任何一点我都可以对应一个形状,然后这个形状是由这五个点加上这个点的权证,共同确定的,那对于我们当时刚才那个问题,首先我们要完成一个什么功能呢,我们其实是想要知道,因为我们需要在每一个不同的角度啊。

对于一个关节来说,它是这个关节的旋转角度,但是对于我们整个姿势来说,因为我们这个关节上,它有比如说20个不同的关节,那时间大概比如说可能有几十个参数,那这个根据这个几十个参数,在对某一个姿势下。

他效果他那个姿势是这个形变是比较好的,比如说我有若干个不同的这样的一个样例,然后每个样例分别对应一个姿势,那接下来其实就说我是希望根据一个新的姿势,我希望去计算一个对应的,我该去在这个姿势下啊。

那这是一个我们这样一个问题,那这个方法其实也叫pose pose based defamation,就是实际上我们是在那个,我们其实改掉的是bad pose下的那个蒙皮的形状。

然后才让我们比如说一个简单的lbs,都能实现比较好的效果,那当然会回答我们经典的差值问题了,我们其实这个差值问题已经在不断提到了,我们就是上节课讲这个learning with method。

其实它本质上也是一个差值问题啊,就是当时那里面每个点是一个动作,那我们这里每一个点实际上对应的是一个形状,那这个形状,那在这个抽象来说,描述来说就是我给了若干个点啊,若干个点,每个点它的坐标是x。

它的值是y,ok这个x可能是很高维的啊,当然这里我画成一个平面,但它可能是很高维的,但整体来说,这个点对于高本来说是比较sparse的,比较比较稀疏的,那我们其实想要知道,对于空间里一个新的一个点x。

它的对应的y是多少,但这个实际上会比我们前面讲的,这种线性差值啊,lp啊,sorry,这个线性差值啊或者样条差值要复杂很多,主要是因为我们差值,这个对象x它的位数可能比较高。

那这类差值其实也有另外一个名字,叫做scattered data diablation啊,就是我这data是在空间里随便散步的,那我需要去学一个嗯函数,或者我从里边构建一个曲面啊,这个曲面其实定义好了。

可以帮助我们去给出一个新的点,我得到它的值,那当然实际上scatter data,interpolation很多种不同的方法,比如简单的像linear interpolation啊。

其实也是一类型的方法,比如说我可以把一维的lan扩展到二维,扩展到更高为还是其他的,比如说gosh process,我们前面讲那个a learning based animation的时候。

我们也提到以前一些方法用高深process,用高斯过程来给我们建立,这个建立这么一个曲面,还有其他的方法,比如rbf的方法啊,radio basis function,那我们今天稍微讲一讲。

就是rebase方法,其实也是个非常简单,也是非常经典的一个方法,就是说我们前面知道每一个点,我们给出了若干点,每个点有一个空间的位置和一个值,那我们其实可以假设这个点,它的值会从这个点为中心哎。

一个圆周扩散出去啊,一个圆周扩散出去啊,比如说这里有五个啊,六个点啊,其实每个点都会扩散出一系列这个圆周,那我给出一个新的点之后,那这个新的点它受到所有这些点,它扩散出去的这些圆周的这些值影响。

那个值应该是由这些扩散出去的点来共同决定,那这个就怎么决定呢,就rbf是说假设是说这个点对每一个样本点,对这个点的影响,是跟这个点到这个样本点之间的距离啊,有关的这么一个量啊,我们只考虑他们之间的距离。

而不考虑他们之间的相对位置,但实际上你计算了跟每一个点的距离之后,你这个点的位置其实也基本是确定的,那在这个基础之上呢,实际上r b f,它其实是通过这样的一个方式去进行计算啊。

当我们给出了一个新的点x这是我要求值的点,我计算x跟每一个样本点的距离,然后计算要慢点,知距离之后呢,我我用一个预先定义好的一个那radio radio basis。

radio basis就是我的这个呃这个叫什么来着,这么一个奇函数,这个奇函数其实给出的是一个权重啊,虽然说我直接用w,但其实这个才是权重,然后他对一些若干个值啊进行混合。

那最后得到的是我要输出的这个值,那当然这里条件是说这里有什么是不值当的,fi其实是知道的,我们预先第一好的,在给出一个确定的file函数之后,我们该怎么去计算w i啊,能够让我这个计算成立,那怎么算呢。

其实还是用我们前面用过的这个待定系数法啊,就说我们其实是要求这个差值函数,在我们给出的这些点上,它的取值应该等于y那达到这样一个数值,所以实际上我们现在有n个点,那其实有呃对应的有n个方程。

那n个方程我们写成一个矩阵的形式啊,写大概是这样一个东西啊,左边是一个矩阵乘以所有的w,然后呢,啊然后加上所有的y那构成这样一个方程,那当前面这个矩阵其实可以看到,其实每一项其实咱们每一项每一个xy啊。

第第二行,第j列的这个这个数其实刚好是等于f,然后就是i和j之间的距离啊,构成的这样一个函数,那接下来就是比较简单了,因为这是一个线性函数嘛,啊线性线性线性方程我们其实对它求解。

把这左边求逆乘到右边去啊,那其实就得到了w,那得到w之后呢,那我们其实给到一个新的x,我们就可以计算y的值,那当然时间这个rbf就是这个这个basis function,可以有很多种不同的这个定义了。

比如常见的高深啊,高斯函数啊,一个类似于这样的东西,所有这些其实都是求对称的,它只跟r只跟这个距离相关,还有些其他的,比如说这种反对者啊,inverse就是就是这个平方求逆,然后还有一些其他的这种方式。

总体来说可以有不同的不同的r b f,它会带来不同的光滑性啊,还有不同的这种这种卖差的能力,然后如果说我们用rbf结合若干个,那它就可以实现,比如说给出一个新的姿势,那我们就可以得到我在这个姿势下。

我再用这个lbs进行计算他的这个新的位置啊,时间用计算出lbs这个skinny,那这种方式,这个这个就是完成了一个,就是可以让我们帮助我们实现一个更好的一个,形变效果。

那这个方法其实叫pose space defamation啊,这个也是一个很老的方法,也不是很老的一个很经典的一个方法,而其实在很多地方还是在在经常被使用的,那在原始的科论文里边的pd。

其实它是用rbf来实现这个差值的,但是实践我们也知道这个差值方式有很多种,你也不可以不用2b你也可以用,比如说,甚至我可以学一个神经网络来做这些事情啊,只要我给出一些像本点。

那当然这里最重要的是说我们这个效果啊,我们要实现比较好的刹车效果,要求我们必须有比较好的这个样例啊,样例的形状,那这个单位形状,通常来讲我们可以是手工上舰的啊,当然我们也可以通过一些比如三维扫描。

可以扫描一个真的人,它在不同姿势下,他的这个身体表面是什么形状啊,可以根据这个来算一个这样一个插值函数啊,这也是一种方式。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

当然这个实际效果,这也是比较当年的论文里的效果,lbs的各种artif。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

不好意思,当然还有一些就是这个方法本身,可能有些有些问题需要去想,比如说我们是不是需要对每个顶点,就是我们是插值的时候,是不需要插插值整个形状,因为知道我们身体如果我可能一个形状,一个插值点。

一个样例的形状,可能只需要我只要关心他的手臂,而不需要关心他的这个角,那其实可能你可以有些根据情况会做一些调整,另外就是说还是那个问题,就是我们这个形状,我们差值差值的时候,那个x它代表了一个姿势啊。

那这个姿势我是用所有关节的旋转表示,还是需要用,还只需要考虑一个局部,比如说可能只考虑胳膊的时候,我是不需要考虑腿才行这个姿势的,那这个其实也是一个实践上具体的问题,我们用r b f啊。

还是用其他的方式啊,这就不同的这种这种能有不同的实践方法啊,当然相对来说我们其实就p s d这种方法啊,其实我们通常来讲可以把它叫做example based,skinny,就是它有一些样例。

基于这个样例来帮助我们去做这个啊磨皮形变,那另外对于我们labs或者d q s这种方法,其实另外还有一个人也可以被叫做这个,scence of space啊,diation或者s s d。

但这两种方法来说,其实example base的这个方法,那好处就是比容易实现很好的这个quality啊,表容易控制,另外呢就是说比较容易实现这种所谓pose,dependent detail。

什么detail呢,就比如说有手啊,我们知道其实手就是很多人,手和你可能有些比较瘦的啊,这个这个这个人比如你手放下的时候,你可以明显看到这个手上青筋暴起哈哈,就是你的血管呢会会会疼起来。

那这种效果实际上用这个example的方法可以,其实可以很容易实现啊,就是你只要在这个手放下这么一个姿势里边,给他一个嗯这样一个样例的一个形变啊,是这个青筋起来的,那就可以实现这样的效果啊。

当然缺点就是说那我为了实现这个效果,我需要额外的去创建这样的一个样例啊,这其实是比较困难的,另外就是我量力很多的情况下呢,我需要额外的一个啊嗯这样一个存储空间啊,除此之外呢。

其实我们差值这件事情本身也需要计算量,而且就是可能不能插着函数,它的效果可能也不太一样,我们相对来说也需要更一些啊,更加细节的调整,那当然这前面只是介绍了,我们一些关于蒙皮的一些技术啊。

那当然作为两个样例啊,两个例子我们稍微讲一讲嗯,你这个新的方法啊,几个非常有意思的一个工作,一个就是s m p l模型或者叫simple模型,其实simple模型应该是呃好像是一几年哎呀。

忘记了116还是17年左右吧,反正提的提出来了一个嗯,一个人体的一个形变模型,那现在其实可以看到在很多很多场合,在本人主要是可能cv啊,就是特别是做pose mission,做这个人体姿态估计的时候。

很多人用这样一个snpr模型,它是什么,它主要好处是什么呢,它其实是可以自动的生成不同体型的人啊,然后不同动作加上不同体型,这个不同体型其实比较关键,那另外一个方案就是。

这个它的数据其实来自于这个真的人的这样,一个嗯这样一个扫描的数据,它这个模型本身其实就是刚好就是组合了,我们前面提到的几种方法,ssd啊,其实主要是lbs,然后以及ebs就post space啊。

formation啊,这两种方法组合完成这样的工作,当然这个细节我们就不会讲很多了,我们只是讲一讲大概它是怎么用的,那主要问题在于我们该怎么去啊,对一个大量的数据进行建模啊。

能够完成我们想要实现的这种对形状的形体,不同人体啊,形态啊,不同大小不同身体的这个这个大小形状啊,这样的这个这个定义,实际上我们其实上节课已经讲过了啊,或者上节课其实讲过了一个非常重要的技术啊。

就是pc啊,p c是什么技术,就是说我给出一大堆数据点之后,我可以找到这些数据点在某个方向上是最关呃,是这个他的信息是最多的,就是某种组合可能性是最多的,然后另外一方面,他其实也可以帮助。

我们去过滤掉一些噪音的影响啊,实现这种dimensionality,就是这个降维的这样一个操作,那当然pc它定义啊,就是说实际上我是找到一系列的方向uk,然后可以把这个数据,所以数据是映射到这些方向上。

然后我们可以保证映射过去之后啊,在这个方向的投影,它的方差是最大的啊,这是我们pc的一个基本要求,那pc我们其实是可以通过什么的,我们可以通过特征值分解啊,或者说svd这种方法可以很容易地计算出来啊。

这是pca的一个一个基本的一个概念,但如果说我们对这个人体数据做pc的话,那其实也可以看到,其实人他的几个主成分方向啊,分别对应了这种人的体型的不同的变化方式,比如说这像这个例子。

第一个主成分其实代表了很像这个瘦啊,瘦和胖之间的变化,然后另外的解释,可能这个代表这个男性和女性之间的变化,还有一些其他的这种变化方式啊等等等等,所以c s n p l模型啊,就它最主要的就是说。

我们如何用这个模型来建模,不同大小和不同体型的人,他实际做的就是说,我会把不同体型的这个人的这样的一个扫描结,果,把它做一个pc,那其实pc会给你几个量,第一个量代表了一个平均人,或者说一个平均的大小。

那后面若干个量代表的是我这体型,在不同的维度上发生了变化,那最终我在用的时候,我只需要给出我在每一个维度上,它的变化的一个范围啊,一个大小啊,其实整体就构成一个新的人,一个人的一个体型,那在在此之上呢。

其实我们前面提到了,我们需要加一点这种example base bloodsho啊,加一点混合形状来实现比较好的形变,sp i模型实际也是额外加了一个部分,因为本质前面这个t代表了我这个bpse下。

这个形状,它其实还有另外一部分,除了原来这个体型之外,它还加了一个跟姿态,这个theater其实是我们这里是表示是一个姿势,那其实加了一个姿势的一个线性的,一个还一个一个变换,那这个线性变换。

其实整体来说构成了我们的一个啊black sheep,就是我们前面那个那个调整啊,当我们之前前面介绍的post post base defamation的时候,我们其实那个纠正一下。

是用一个r b f来来实现的,但我们其实也提到了,就是说其实对于这种大量的数据来说,我们其实也可以用更加简单的函数,比如说r b啊,一个线性函数来去fit啊,来去这个回归啊,我们所有的点。

那simple model是因这里其实是一个怎么说,它也不是一个完全线性函数,但是也大差不差的是一个线性函数,它对c它是一个线性的,当然c它对于我的姿势参数来说,可能不是一个线性,这是sp l模型。

那它前面这个通过这两个方式,我们其实得到了在某一个体型,橘色的体型以及某一个姿势之下啊,它的原来那个形状,每个点的位置应该是什么样子,那剩下的部分其实我们就是加上一个萌新前重,加上姿势。

我们就可以用用一个一个a一个s d啊,就是我们的一个这个r b s或者一个dk s,来完成这个形变过程,实验就实现了这样一个效果啊,这其实就是散步模型做的事情啊,就他一个说。

我们可以给出一个不同体型的一个参数,加上不同姿势的一个参数,它可以生成一个不同体型的人,做不同姿势的一个非常高,质量比较高的这么一个这样一个角色模型,那另外一个例子其实也是非常重要的。

就是这个facial animation脸的表情啊,其实我在不断说话的时候,大家可以看到我的视频里,我就在不断的做出各种的表情,那这些表情我们在这个动画里面,我们会怎么生成呢。

但这里其实表情甚至有很多种不同的方法,其中一种方法可能就是我在脸上多加一些骨骼,因为本来我是人,其实就是比较下颌骨啊,你的这个这个形变,你的这个移动来产生你的这个嘴嘴巴的形变。

南方其实人脸其实还有一些更丰富的表情,就是它可能是你在骨骼上是看不出来的,它主要是肌肉的收缩带来这些表情,那这些表情一种方法是说,我可以在脸上加几块所谓的新骨骼,那这些骨骼不是真实的骨骼。

而是实际上它就是为了产生这样的形变,我通过调整这些骨骼的位置,来产生我这个脸的形变啊,这是一种方式,那另外一种方式呢,其实也是通过我们前面提到的这种所谓的,bend shape来完成。

就是说我这个脸的嗯,他的一个表情,我们可以认为是一个neutral的,一个无表情的一个脸啊,然后加上不同表情的这个位移,来产生了一个新表情,就比如说我可能就说一个500星点,就是一个人啊,闭着嘴啊。

睁着眼啊,这么一个这么一个这么一个表情,那这种情况下,比如说我可以加上一个左眼,一个闭眼的操作,那其实就相当于是我是把眼睛,左眼的这个这个这个是左眼,对于最左眼上的这些点啊,我加一个向下的偏移量。

那这个偏移量是可调的,从0~1,我分别对应于完全睁开到完全闭上,这样一个过程,那类似的我可以定义一个新,另外一个好black sheep一个形状,它是比如右眼张开,然后另外一个是对应的嘴啊,类似于类推。

然后把这些表情啊通过一些加权平均啊,不是加权平均,就是加权之后加到我最开始的无表情的脸上,脸上,那其实就构成了一个表情,从我们通过调整这些这些权重,我们就可以形成各种丰富不同的一个表现方式。

但从数据上表达,我们可以写成这样的形式,这个x代表我们整个脸每个点的位置,然后x0 代表一个什么,代表一个平均点,或者代表一个模板脸,然后中间这一部分我们可以是说一些可以定义。

可以自己定义的一些一些位移,比如说这种捏脸啊,其实我们其实可以对这个脸的形状做一些调整,然后最后一部分实际上是说我们刚才提到的,在这个调整之上,我们可以加一些偏移来产生不同的表情,那其实有一个问题啊。

就是说这个偏移是不是,就是说我们我们比如说把脸型改了之后,这个偏移是不是还还是不还能用,这个确实有这个问题,理论来说,你这个脸的表情的偏移,如果你想高质量的话,它应该是根据你这个脸型会发生变化。

但实际上我们会发现,其实大部分情况下,其实我们对不同脸型用相同的偏移,效果都可能是差不多的,那就别说闭眼,我不管这个脸长成什么样子,闭眼可能就是眼睑,眼睛眼皮上的点往下挪挪两公分啊,就闭挪一公分。

那就闭闭好了,那所以说这个其实可能跟脸型,反而就可能实际上并没有那么大的关系。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

当然了,如果说你想实现更好的效果的话,那当然有关系是更好,所以实际上我们一般来说,做这个脸的动画的时候,我们都是需要这么一系列的bloodships啊,就是混合模型啊,每一个混合模型分别对应于不同的。

比如说这个表情,那首先记录的是说,我们总是会记录这个混合模型,相对于我一个平均脸,好标准脸他俩的偏差,那这个时间是我记录下来的,那实际我用的时候,时间是把这个偏差乘上我要加的一个权重。

这个权重表达了我要做这个表情的程度,然后把所有这些表情的权重加权。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

然后加到这个平均脸上,那最终得到我这个新表情,但实际上其实大家也是发现,有一些系列表情是比较好用的啊,可以去用它来实现很多种不同的,这个非常复杂的这个种,或者比较好的一些效果啊。

其实这是一个一个简单的列表,那这个就是大家可以很容易,如果大家用的时候可以很容易找得到,就是那个啊应该是苹果哪个ark的,它在默认的这个表情好像是50数量,我忘了,反正是反正是这么多个表情。

就相当于如果说你给每一个表情定义好,比较合适的banshee,有点类似于这种,那它就可以驱动这样的一个啊角色啊,做出不同的表现,那当然具体来说,我们其实本来还有不同的方式了,刚才我们说的这种方式。

比如说眼皮是一个方,一个控制一个black ship,然后比如说嘴巴啊,向左撇也是一个shape,向右撇也是一个shape,那时间有点类似于前面这种效果,就是每一个shape,那实际上我最终混合的时候。

调一个每一个都要调一个参数,来实现一个完整的效果,那其实还有些其他的方式啊,就说我确实可以减用比这更加少一点的example,一个靓丽,比如说可能一个脸代表的是生气,另外一个点代表了悲伤。

然后另外一个点代表了什么,什么高兴之类之类的,然后我们在这些点之间做一个差值啊,那其实也是可以实现这种表情的变化,那当然这个取决于我这个脸的样例的数量了,就是有点数的数量比较少的时候。

那可能实际上我做不了特别精细的操作,其实只能在这几个表情之间做个切换的啊,那如果说我这个压力给的足够多,那时间可以同样可以实现,非常复杂的这个动作啊,这个这个这个嗯人脸的这个表情动画。

那当然类似于我们前面提到的,像是s n p r模型,那我们其实可以对应不同的身体的形状啊,不同的身体的姿态啊,其实这个脸的研究其实还是更早一点,其实很长一段时间之前就已经有,这种可以变成不同形状的啊。

脸的这样的一个这种叫叫multiple,就可变形的这个脸的模型,其实这个公式还能数学底层的公式,实际上跟我们前面提到的三pr模型啊,或者其实很相似啊,就是实际上就是第一部分我们刚才提到了。

它是一个基本的脸基准脸平均脸,那第二部分通常来讲我们可以用一个pca,然后给出一堆人脸啊,作为一个pca可以找到这么一个线性的模型,那第三部分其实就是我的表情模型,它其实就是benship。

这个其实相当于更容易控制一点,当然这个第三模型如果想用了,我们也可以用pc来进行实现,当然这个脸的模型圈有很多其他的问题啊,因为除了形状之外啊,我们其实还有人脸的这个比如肤色啊,比如说想做精细一点。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

比如说我们要想比如像mata human,那其实他做的很精细啊,跟年龄可能会有不同的变化,然后另外还有其他的,就是我们本来是不大容易实现的,其实像比如说现在也一般,就是也是有些人会用。

比如像这种基于物理仿真的脸的这个动画,其实他因为你的脸的肌肉嘛,你发现最终还是其实你肌肉的形变,带来脸的变化,那么肌肉收缩收缩肌肉它会蓬起来嘛,它会给你的脸型发生些变化。

那同时肌肉的形变会带动你的皮肤啊,产生各种褶皱,比如说皱纹啊,比如这个演讲的各种纹路啊,这些其实你要就靠建模的,放在bansheep,实现所有的这些细节其实很麻烦的。

特别是你想建立让这个模型变到不同的年龄上,那这个其实你可能需要一些更更多的一些建模,的一些数学上的一些技巧来完成这样的操作,那最后呢就是我们如何去让这个脸动起来啊,那这里其实有一些基本的技术。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们前面提到了reading,这rian有很大的一个功能,就是说我怎么让我的动画师,可以通过一系列像这种的简单的ui操作,去控制一个脸,那我其实可以简单的,就比如说我就可以给每一个点控制一个bansh。

然后通过调这个点的位置,那就产生了一系列的动画,那它还有一些其他的方式,比如说常见的一些方式,我们想要通过采集一个人的脸的动作啊,然后就把这个动作映射到一个虚拟角色之上。

那这就是face tracking所做的事情,那当然face tracking,它本身也是一个很很经典的一个研究问题啊,那这个问题比如说有一类比较成熟的一类方法,就是说我其实我直接去追踪人脸有点麻烦。

因为主要人脸的话,他现在这个有些光滑的地方,其实它这个特征点不太容易找到,那很多时候我们做人脸跟踪的时候,我是跟我是在这些比如眉毛呀或者嘴唇呀,或者眼皮,就是眼睑啊,这些地方它会有非常强的特征点。

所以说我们常用的方式就是说我通过这个脸,我会去检测这些特征点的位置,然后得到这些特征点的位置呢,因为这些特征点本质上是我做表情的时候,他会带动我的肌肉,带动我的面面部的这些那个模型啊,做出这样的表情。

所以实际上我可以通过求解一个什么呢,这个其实也是一个ik问题啊,当然这个ik不是关节了,而它的参数是一系列的这个banship,这个参数我们同样可以求解i k问题啊,比如说用一个优化的方式求解。

那就可以得到一系列的比较合理的表情的参数,那个参数可以刚好对应到我采集到这个眉毛,眼睛的这些特征点的位置,那实现了这样一个驱动啊。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这是一个也是一个类的方法,还有一些其他的方法,比如说呃基于语音的驱动,那这个其实也是近2年,非常也是非常这个热点的一些研究问题啊,当然这个madam这个是不是语音的,我我我我觉得大概率不是。

但是这个问题本身是一个很是一个很好的问题,那当然语音其实有很多种不同的解法,一种解法是说我们还是基于bansh,就是类似于我们前面那个公式,我们去改每一个表情的参数,来去生成一个合理的这个人的表情啊。

当然其实我们今天也看到很多工作,最近就是他就完全不需要任何ban的shade,我就直接输出一个人脸,每个点的位置效果其实也挺好啊,但这个其实还有一些其他的问题,比如放化性的问题啊。

或者是这种怎么去训练啊,跨语言啊,各种各种问题需要解决,但就是不管怎么样,这其实这也是一个非常重要的思路啊,既然在游戏里,其实一些游戏已经在用了,特别是近2年的3a大作,比如说可以跨语跨语。

就不同语言他的角色可以用不同的,比如中文也好,用英文的也好啊,可以去说话啊,那就可以看到他嘴型大概是对的啊,其实这种方式其实也在不断的,这个在我们平时这个见到的这些应用里面出现。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

ok那总结一下,那今天其实讲的内容还是比较多的,比我想的要多啊,总体来说我们还是讲一讲这个skinny蒙皮,要从最简单的线性蒙皮lbs讲到dcs,然后讲了一点black sheep啊。

作为example呢,我们其实也是回顾了一下s m p l模型,以及这个fish animation,其实它主要还是基于这个blood shape加上lbs啊。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

实现了一些动画的效果,ok那我们今天的主要内容就是这些,那看看大家有什么问题,语音驱动嘴型的最优方法是什么,哇塞这个其实是一个很好的问题,但实际上我是觉得现在哪种方法都有可能。

因为主要是如果说你用bansheep的话,相对来说,你的表情的这个自然程度是更容易有保障的啊,但是相对来说,本来shift其实也限制了一些细微的,这种脸的形变的出现,因为你建立benship。

你可能没有考虑所有的可能这个嘴型的状态,所以说如果说我直接生成脸的这个mesh的话,那可能这个更容易产产生这种微小的特征,那当然哪一种更好呢,其实我觉得我觉得最理想的话,简直是另外就是如果直接生成麦。

是可能是最好的,当然你需要解决怎么去啊,怎么去加这个正则项,让他这个效果看起来好一点,这个问题就是经常现在有很多问题,你可以看到这脸如果直接生成mesh的话,他有可能脸会有点抖啊,这这这挺挺重要的问题。

啊我们那个语音驱动人体动作的论文,那个我们近期要开源啊,这个会开源的,然后我们还需要整理一下代码,对于穿衣服,人体的蒙皮有什么办法,我觉得嗯,这个我觉得好像很常见的方法,都是说我再加一些骨骼。

然后这些骨骼是专门给衣服加的,那这样一股可能你不控制它,会加一点仿真去随动啊,这可能是一些比较方便的方法,那除此之外的话可能就是如果说不关心啊,这种随动效果的话,那其实就像一其他的这个蒙皮一样。

我就直接绑定就可以了,但如果想要加的话,那可能还是需要加一些放针啊,或者加一些额外骨骼这种方法,其他的还没有什么特别好的想法,但是有些可能有些研究上的这个方法是说,也许可以。

那部分地方我是用一个神经网络来预测,它该是什么动作,其实这个我知道米哈游啊,还有之前我看到一些人他做了一些工作,其实也是用类似的方法,但这不完全是绑定了这个,实际上是这个实际上是仿真的。

就是用神经网络来做仿真啊,这其实也是一个很好的问题,ok行我觉得时间关系啊,我们也就不再,我们可以下就是下面在这个这个群里啊,或者在其他地方进行交流啊,另外就是说我们第二次的作业啊。

我们已经放在github上了,其实上周上周一上周二就已经放出来了啊,也是欢迎大家有兴趣的同学,可以去这个研究一下啊,也就是我觉得还是蛮有意思的,ok好,那我们今天的课就到这里啊。

GAMES105-计算机角色动画基础 - P9:Lecture08 Physics-based Simulation and Articulated Rigid Bodies - GAMES-Webinar - BV1GG4y1p7fF

那我们就开始上课啊。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

非常感谢大家来参加我们game 165的啊,现在现在应该是第九周的课,所以说我们这里写的是lucture 08,那实际上我们是第九周的课程啊,当然我们今天的主要内容是关于啊物理仿真。

以及这个特别是啊刚体仿真的这块的内容,我们前面一直到上节课,我们其实讲的主要还是所谓的,基于运动学的方法,就是基于运动学的方法是什么呢,就是说我可以直接去改变角色的,比如一个虚拟角色。

他的每个关节的角度啊,每个关节的位置啊,然后这样的话可以去直接生成一个动画,那当然这个应该是我们现在见到的,绝大部分的这种啊,实际的应用里边啊,基本都是所谓的基于运动学的方法,当然其运动学方法。

其实很多时候可以再稍微扩展一点啊,就是说可能我也许不是直接设置一个角色的啊,位置,比如说我就可以去设置一个角色的这个速度,但如果说我直接设置角色的速度的话,这个本质上还是一个基于运动学的方法。

它其实并没有无理仿真,那我们这节课会讲一讲,这两种方法到底在什么地方会有些联系,或者他们之间有什么不同点啊,这可能是我们需要关注的地方,达人基于物理的阿拉斯,也不好意思。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

但我们为什么要说,我们要研究基于物理仿真的方法,因为我们知道基于基于这个印度学的方法,其实有很大的一个问题,在于它无法或者他很难去生成一些跟环境啊,交互比较强烈的这些动作,就是很多时候。

比如说特别是比如说我的环境的交互呃,环境的这些参数会影响我的运动这个形式,而同时比如说可能有些没没有这个unexpected,就是我们可能在预先设计的时候,并没有出现这样的这样的这个呃交互。

那这些时候的话,我们用基于运动学的方法的话,你是很难去比较合理的生成这些动作的,就比如说比如说我们做动捕,比如说我们很多时候,可能比如说有些时候是一个啊格斗游戏啊,那其实比如说我就是两个角色。

那比如说这一拳打过去,那个人那个角色安全了,那其实要要做一些这种挨打的动作,这些动作其实都是预先设计好的,那你如果你要动捕的时候,包括你的动画师去做,你总是要这个有一个有一个规划,那比如说我要在神啊。

这这个角色被怎么打啊,怎么击打了,那他肯定要做出相应的动作,那如果说比如说一个vr场景,如果说我想让这个角色,因为在在vr场景里,其实我是无法去控制这个这个用户,到底他会用什么方式。

去跟这个这个虚拟角色进行交互的,那在这种情况下,其实很多时候,他击打这个方式是我无法预先去估计的,无法去先去准备的,那这种时候我们只用基于运动学的方法,是很难去生成一个合理的这样的反馈,而另外一种场景。

比如说像这里这些动画啊,其实已经已经replay了好多遍了,就比如说这个叫力大滑,那这种东西其实你是完全无法估计的,无法判断的,那这个时候我们该怎么去生成这样的动作。

那其实我们后面包括从这学期开这节课开始,一直到我们这学期的课程的结束呢,我们其实后面还有五六节课,那我们主要关注的是一类新的这个方法,叫做什么呢,叫做物理,基于物理的角色动画。

那physis based carnivation,其实基物理的角色动画,我们在第一节课时期也介绍过了,就是说其实这个历史还是很久远的,其实你可以从这个九几年啊,就已经开始有很多工作来做这件事情。

但是直到最近1~2年,特别是从deep妹妹开始到我们后面,其实我们这边也做了一些工作,比如像我们今年的srah的这个这个control v e。

我们其实逐渐的把这样一个呃phs base carnivation,现在感觉是已经越来越啊,更加有希望能够去真正的用,在去代替我们在这个基于运动学的方法,来实现我们这个这个比较好的一些效果。

那当然这个其实我们前面也提到了,他跟运动学的方法之间最大的不同点是什么呢,就是基于unix的方法,我们是直接去设置角色的姿态啊,但在这个过程中,我们比如说环境有些变化,我们这个用户有些交互。

比如这里有个就是这个这个地上有个箱子,那我就贴在箱子上,我该做出什么动作,那这种情况下,就是我们完全是依靠数据,来给我们这些这些内容的,但是基于物理仿真的角色动画呢,它其实是另外一种思路。

他是说我可以比如人在外世界里走路的时候,我们总是去驱动,靠我的这个骨骼,肌肉系统来驱动我的这个身体产生运动,那这时候比如地上有个箱子,或者地上有个门槛,他帮忙半漏一下。

那这个时候其实整个我身上身体的这个反馈,我的这个运行方式啊,其实是受到这个,比如说这个重力啊,或者受到这个这个经典力学的这个影响,那我可能要摔倒,那其实为了避免这个摔倒,我可能需要做一些动作。

那这个其实自然而然产生这样的响应,其实这个过这里边其实最难的地方啊,其实两部分,一部分是仿真,就是我们需要用一个物理在电脑里边,在我们的这个计算机里边来计算出来,实现出啊草。

或者能模拟出我们在真实世界里,这个世界各个这个物理世界的运行方式,那另外一个方式就是另外一个问题,就是就是控制我们该怎么去生成,怎么去创造一个控制器,那能够让这个角色一方面做出动作来。

一方面能够去反应啊,去响响应我们外界的各种,比如说推他一下。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

或者是这个环境的变化等等等,那当我们这节课,其实是从一个非常简单的地方啊,其实也不能算简单,应该说这两部分中的第一个部分,就是关于如何进行仿真这件事情,来做一个简单的介绍啊,这个其实关于仿真的课程。

我们其实其实前面已经有几门课讲的非常好了,包括包括呃比如说game 102啊,sorry,103,还有game 301,当然实际上在前面几门课里面,可能介绍的很大一部分是说,一方面是物理反射针的基础啊。

另一方面是说这个关于流体啊,液体还有软体,这些仿真其实会介绍很多这样的内容,但是呢我们做角色动画的时候,实际上我们大部分情况或者是找在现阶段啊,现阶段我们其实关心的还主要是缸体的方针啊。

特别是这种角接的多钢铁的这种仿真,因为毕竟人嘛人和动物其实大家都是骨骼系统,骨骼基本是刚性,它不会剪,不会轻易形变,当然你也可以说形变,比如说破碎啊,那这个其实就比较比较危险了,所以在这种情况下。

我们其实今年今天这么这节课,主要是简单回顾一下我们仿真的一些基础知识,以及在额外的介绍一下,这个多缸体仿真的一些简单的这个技巧,那当然实际上现在我们在很多的这种,真正的角色动画里边。

我们其实就是会特殊物理角色动画,我们通常来讲不会特别关心仿真是怎么实现的,通常来讲我们拿一个物理引擎,那这个都可以就做一个黑盒在实现,但实际上这件事情就是,我们其实后面也可以看到。

其实这里边还是有相当多的一些方法,它是基于我们对仿真的这样的一个,数学的这样一个表达的这样一个理解啊,其实以前有很多方法是基于这样的产生的,那当然比如说最新的一些,比如基于深度学习的方法。

比如基于这个强化学习的方法,那我们其实也有各种写各种不同的思路啊,一种思路就是说我们可以完全当成黑盒子,另外一种方式就是说,我们其实也可以把它作为一个白盒子,就是model based。

所以就基于模型的方法来实现这个运动控制,所以说我们这个仿真的这个过程,还是相对来说还是有必要去了解的,ok那什么是仿真呢,或者说其实我们就是想一想,一个非常非常简单的例子,就是一个物体,一个例子。

或者我们可以想象它可能是一个小球,那这个小球有它有一个质量啊,质量通常用用m来表示,然后它在空间里的一个位置,然后是有一个速度,位置是x,速度是v,然后我在这个球上加了一个false。

加了一个这个常数的,就是不变的一个力,那我接下来问你,那这个就这个球该怎么运动,那这个其实是一个非常简单的题了,我相信大家在高中的时候,这个这个高考之前类似的提起人做过,做过无数多啊,很多很多。

那时间我们本质上来说,我们想做的是什么事情呢,就是说我其实告诉你一些信息,这个信息是说这个局物体在当前时刻,它的位置和速度啊,通常来讲,当前时刻我们认为就是t等于零的时刻。

那接下来呢我希望能够去找到一个方法,去计算未来一个时刻,比如说t等于十秒,那这个时候他的位置是多少,它的速度它在哪里,它的速度多少啊,大概是这样的一个信息,那这个过程中我们其实知道了。

比如说这个简单问题来说,我知道这个力啊,它是始终恒定不变的,一直在这个加上去,那这边怎么算呢,那其实大家在高中这个做做作业的时候啊,高考高考的时候肯定是做过类似的题的。

你们觉得首先想一想牛顿第二定律f等于ma,这个其实是非常非常经典的这个牛顿定律,那这里边其实a是什么,a是加速度,那加速度是什么,加速度是速度的导数,那速度是什么呢,速度是这个位置的导数。

其实就是说我们这个物体在移动过程中,让它移动的这个轨迹的这个对时间的导数,那肯定就是速度,那这速度其实它也是一个轨迹,它的这个大小是随时间变化的,那它导数是加速度,那有了这样导数关系之后呢。

那我们其实可以自然的去想,去做这样一个导数的这样反运算,其实就是求积分嘛,也就是说我们首先算一个加速度,由牛顿第二定律我们可以到a等于f除以m,然后一知道a了之后呢,那我们其实对这个对这个v啊。

因为v的导数等于a嘛,所以对它求一个积分,那其实可以得到这个v的这个这个函数的关系,然后如果说知道v的情况下,我们在对v进行进行进行求求这个积分,那么其实得到了x,比如说位置的这个一个函数关系。

那当这个函数关系非常简单了,因为我们知道这个在a是一个常数的,一个情况之下,那我们其实求求积分啊,求一次积分和求两次积分呢,其实都是非常容易的,我们其实是非常熟悉的这个公式。

x0 等于这个啊x0 加上v0 ,t加上二分之t方啊,这个大家经常做的这个自由落体运动,所以本质上是这样一个公式的一个特例,那在这种情况下呢,我们其实很容易知道,如果说我知道x0 d0 时刻。

它的位置在x0 ,然后这个速度是v0 ,那么在t等于十的十秒的时候,那它的位置在哪里呢,那其实可以直接套用这个公式啊,直接直接套用这个啊,最后这个公式我们可就可以得到这个这个,这个x0 的位置。

那这是一个非常简单的情况,为什么呢,因为我们这里是非常啊告诉大家,这个是一个常数,也就是说它随着时间是不会变化的,随着这个积分呢就从上一步,从这个积分到这一步的这个积分的这个结果。

我们是可以很容易计算的,它是有一个解析的解,或者一个closed form的一个解,或者说这个所以它其实可以很容易地写出公式,可以让我们做这样的一个计算,但是大部分情况下。

我们这个f它通常来讲是一个比较复杂的函数,那当然这里其实我只是只是简单的写成这样,一个形式的,但实际上它通常来讲是一个比较复杂的函数,那可能是一个各种各样奇怪的函数,混在一起的一个函数,在这种情况下。

你要做这个积分基本来说是很难的,其实我们知道能够显示的啊,能够写成一个解析的一个积分形式的,这种函数的范围是比较小的,其实只有少数几种函数能这么干,稍微复杂一点,函数生成的结构,函数的一些复合。

你都没法去把它写成一个直接解析的,写成一个公式,那在这种情况下,如果是我还是想要制计算,比如说t等于十秒的时候,你的这个积分的值啊,就说你这个位置的值是多少,那我们直接积分这件事就不就不成立了。

就没办法做,那为了解决这个问题呢,我们其实就是仿真,其实做的事情就经常是做的是这样的啊,什么事情呢,就是说我把我本质上求仿真,我就是为了去求这个公式啊,因为我从一个初始解开始,我去找到一个方法。

去计算这个时间的这个值位置,那这其实就是一个仿真的过程,但是因为这个解析的公式我们是得不到的,也就是说实际上对于任何一个t啊,就是我无法对任任意一个t去求这个值,那为了能够解决解决解决这个问题呢。

通常来讲,我们在仿真里面会做一个,非常重要的一个离散化,也就是在时间上做一个离散化,时间离散化就是说什么呢,就是说本来这是一个t,是一个连续取值的一个一个变量,那么就是2x应该是在连续的任何一个t上。

有一个值,但是呢我们其实因为我们知道这个解析的公式,我们没法计算啊,所以通常来讲我们会把t给离散掉,就说我不是在一个连续任意时间去找这个值,而是在一些离散的时间上,比如说t一的一个n个tn。

这样的一个这一系列的tn的这个点上,去计算它的位置,一般来说比如说我们在仿真里面,我们通常会让这个tn的选取是一个均匀的,也就是说我们可以比如说有一个不长h,我们通常把它叫做这个仿真的这个不长。

然后呢这个tn,那其实就是第n个这个h这样的一个这样,一个不长之后的那个点,那个时间点我计算一下它的位置,这是一个非常重要的一个时间,第三话,那当然我们选举了tn之后呢,其实际上比如说我们前面这个计算。

本来我们是需要做这样的积分,要做一个连续的积分,那我们其实可以把它放在一个比赛,到时间上之后呢,我们可以只需要去计算什么呢,我们只需要根据当前某一个时刻,n这个时刻的速度和位置。

我们去计算下一个时刻的速度和位置,那我不我们不断去迭代着,去完成这样的一个计算,那实际上逐渐逐渐,我们就会达到我们想要去计算的那个位置的,那个那个时间时刻的那个那个那个位置,那个他的状态。

那当然实际上这个转换到目前,这个转换其实是精确的,比如说我因为我这个积分我可以把它,我就知道我们这个这个连续的积分,我们可以把它拆成一系列区间的积分的求和嘛,所以说实际上这样一个公式。

我们是可以直接精确到这里面来,但这里还是有一个问题,就是这里,其实我本质上虽然说我把时间离散化了,但是这里我还是需要计算这个积分值打开,但是这个积分的值,因为a是由f来算出来的,但是f是一个不可积分的。

就没法直接去积分的这样一个函数,所以造成这个小积分其实还是无法计算的,或者再去一些,比如说我们就是一个x我们知道它的导数,它导数的曲线是这样一个曲线,那个曲线形式是什么,我就不关心,我不是很关心。

但至少我知道这个曲线,这个函数我是没有办法直接积分的,ok咱们在刚才我们说的这种离散的啊,空时间的离散这个这样一个条件之下呢,那我们需要知道,比如说我知道t5 时刻x的位置。

然后我需要计算t60 个x的位置,那时间t60 个打字位置,应该是t5 时刻来位置,加上5~6中间这个函数下面这块面积啊,就是这段的积分,但是因为这个函数形式我不知道无法表达。

所以说我只能近似去计算这一块的面积,然后用这一块近似的这块面积,来代替这个积分的值,那当然这个近似,我们有好几种不同的方式来近似的,比如说因为要计算这一个小块的面积对吧,他这边有个起点,有终点。

那么可以认为这一小块的面积可以用一个,可以用一个t,用一个正方形来近似,当然这些其实多了会有一些误差了,因为这个误差是我正方形无法去弥补上的,那这个正方形的面积等于多少呢。

等于这个它的宽度是我的时间的间隔就是h,然后它的高度是在n时刻的这个速度的值,x导数的值,那这样的话我就可以实现了一个近似的,这样一个计算啊,就是在他跟前面这个这是一个精确的一个公式。

但是这个公式我算不了,所以说我用一个近似啊,用这个上一时刻的这个这个速度,乘以这个时间间隔啊,得到了这样的一个估计,当然这是一种近似方式了,那么其实还有另外一种近似方式。

就是说我其实可以用下一时刻的速度,我认为是这一区间整个的速度,那这也是另外一种计算方式,所以不管哪一种近似方式,实际上我们都是可以完成这样的一个,对前面这个比较比较难算的。

这个这个积分的一个数值的一个估计啊,的一个计算,那当然这个过程实际上也叫数值数值积分啊,叫数值计算,它其实是用一些近似的方式来去来替代,我们的对这个积分的计算,那么这两种方式刚才也说了。

它最大的区别是什么,最大的区别在于第一种方式,我比如说我要先从x n算x n加一,第一种方式我是用了对应的xn的速度,n时刻的速度来代替,这一小框格的这个整体的速度,那第二种方式呢。

是我认为是为了算x n的这个更新,我用xn加一的这个速度来去作为整体的速度,那就是两种不同的,这种这种啊啊这种这种祭祀的方式,那当然你要说可能有其他的方式,比如我是不是搞成一个梯形啊。

是不是改成一个中间的这个这个这都可以,但这都是不同的计算方式,但是为什么要讲这两种,因为这两种刚好是对应于两种不同的欧拉,积分方法,就前面这种就是用第一用,且就是当前时刻的速度。

或者说它这个速度值叫做前向欧拉,或者叫显示欧拉,那反过来第二种用后面这个来做计算的,那叫隐式欧拉啊,也叫也叫逆向欧拉,就这是两种不同的欧拉的这个方式,其实公式很像,唯一的区别就是说前面都是一从当前速度。

当前的位置和速度计算下一时刻的位置和速度,只不过呢这个加速的部分,积分的部分对于显瘦拉来说,我用的是当前的值,对于野兽来说,我用的是下一时刻的值,但这其实有一个问题,特别是对于野兽拉来说。

这个下一时刻的这个加速度,其实是某种程度上它是一个未来的信息,就是我现在还不知道的一个信息,为什么呢,因为主要是说下一时刻的速度,就是我们这个力,很多时候我们表示他是跟我这个物体。

当前的位置和当前的速度相关的,那就比如说我们知道万有离万万有引力啊,非常典型,万有引力的话,你离得这星球越近,那他这个力就越大,离得越远,力就越小,那它当然跟位置相关,那其实有其他的,比如说风阻啊。

风的阻力它其实跟速度相关的,你跑的越快,你的风阻越大,所以说其实经常来讲它是跟这个这两个相关的,而为了能够计算这个力,我需要知道下一时刻我的位置和速度,但是呢在当前这个计算这个力的时候。

我下意识和力和速度我又不知道,所以说这里其实有一个问题啊,就是它需要一些future information,那为了求解的话,我们就需要解方程了,那这个解方程通常来讲会变得比较复杂一点。

因为这个f是一个非线性函数,那其实去求解这个方向会比较会比较麻烦,那另外还有一种方法,就是这两种方法的一个混合的方法啊,叫这个simpletic,或者叫新欧拉,或者叫这个半隐式欧拉。

但其实看到有其他的名字,它实际上是说,因为我们同时需要关心一个速度量啊,和一个未知量,那这对于我们其实因为速度量的更新,我们需要这个加速度,然后加速度通常来讲他可能会需要,如果说我们有隐身欧拉的话。

它是需要未来的一些信息的,所以说我们可以把这个加速的部分,改成当前时刻啊,这个这这一行,其实就跟你这个显显效欧拉是相同的了,但是从速度来更新位置,我们其实是可以用这个对于这个新欧拉来说啊。

或者半隐式欧拉来说,它其实是用的,我已经计算好的新的速度去更新这个位置,当然写手拉的话,它是用当前的,而不是已经更新好了,所以这是另外一种欧拉方式,这种欧拉方式实际上在我们的这个仿真器里面,是最常见的。

而前面这种其实相对来说呃,就稳定性上就是和这个它有一些不太好,就是性质来说不如这个这种积分器要好一点,但不管这两种哪种积分器,就不管是前向欧拉还是这种影射啊,半隐式欧拉它的所有的信息都是已知的。

就不需要解方程,就可以直接进行计算,那当然这个也引兽拉的话,它是需要解方程的,因为它有一个未来的信息,当一个具体的例子,比如说弹簧啊,这是一个弹簧质点系统,就是一个弹簧,然后一个木块放在这里。

然后这个时候假如没有摩擦的话,然后这个物体的话,它放在原点,那在这种情况下,这个物体受到力,我们知道混合定律嘛,这也是高中大家比较熟悉的内容,它可以告诉我,我定会告诉我们,这个弹簧给这个物体的力大小。

应该是这个负的k啊,进度系数乘以x那在这种情况之下,我们可以比较容易,比如知道f之后,那我们知道它的加速度,加速度是f除以m就是负的k乘以二,然后乘以x n,比如用显示欧拉的话。

我们可以写成这样的形式啊,就是根据当前的x n计算出这个速度加速度,然后做一个做一个数值积分,然后用当前的速度作为数值积分,得到下一个时刻的位置,然后类似的这个半隐式啊,唯一的区别是这里啊。

但是更新的速度时间不一样,然后还有另外一个这种野兽拉,其实你稍微复杂一点,就野兽拉,因为我需要借用下一时刻的位置,去计算这个加速度,所以说这里其实是一个x加一,在这里,当然我们可以比较容易的。

把它写成一个矩阵的形式,那也是欧拉写受欧拉是这样子的,然后半隐式欧拉写成这样子,然后野兽啦其实要特别注意是说,其实你会发现前面两种写出来,写成矩阵形式的话,其实xn和xn加一就是直接是在左边。

他们前面没有系数,但是也是奥拉号前面有个系数矩阵,其实本质上来说,就是因为我需要一个未来的信息,导致了我这个这个系数矩阵在这边,我其实做一个需要做一个求解,最终得到的是说下一个位置。

需要是把这个矩阵矩阵求逆啊,从这边去走到这样的一个公式,但这三种方式啊,如果说我们直接对它做仿真,因为本质来说我是每一时刻,从当前时刻我可以去乘上一个系数,得到下一时刻的这个这个位置和速度。

那如果说我们把每一种方式不断做这样迭代,那得到了这个速度和位置的关系,我们把它画成图啊,这里横坐标是位置,纵坐标速度,那其实你可以发现对于饮食啊显瘦拉来说,他其实是当然可以先看一下这个坐标,坐标范围啊。

这个其实已收啦,其实我反正了若干步之后,他其实是逐渐逐渐在往外扩大,这意思是什么呢,就是说我的这个随着我不断的仿真,那这个木块会抖动的越来越快,越来越快,并且抖动的越来越远啊,这是一显瘦了。

他从一开始的一个距离开始,它会抖动的越来越慢,越来越慢,最后逐渐收敛到零,就收敛到完全不动,而这个中间我们说这个新郎或者半夜收了,它基本来说是一个比较稳定的一个简谐振子,这样一个效果,所以说实际上就是。

这也说明了这三种不同的这种仿真啊,就是求积分的公式的性质,对于学生来说,它通常来讲经常会导致不稳定,就是这个系统会不断的从虚空中拿出能量来,但这个能量其实是不真实的,是假的。

就是这是一个数值上带来的能量,它会让这个系统越来越不稳定啊,这个不稳定会导致这个这个角色,物理这个角色可能突然就飞掉了,然后突然就是这个本来是一个整体啊,突然就散开了,然后就飞到这个道都是。

所以这是一个写手了,它竟然会有些数值不稳定的问题,然后也是欧拉是肯定可以保证数值稳定的,但是呢它就会有一些能量,会不断的从系统中被耗散出去,但是有些时候对于我们仿动画来说,可能不是一个特别严重的问题。

因为这些能量耗散,你可能肉眼并不能直观的感受到,但是另外一个问题是说也是欧拉,就是野兽,欧拉实际上是说它因为它需要去求解一个方程,你前面提到的,其实对于这样一个弹簧振子来说,还是相对比较简单。

就是一个二维的一个矩阵,二阶一个矩阵,但如果说我这系统比较复杂,比如说我可能是一个人,那可能是60多个自由度,那这么多自由度每次需要每个时间都要求逆,那可能是比较复杂的,那如果是再大一点行动。

比如说有些时候,我们常常经常看到一些一些这个,一些这个例子啊,比如说可能有有1000个方块,1000个小球同时丢到一个场地里面去,那对应的那个那个矩阵会非常非常巨大,所以说这个隐身拉。

通常来讲它会有一个求解速度这个问题,所以总体来说呢就是说啊,然后就是中间我们这个稀有啦,这个其实是可以证明的,但我们这里就不再做介绍了,就是你可以证明它是可以在这样的。

至少在这还用质子这样一个线性系统的情况下,它是可以保证我这个能量是守恒的,那当然这个如果是非线性系统的话,其实他这个也不是严格守恒的,因为主要是非线性系统,你做线性化,本质上我们是在做一个非线性系统。

做线性化嘛,那这个时候其实内部呢会带一些误差,这会造成一点点这个不守恒的因素,但总体来说呢,就是说我们不管是显瘦欧拉还是半隐兽拉,或者新优拉,它是相对来说比较快的,因为我们不需要去解封城。

但是不管哪一种,特别是显瘦了,稍微大一点的这个纺织布就会非常不稳定,当然这个新又来了,就是虽然说是他是在这个弹簧质点,这么一个系统里,它是稳定的,但是更复杂的系统啊,通常来讲它也是不稳定。

特别是这个反正不大的时候,然后野兽了,因为它是可以保证,反正是肯定是稳定的,那当然缺点就是慢,而且虽然收入虽然说稳定,只是说他这个公式本身数学还是稳定的,但数值上通常来讲也可能是不稳定的。

取决于我前面去求解那个方程的,那个那个矩阵啊,那个矩阵如果它是一个奇异阵,或者是接近于奇异阵的一个条件,是非常差的一个矩阵,那它也会不稳定,所以说这也是这个不同积分方法的一个应用,就像我们前面所说的。

其实很多时候我们常用的这种仿真引擎,比如说bullet,比如说o d e啊,比如说还有什么mojo,其实大部分都是属于这种信用拉的方式,在这种方式多一点,当然还有一些其他的,比如说我们想要更精确的这种。

或者更加稳定这种积分方式,那其实还有一些其他的方法,比如说这个rk啊,常见的r k for这个龙格库塔法,然后还有一些这种变分法,变温积分器,那变分积分计是另外一类的方法,就是首先能够互打法。

这个是其实相当于他是比欧拉法更加精确一些,所以它比如说我即使不稳定,我其实这个崩得也慢,但是本质上来说,它可能还是如果除非我用隐士啊,不然的话,他其实还是一个,不能保证稳定性的一个基本方法。

然后这个variational integration就是变分计分器啊,它本质上来自于什么呢,来自于比如大家有可能有些同学,有些同学这个了解过,比如说悬链线或者最速降线啊。

我们知道这个小球沿着什么样的轨道下降最快,那其实这个求解的方式其实它用了变分法,那这里其实它基于一个什么呢,就是最小作用量原理,就大自然总是想偷懒的,我们总是想要让一个作用量这么一个量。

走这样的量增量最小的轨迹,所以这个变温积分,其实基本来说从那个方式去推导的一些公式,当然缺点是它不太容易去处理这个碰撞,这个膨胀一般来说不是一个,它是一个耗散的一个一个过程,所以说不太容易去处理。

还有另外一类非常差,也是最近非常这个应用非常多的,就是position based dynamics,就是基于位置的啊,这个物理,那当然这个我们就这门这节课就不讲了,就是这门课我们就不会讲。

但是有兴趣的话可以自己去了解一下,因为现在一些很快的仿真器,特别是非常高高度并行的仿真器,大部分是就是不是,大部分就是很多是基于这种啊,p p t或者x p p t。

就是这种基于位置的这种物理仿真的方法,比如非常典型的像是这个嗯啊,这这不只是个人的一些了解啊,就比如说像是nvidia的一些这种,可以跑在gpu上的这些这些,反正期其实还是以这个p p t的方法为主啊。

它可以实现很快的并行,可以很快去这个在这个嗯gpr使用,那当然这是一些其他的一些防尘器。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

那当然前面只是简单介绍了,我们只是一个质点啊,作为例子,我们介绍了一下这个我们怎么去进行积分啊,怎么去这个一些基本的一些基本积分的,这个方法,那我们其实这门课啊主要关心的是什么,我们关心的是钢铁。

那什么是钢铁,那缸体实际上是一个物理学上的一个,非常抽象的一个概念,它只是说我一个物体,它在运动过程中不会发生形变,不好意思,它就是一个钢铁,那比如说一个石头啊,非常典型的缸体。

那很多时候比如说一个桌子呀或者一个乐高块,那都是钢铁,但是实际上真正的钢铁在自然界是不存在的,因为本质上来说,如果说一个东西完全不会形变,那就意味着这个东西它可以以光速超过光速的。

就是无限大的速度进行进行传递信息啊,那这个当然是首先这个相对论是不允许的,其次也相当于这个材料的这个钢筋,它的强度是无限大的,那这个材料学也是不允许的,所以说真正的管理是不存在的。

其实本通常来讲只是一个近似,就我们在认为在有我们常见的这些交互里边,它的形状是不改变的,这是一个钢铁,那当然对于钢铁来说呢。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们其实前面也是也是经常会讲一些,就是很多其实也多少也设计过啊,就对于钢铁来说,它一个非常重要的性质,因为它它形状不会改变,意味着什么呢,意味着里边任何两个点的相对位置关系,是不会发生改变的。

就是相对在局部坐标系的相对位置关系,是不会发生改变,这也意味着我对于钢铁来说,我只要确定这个钢铁上一个点,比如说x这个点的位置,然后以及这个缸体在视觉坐标系的朝向r,那我就可以为唯一的啊。

完全确定好这个缸体的性质,就是它的它的位置,每个点的位置我能给同样算出来,就比如说这钢铁上另外一个点xp,它跟x在缸体局部坐标系的相对,这个相对关系是r0 ,那我知道x和r之后。

那我其实可以直接写出来这个这个x撇,它的位置应该是x加上r乘以r0 啊,其实就是做一个坐标转换的这样一个过程,那其实这个r好,r乘二零,我们可以稍微写写写,写成一个r就不带不带不带零的这个r。

那在这种情况下,就是如果说我们想再进一步的,比如我讲,因为我们知道这个缸体它在运动过程中,他其实每个点在空中,空气在空中都会有一个轨迹在空间中,那这个轨迹我们可以对这个x。

对这每个点进行一个求对时间进行求导啊,比如说对这个x x表对x p的这个移动啊,对对时间求导应该是什么,其实应该是x撇的速度,那它的速度应该是多少的,应该是什么呢,所以我们知道这个。

其实我们可以从x表这个表达公式,我们可以直接对它求,比如最多这个x撇的公式,左右两边对时间求导,那左边是x p r x撇的角啊啊一点啊,那其实是这个速度,然后右边其实是xx的一点。

x我们一开始参考的那个点,然后以及r的旋转矩阵的导数乘以二零,其实因为r0 是一个固定不变的,它是一个局部的一个向量,它的运动过程它是不变的,所以说这个求导,后面这个求导只需要对r进行求导来完成。

那当我们前面已经知道了,这个x点其实对应的是x,就这个参考点在空间中的速度,然后呢这里清另外一个问题,这个r点应该是什么r点,什么r什么r是一个朝向,它本质上是一个旋转矩阵,所以旋转矩阵的话。

我们知道我们就是第二节课的时候,讲数学的时候,我们知道旋转矩阵有一个非常基本的要求,那就是说他本身是正交的,就是x r2 乘以r t等于i,那如果是占满,我们要因为我们这不管我这个角色啊,sorry。

我这个缸体怎么运动,这r其实是可以在不断时间不断的变化,但在变化过程中,我们需要始终保持r2 乘以r t等于i,这样一个公式是不变的,它是一个常量,那如果说那这样一种情况下。

我对两边可以对时间同时对时间求导,然后左边对时间求导是这样一个公式,右边i是一个常数啊,它是一个长矩阵,单位阵嘛,长矩阵,所以他对时间的导数应该是零,那左边这个其实我们可以应用一下。

我们这个乘积的导数等于这个导数的乘积啊,分别导数的乘积啊,可以写成这样的一个公式啊,其实本质上是前面这个导数乘以右边,然后在前面乘以右边的导数,那其实可以看到,这两个其实有比较明确的这个对称性啊。

就看起来好像是这个形式比较相似,所以实际上我们也确实它是对称性的,就是前面这个公式右边r乘以r。t,它其实是r点乘以r t的转置,那其实这里可以发现,r这个前面是r点乘以r的转置。

右边是r点乘r的转置的转置,所以说一个这是一个矩阵,这是另外一个矩阵,一个矩阵乘以加上它的转置等于零,那就说明这个矩阵是一个反对称阵啊,就所以是r点乘以r t它是一个反对称阵。

那反对阵我们其实前面也提到了,我们是反对,就反对称阵它具有什么样的形式呢,它可以写成这样的一个方式,那就对角线肯定是零,这是反对称的一个基本要求,然后这个另外其他两个这个对应的这个点上啊。

对应位置是互相为相反数,那另外说我们我们前面也提到了一个,任何一个反对称阵啊,总是会跟一个差乘矩阵,它本质上就是一个差成矩阵,它其实跟一个差乘是对应的,那这个叉乘就是我们可以从这个反对称这里边。

去提取这个差成的这个前面的那个向量,那这个向量我们就把它叫做角速度,也就是本质上r点它等于什么呢,它等于这个角速度这个向量所对应的差乘矩阵,然后再乘以r就是数据上可以执成这个样子。

然后然后就是如果带入到上面去,其实可以把这个x撇的导数,可以写成这样的一个形式,那时间我们再稍微这个代换一下,因为它这个叉乘矩阵嘛,我们总是可以写成叉乘的形式,那其实就是比较熟比较熟悉的这个公式了。

比如说我们再把它解写,把r r乘以r0 ,对我直接写成r2 ,那其实就是这样的公式,那这个公式是,可能大家可能比如在物理课上也可能见过,或者在其他地方也可以,建议可能也见过,就说这个x点。

就是就是这个钢铁下另外一个点x撇,它的位置啊是x加上2x20,然后它的速度是这个x的速度,加上这个角速度叉乘,我们变个插上r,那当然其实就是刚才我们说的这个x点,二等于v啊,就是这个x的速度。

然后r的点就整个这缸体旋转的这个朝向的,时间的这个对时间的导数等于角速的,插上去转乘以二,但这里其实有一个问题啊,就是我们只是说我们这个omega,实际上本质上是由前面这样一个关系,从这里提取出来的。

那为什么是讲速度呢,就是说实际上我们总是想象,因为我开始看到这个公式,当然是这个公式v加上r我们应该差了二,那为什么它是角速度呢,就这俩都有什么关系呢,这些东西都稍微多讲一句,就是说其实回想一下。

我们当时讲过那个罗德里格斯罗德里公式,就是比如说我这个只有一个空间上,有一个方,有个向量x我希望它能够绕着一个轴,一个轴旋转,那比如旋转角c塔,那旋转之后呢,这个点的位置,x撇的位置和x之间的差啊。

其实可以写成这样的一个公式形式,如果你没有印象的话,可以去看一下我们第二节课的一个推导,那如果说我们这个轴,实际上如果说这是一个刚体啊,这x是刚体这一点,然后我们当天刚体正在沿着这个轴做旋转。

那旋转的角速度是omega,那这个旋转我们其实可以得到什么呢,就是说在这个旋转过程中,这个x这个点这个向量,因为它在旋转过程中,这个x点这个向量它的它会沿着圆周会移动吗,在移动过程中。

这个向量的坐标值啊,对于时间的导数,我们可以用一个这个链式链式法则啊,我们可以写成这样的一个形式,那这里其中这个dx比d feat,其实我们知道这个dx本质上是deltx。

在这个fa趋近于零的时候的一个极限值,这是导数的定义,所以说你其实可以很容易得到dx d dx比cdc的,你可以用比如说洛必达法则,你可以去得到它其实应该等于u差乘x,我们其实之前用过这个关系。

就是说在我们计算i k的那个,雅克比矩阵的时候,我们其实已经用过了这个关系,本质上他俩是同样的东西,然后这个d c和d比dt其实就是旋转的速度嘛,那我们知道旋转沿着一个轴的旋转的速度。

那本质上就是角沿着这个轴就是角速度,这实际上在这样一个旋转过程中,我们知道这个一个向量,x在一个角度进行旋转的时候,它的坐标值的变化绿啊应该是欧米伽插上x,这是我们从这个可以得到一个公式。

那因为另外一方面,我们知道一个旋转矩阵,r那几个旋转矩阵它本身就是一个,它对应的是什么,是一个钢铁的朝向,那刚那个朝向,其实本质上来说是一个缸体上的三个坐标轴,在世界坐标系下的这个表示。

所以r其实每一列都是一个向量,对应的是对应坐标轴的那个嗯,那个坐标那个轴的这个向量的方向,那其实比如说ex我们看这个向量,它在这样一个欧米伽这个角速度下旋转,ok那这个旋转之后,或者它的旋转的变化率。

那其实按照我们刚才那个推导,应该是欧米伽x1 x,那类似的e y和ez有同样的关系,那也就是说如果说进一步,比如说x的点啊,r的点r的这个导数对时间导数,时间本质上是它里面每一个元素,对时间的导数啊。

或者说可以说是他每一列分别对时间的导数,因为每一列的时间导数分别是,我们应该差成这一列,那第一列是我们应该查成第一列,第二列是我们应该查成第二列,那以此类推,那我们其实可以把这个这三个。

这三个差成这个形式,我们可以把这个w给提出来,它本质上就是说我前面乘上一个w的旋转矩阵,其实可以同样的得到这个公式,所以实际上就是说角速度和,就这就回到我们前面这个这个关系嘛,所以说就是r它是一个旋转。

是这个缸体的朝向,那这个缸体的朝向,因为它是随时间变化的,我们可以计算它的导数,看他对时间的导数,就是角速度的差乘矩阵乘上r的这样的形式,那这是一个非常重要的一个关系,ok那我们知道这样的关系之后。

我们可以做什么事情呢,比如说我在这个缸体在某一时刻,ok我现在它当前的位置是x,然后它的朝向是r,然后呢比如说现在这个缸体是它有一个角速度,是沿着某一个轴啊,一个方向的角速度,然后同时它有一个速度v。

然后他在这样的速度之下,角速度和速度之下,我运行了一个dott的这样一个时间,离线之后呢,我这个刚体旋转了一个新的位置,移动了一个新的位置x表,同时呢我这个朝向啊稍微转了,转到了一个r撇。

那我接下来就问我该怎么去计算x撇和r撇,x表其实是比较简单,就是实际上我们也就是说实际上这个这个v啊,就这个角速度,这个速度我们前面也知道它本质上是一些导数,所以我们知道x的导数。

x导数应该是这个v的值,然后刚才其实我们也推导过了,r对这个朝向矩阵的导数,它是omega的差乘向量和差乘矩阵,乘以r r的这样一个形式,那知道导数之后呢,其实就相当于我知道了这个角速度和速度。

我就同时知道了这个x和r对时间的导数,那主角导数呢我们就可以做积分啊,求出这个下一时刻x撇和r撇的位置,那其实xp那很简单,它就是达到t乘以v啊,这是我们做了一个简单的欧拉积分。

另外这个r撇其实也是一样的,本来是r撇,应该是r撇等于r2 ,加上w t乘以r点,ok但是r的导数r点等于这个欧米伽差乘以r,所以说时间r撇就是我在下一时刻,这个旋转矩阵,注意这是一个矩阵。

他应该是上一时刻,这个旋转矩阵,加上dot乘以这样一个这么一个dot的形式,那这其实本质上就是完成了一个对旋转矩阵,对这个朝向矩阵的一个更新,那当然这里有一个问题就是这个更新本身啊。

因为这是一个本来如果说这个时间是无限小的,那我们是可以保证这个加完之后,这r还是一个正交矩阵,但是呢我们如果说这个dot不是非常小,通常来讲,比如说我们用1‰秒,1%秒,那这其实不算很小了。

那这种情况下这个东西的会有一点点误差,他会让我的r撇不再是一个正交矩阵,但这个正常解决,这个本质上来说不是这个公式错了,而是因为我,我们现在其实是在用一个线性的一个函数,去近似一个非线性的函数。

它会有误差,那这个误差会导致r撇不再是一个正交阵啊,他其实同时也就是它不再是一个学生矩阵了,所以说为了能够让这个就这个其实问题很大的,通常来讲你你迭代个十十几部或者100步。

那这个r就已经变成完全不完全不对的东西,它可能是一个一个奇怪的,就是可能是一个让这个东西发生形变的,一个一个矩阵了,它不是一个正交阵,所以为了能够让这个稳定下来,我们其实相当于每一步之后呢。

我们通常是需要对这r做一个正交化的,那怎么做正价化呢,那当然是这个大家这个大一的时候,这高大肯定是讲过的,比如说这个格莱姆斯格莱姆史密史密特正交化,你总是可以做的,有各种不同的方式。

那其实这个正交化虽然说是可以做吧,但是总体来说还是比较麻烦的,计算量比较大,那就回到了我们前面用的非常好用的,这个四元数,我们知道这个前面这个矩阵,我们用九个数来表示,但是用四元数我们只用四个数。

相对来说会容易很多,然后另外一个非常好的一个问题,就是说四元数的正交啊,因为单位四元数代表一个旋转吗,单位化比这个矩阵的这个正正交化啊,要简单很多啊,要算出来简单很多,所以实现类似的问题。

比如说我这个缸体,它的位置是x这个没有什么问题,它的朝向不用q来表示,那如果说它能通过同样的这样一个角速和速度,的这样一个啊移动,那这个位置变成x撇啊,实际上我们这个积分的公式我们是非常熟悉的。

其实关键就是说我如何去计算x撇,x的导数和q的导数,如果这两个算出来了,那其实后面这个积分,我就只需要把新的导数乘以达到t,然后加到那个q上就就就成立了,然后这个对于前面这r的情况下。

我们知道r的导数还是可以写成这样的关系的,对于q来说,就对一个四元数来说,那其实这个关系也是相对来说不是特别复杂的,就q它的导数是角速度乘以当前的速度啊,当前的这个q当前的这个orientation啊。

它的长线,然后1/2,当然这里这个乘法是一个四元数乘法啊,不是矩阵乘法,也不是这个点乘,它是一个四元数乘法,那这个过程中这个omega我们写成omega bar,那它时间是一个纯四元数,意思就是什么呢。

就是说它的实部啊,这个标量是零啊,然后这个向量的部分是当前这个角速度,然后知道这个点之后啊,这个q点之后,那么其实可以用一步积分,可以更新我的一个物体的朝向。

那当然同样的我们其实这里需要做normalization,做这个正交换,而不是正交正则化,那不然的话这个q也很快,因为我们要求他必须是单位置嘛,或者叫单位换,不是叫单换。

那如果说我们如果不做这个单元话的话,你也会发现这个q可能很快就会变成一个,变成一个这个差了很多的,一个一个一个四元数了,就不再是一个旋转,所以这是这个嗯求积分的方式,所以实际上比如说我知道了一个钢铁。

一个box,比个七一个一个方块,它在不停的旋转,那这个旋转比如我要仿真这个动画的话,我其实需要不断的去计算出它的每一时刻,他的这个位置和朝向,那我其实本质上就是可以通过这样的公式啊,去不断的迭代。

因为我因为我知道它角速度不是它的速度,那我其实可以不断的进行迭代,就可以得到他每一时刻的位置,和它的每一时刻的朝向,然后再画出来,你就能看到这个物体在旋转了,就是这样一个公式,那前面其实提到了。

就是说实际上到目前为止啊,我们其实介绍的还都是运动学的部分,就运动学其实关心的是什么,就是说比如说物这个物体的位置,那它的朝向,然后位置和朝向的一阶导数就是速度和角速度,然后二阶导数加速度和角加速度。

那可能甚至我们还有可能很好的更多了,比如说三阶导数和四阶导数,四阶导数等等等等,这些其实都是这个运动学,那另外一个方向是动力学,动力学关心的是什么呢,关心的比如说动量,比如说角动量,比如说力。

比如说力矩,那这是动力学需要关心的东西,但实际上更加具体来说,其实动力学关心的是什么呢,是这些量和这个运动学这些量的这个相互关系,那这个和相互关系最大的一个,或者是最主要的一些这种这种它的这个要素啊。

factor它是什么呢,其实主要是质量,你觉得实际上我应该说可能嗯,但是我可能这个说法也不一定是最最最正确的,但是从我的角度来呃,这个观点来看的,就是说实践运动学和动力学。

就是cinematics dynamics,其实就看你有没有考虑到这个角色的质量,那如果说你考虑到角色的质量,那你就是在研究一个运动力学,那没有的话,那其实就是运动学,因为质量是什么。

质量其实代表了惯性,惯性就代表了你不可能从一个地方去,直接瞬移到另外一个地方啊,因为这是这个这个这个,这是一个惯性所不允许的,我必须要缓慢的去变过去,所以这是一个非常大的一个不同点。

那当然我们讲到动力学,就有很多动力学的一些特性,一些属性,比如说最主要的最基本的两个属性啊,就是这个动量,角动量啊,线性动量和这个角动量,那从定义上来说呢,线性动量就是m乘以v啊。

如果一个粒子它的速度是啊,这个例子sorry,这速度是v,那它的动量就是m乘以v质量乘以速度,那对应它的角动量,角动量我们总是要有一个参考点,你比如说这个三点是o,然后从o到这个这个粒子的距离是r。

向量是r,那这个角动量要沿着这个相当于o的,这个角动量是这个m啊,m h r x乘以v这样的一个形式,就是这个粒子啊,这个粒子的这个动量和角动量,那相应的呢其实对于这个例子来说,我可以在上面加一个力。

加一个力,比如加一个f,那这个f呢比如说这个在这个app,它其实有两种性,两个效应,一个效应是让这个物体粒子产生移动,另外一个项目,也就是说比如说我选择了一个物体,选择了一个点,空中一个点。

比如说o其实这个物体x移动的时候呢,它其实是相会带来一个相对于o的一个旋转,你可以从o来看的话,那其实就x在你知道它转,但这个转可能同时也走远了,那这个旋转其实力,其实本质上也带来了这个旋转。

那带了这个旋转,我们用什么来衡量呢,这个其实我们用一个套就是力矩来衡量,所以说力矩是什么,例举其实是一个力啊,产生这个旋转的效应的这么一个这么一个衡量,那定义上来说。

它就是差这个gr叉乘i来构成这个例句,那就是实际上那我们前面提到了几个量,首先动量和角动量,然后力和力矩啊,其实是对于这个角度角度的部分,我们知道就是r就是它这个旋转的这个轴啊。

就这个参考点和这个呃质点这个相对的,具体这个r其实起到很关键的作用,就是我必须要有一个参考点,我才能去说我这个例啊,我这个角动量是什么和这个例句是什么啊,必须要有一个参考点,那这个公式指的就是这个样子。

当然这里前面说的都是一个质点啊,那我知道钢铁钢铁通来讲,我们可以认为它有无限多啊,大量的质点构成一体,构成了这么一个东西,那是因为缸体它是保证什么的,因为保证形状,或者说最近进一步来说。

它是保证缸体里边的,所有的这些质点的相对位置关系,是不发生变化的,就是钢铁的性质,那比如说这个钢铁,那么就可以看成它里面有若干个啊,无限很多很多个大量的质点构成,那每一个质点的质量是mi啊,位置啊。

然后所有质点的这个质量总和啊,其实就是缸体的这个质量,那这样的话这个对于每个位置,每个点的位置用质量做一个加权平均,那其实得到了一个点,这个点就通常被叫做知心啊,3d max之心。

然后最速度做一个加权平均,还会得到一个平均速度,那这个平均速度我们通常也叫做执行速度,那如果说我取了一个参考点,o这个o在哪无关紧要,反正就是就是一个参考点,在这种情况下呢。

比如说首先这个所有的速度的做动用质量,做一个加权求和,得到的这东西,其实是整个缸体的一个线性的惯量,sorry线性的这个动量,然后对于这个相对于这个参考点o来说,我们其实每一个点都可以算。

它相对于这个o的一个角速度角动量,然后把所有的这些角动量加起来,那其实就得到了整个缸体,相对于这个点的角动量,其实通常来讲动量是p嘛,然后脚跟是l,它是代表了整个缸体的这个角动量,原来角动量。

其实我们可以稍微再在这个改一下形式,因为我们知道这个因为xx就是我们的质点,我们是可以计算出来的,那我们其实是对这个才对,对于这点来说,这个质点到任何一个点它也有一个距离,我们可以写成r。

实际上因为对于钢铁来说,因为它形状不变,所以这个质点在钢铁中的位置,其实也是相对来说不会发生变化,那这样的情况下,每一个点,钢铁里面每一个点跟质点之间的连线的方向,也是基本不会发生变化的。

那也然后那样这样的话,其实我是可以把一个相当于一个任意的一个,参考点的一个角速度啊,我们是可以把它写成什么呢,写成一个这个质点相对于这个参考点的角速度,加上刚提的每一个点,相对于这个质点的角速度的。

这样一个这样一个这样一个啊求和啊,其实大概是这样的一个形式,那当然这里边,其实因为这个参考点是可以随便取的,那我们其实最佳最最简单的情况下,我们是可以把这个参考点就直接取在支点的。

这个世界标坐标系的位置,那在这种情况下,其实我们可以把这个角速度的这个表现,表达形式再简化一下,因为前面这一半这个r c啊,r c是代表什么,代表这个xc到这个o的三和点的距离。

那如果是把o的取在x c的话,那r c就等于零了呀,所以前面这项就没有了,所以说对于质点来说,我们其实可以计算一个相当于质点的角速度,角动量,那它其实是每个点相对于质点的相对位置。

然后插成每个点自己的这个速度啊,这其实是这样一个关系,那其实可以比如这个质点系统,可以因为质点系是一个非常重要的,一个通常非常常用的一个系,一个非常重要的一个参考系。

所以我们通常来讲我们后面我们再不加这个,不加这个强调的时候,那我们其实都是说我们的参考点,就永远是这个支点啊,就这个质心点啊,就知心的位置啊,这样的话是一个比较比较简单的一些形式。

那如果特别是如果说我们同时知道这个钢琴,它的旋转的速度omega,那其实我们知道这个v他应该是写成什么呢,这个v其实应该等于它的相对质点的速度,相当于质点,这个速度应该是欧米伽插上r这样的一个方式。

那这个其实因为看起来这三个连乘连续的差乘,我们可以把这r和欧米伽交换一下顺序,那前面带一个负号,再稍微整理一下,比如说把r写成它的这个插成矩阵的形式,但实际上前面这个l它的角速度。

角动量我们是可以写成每一个的r,那到执行的到每个点到直线的相对位置,然后呢这个叉乘矩阵的平方,然后乘以omega,然后乘以角度,乘以当前每个点的位置啊,质量啊,这样的求和的形式。

那么这个球和里面其实可以看到,omega是对所有质点相同的啊,所以可以把这个求婚这个做一个硅啊,做一个这个结合啊,就把前面这一块就把omega提出来,然后把前面这块作为一个整体,那这个这个东西是什么呢。

这个东西是转动惯量啊,i我们从来不用i来表示,它本质上来说就是前面每一个质点啊,相对于质心的位置的差乘矩阵的平方,然后乘以每个点的这个啊质量,然后求复啊,就这么一个东西,我们叫米德,是转动惯量啊。

或者叫转动张量,那惯量张量矩阵啊,就大概是各种名字吧,但总的来说它其实是一个3x3的矩阵啊,它不是一个标量,不像不像质量,质量是一个一个数,但是转动惯量是一个3x3的矩阵。

然后它其实是可以通过这种方式计算出来的,当转动惯量其实代表了什么呢,代表了惯性啊,其实我们知道,质量其实本质上是惯性的一个横梁,就我推一个重的物体,它很难去推动,那动起来之后就很难停下来。

那这个这个这个量就这个能这个能力,其实用这个质量来衡量来衡量,它代表了惯性,那类似的,如果一个物体它旋转,它是否比较容易地被转动,然后以及它转动之后,是否变得能够容易地停下来。

那其实由这个转动惯量来衡量,所以实际上转动惯量其实本质上是质量,在角速度上的一个类比,那这里其实是那个维基上找了一个例子啊,就是说这五个物体形状是一样大的,但是呢这个这个物体转动惯量最小。

依次往那边转动惯量增大啊,可以看到这个颜色最右边那个那个那个球啊,这个圆柱它的转动关联是这边的六倍啊,其实可以看到在同样的起始状态之下,主要能关联小的这个物体,它会更加容易去旋转啊。

这是一个非常正能关联的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

另一个非常重要的一个性质,另外呢还有一些比较,就比如大家可能上午课也经常看到一些实验,比如大家看滑冰啊,滑冰里边做这种高速的自旋啊。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

其实这个速度你是可以控制的,因为知道我们前面提到的转动惯量。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

它实际是这个每个质点啊。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

每个质点相对于质心的这样一个距离的平方。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

差不多是这样一个东西,所以实际上来说,如果说比如像这个例子,如果说我这个手伸开,那其实就相当于我增大了这个距离,其实相当于增大了我的转动惯量,那这个时候转动惯量其实会影响我的速度。

就是转动惯量大增大的时候啊,当然这里其实是一个角动量守恒的,一个一个一个一个展示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

就是专门关联大的时候,我相相对来说这个速度减小啊。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

才能保持我的脚能守恒啊,所以说你看他伸手伸开的时候啊,手放在这个中心的时候,其实是转动比较比较快的,但一旦手分手放开。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

它就速度一下降下来啊,这其实是以转动惯量带来的变化,那当然转动惯量我们前面提到了,它是一个3x3的矩阵,而且实际上我们前面的计算里边,是要求这个那个求和啊,它是一个位置相对于质心的这样一个方向的。

这个叉乘矩阵的平方,那这个方向是世界坐标系的方向,所以这意味着什么呢,意味着转动惯量,在随着我这缸体发生旋转的时候,它的大小,它的值会发生变化,那怎么变呢,其实这个比较简单的关系啊。

就是说比如说我在零时刻,我的专业关联是i0 ,他当时是这个旋转是r啊,到另外一个时刻啊,旋转比如说i吧,就是比如说他当前是时刻是啊,旋转是一个什么量,我先不管,然后从这个形状啊,这个状态到这个状态。

我旋转了r啊,这样一个旋转,那在这个过程中呢,首先质量是不会发生变化的啊,因为质量是所有点的这个本身的位置,在它跟柜子无关啊,所以它本身质量是不会发生变化,但是转动惯量呢他其实原来是i0 啊。

通过r的旋转之后呢,它会出现一个这样一个类似于夹心三明治的,这样一个结构啊,就是r乘以i0 j r的转置啊,这样的一个方式,那当这个公式其实它其实是比较容易推倒的,因为本质上是使用了这个叉乘啊。

对上的一个坐标转换的关系啊,其实可以很容易得到这样一个关这样一个公式,那另外一个就是,其实前面这也是告诉我们是什么呢,就是说随着这个旋转好,我们可以找到一个找到一个旋转。

然后使得这个在那个旋转朝向之下啊,这个转动惯量可以有不同的表达方式,那另外一方面其实我们知道这个转动惯量,那从它的定义里边,我们可以很容易得到一个结论呢,就这个转动惯量肯定是一个对称阵,正定对称的。

所以说它我们可以把它做一个这个正交化,对角化,我们可以也就是说我们可以找到一个旋转r,在这个旋转之下,我们这个一个任何一个这样的一个转动惯量啊,我们可以把它变成一个对角阵,那实际上这也说明什么呢。

说明实际上转动惯量,虽然说我们马上写了一个矩阵,但实际上我们关心的其实是里边,我们其实只关心三个数字啊,这个三个数字其实是这个特征值分解之后啊,在这个特征值分解之后,它对应的这个特征值。

那这个特征值所对应的特征向量,或者对应这个r其实也叫做这个惯动转的主轴,所以对任何一个三维物体的话,其实我要定义它的正能惯量,我只需要定义三个数字,代表它在三个主轴上的这个这个,转动惯量的这个大小。

其实就就知道这个物体在这三个方向上,大概有多么,这个就是转动上的这个这个阻抗能力有多大了,但是这样的一个性质,对当然我们前面也提到了,就是我们后面很多的这个计算,都是基于这个质心的坐标系。

就是质心坐标系,它本质上是一个以质心为参考点的一个坐标系,那当然实际上大家要特别注意一下,就是我们在说质心坐标系的时候,实际上只是对当前时刻啊这个物体的这个状态,我们假设有一个坐标系是放在至今的。

它这个治标系坐标系本身它是不会移动的,就是下一时刻,我可能要重新定义一个新的坐标系,也就是它不会带来一些什么,不会带来一些可能有些想想,一说到这个相对性原理啊,比如说可能这个会不会有这个离心力啊。

会不会带来这种这种这种惯性力啊,这不会的,就是本质上来说,这个知心系只是当前时刻的一个固定的一个,一个一个系,它只是位置放在知心上,让我们计算变得容易一些,那比如说这是一个缸体啊。

我们可以定义这样一个执行系,那如果说我们对这个钢铁上加了一个力啊,加了一个f,我不知道我这个钢铁如果加一个力的话,那其实是一方面会拉动钢铁去移动,另一方面呢它其实是钢铁,因为它不在质心嘛啊。

我知道知至亲它其实是一个比较重要的东西,他如果不在之前,它会带来一个旋转效应,它让这个物体沿着这个质心发生旋转,所以实际上对于这样一个力,它实际上在质心上会产生两个效果,一个效果是让这个质心产生移动。

另外一个效果是让这个物体沿着质心发生旋转,那其中这个让物体产生移动的这个效果,实际上它是有这个相当于等价,于是把这个力直接作用到质心上产生的效果,那同时呢让这个物体发生旋转的这部分呢等价。

于是说我在这个物体上加了一个例句啊,这个力矩的大小是等于原来这个力的位置,这个r叉乘力的大小来得到这个力矩,当然这里还有一些其他的问题啊,这通常我们有些经常会有一些情况,就是说我没有加一个力。

我直接加了个力矩,那这个力矩肯定它会带来一些效果了,这个效果就是让这个缸体发生旋转了,那这里其实有一个问题啊,可能就是说那这个例句到底是怎么加上去的呢,就是在数值上数据上比较好加。

我就说你这加了一个多的东西,这没问题,但是在真实世界里边,我们是怎么实现这个例句的呢,其实可以比较容易想到,就是说因为本质上来说一个例句,最终的所有的例句,其实本质上都是由利益来产生的对吧。

所以在这种情况下,我们其实是相当于是什么呢,我们相当于是加了在两个点上,在这个钢铁的两个不同的点上,加了一个大小相反啊,大小相同,方向相反的力,当然不一定,这是两不一定,两个力可能也更多了啊,总而言之。

就是说这三个力是没问题,就是说你你这三个力的这个向量的和肯定是零,这其实保证了什么呢,保证了他们三个力,所有这些力在中间那个点,因为本质上这个质心是否移动,或者质心上的这个移动的平移。

这个效果是所有力的这个求和得到的,所以说如果说这些力就大小相等,求和等于零,那就代表着他这这这中心点是没有力的效果,但是呢因为每个点都会对,中心点有个有个力矩的效果。

那每个点的力矩叠加会产生一个所谓的尽力局,就是就是一个就是一个诶,不好意思,就是一个只有例句没有力的这么一个例句啊,所以本质上来说我们这个只要看了一个例句,我们可以近似的就想象啊。

它其实是有一对或者很多个互相平衡的力,作用在不同的位置上产生的这样一个力矩,那类似的如果说比如说这个缸体上,我们其实可以在不同的点加很多不同的力,然后又加很多不同的例句,那所有的这些不管我加多少。

对于钢铁来说,我最终总是可以用一个力作用在质心上的,一个理和作用,在质心上,相对于这个至今的一个这个转的惯量来表达,我们前面这么多力和力矩,这个相对相对作用啊,这是一个这样一个关系,也就是说。

这个我们可以认为是所有力的这样一个求和,然后力啊套是所有的力矩的这样一个求和,那接下来呢,我们其实也需要了解一个非常重要的关系了,就我们知道这个动力学和运动学,动力学的量啊,力啊,方向位置啊。

位置方向速度,角速度,动力学的量啊,惯量角动量,然后力和力力矩,首先这个过程中,首先这个转动惯量啊,就是角动量和动量,和这个前面的角速的这个关系,我们是比较明确的,因为我知道m i之后。

这样可以直接得到了,但是其实这些关键就是说我们要知道f和套,就这样两个力跟我的这个冠啊,这两个动量之间的关系,那这个关系通常叫做equation motion啊,叫这个运动学公式。

其实我们最常用的非常理,大家非常熟悉的这个f等于ma,它其实是一个应用学公式,但他只关心物体的平动,就不关心这个旋转,比如例我当时写成f等于ma这样的形式,但是我们知道这个嗯,因为a嘛。

因为这个角动量p等于m除以v,然后a又是v的导数啊,所以说我们其实可以写,知道这个f其实应该等于dp,就是就是线线动量,就是动量对时间的导数等于f,那其实也是牛顿第二定律另外一种形式。

那另外一个对于旋转的这样的一个公式,有另外一个公式叫做那个欧拉运动定律,实际上牛顿第二定律,这个形式也是你欧拉运动的第一个,第一个公式就拉欧拉运动能力其实有两个公式,第一个公式其实就是牛牛顿第二定律。

第二个公式,时间是欧拉这个旋转的这样一个角动量定律,这样的一个形式,那在这个形势之下啊,我们知道这个,呃首先这个牛顿第二定律啊,dp就是动量的导数等于力,欧拉定律告诉我们,角动量的导数等于力矩。

所以这两个公式合在一起,就构成了刚体的运动公式,那我们可以进一步的因为这个p啊,动量是m乘以v嘛,那我们其实对它求导,可以知道m乘以v的导数等于f,因为f是不动的,m是一个质量。

质量是一个这个随时间不会变化的这么一个量,ok当然如果说你说要变化的话,那就不是钢铁,然后对这个角动量导数会复杂一点,复杂在哪里呢,因为主要是这个转动惯量,我们前面提到了,它随着我这个物体的朝向不同。

它的这个数也不同,所以说实际上物体的过程中,运动过程中,它的这个转动惯量也是会发生一发生变化,所以实际上这个你对l的求导,相当于对欧米伽的求导,加上对专门过量的求导这样的一个形式。

那当然从转动惯量的公式呢,我们其实可以进一步的稍作推导,我们其实可以得到这样一个形式,就是说对l的求导,对角动量的求导,它其实是i乘以欧米伽的导数,加上欧米伽叉乘i乘以欧米伽啊,这样的一个形式。

然后这两个公式联立嘛,我们通常来讲可以把它写成一个矩阵的形式,就是把v和omega啊写成一个向量,向量代表当前物体的这个速度的状态,然后前面是这个惯量动量啊,sorry质量和转动惯量。

然后中间是一个这个这个inertifalse,其实是转动惯量的这个导数的这个值,然后右边是我加的外力,也就是说,如果说我在这个物体上加了这两个外力,那这个外力所产生的这个加速度啊,在速度这个现象。

线线加速度和角加速度啊,其实它满足这样的一个关系,那这关系我们前面提到了,它是以窥视motion啊,就是运动公式,那同时呢这个方程也叫什么,叫合在一起叫牛顿欧拉方程,因为上一行是牛顿,下面一行是欧拉啊。

欧拉一声牛顿欧拉方程,那实际上我们可以进一步的,因为这里是一个v的导数嘛,v的导数我们知道我们前面用欧拉公式的时候,我们知道这个vn加一等于vn,加上v导数乘以h,那其实可以反过来。

可以把v的导数写成vn加一减,vn除以h这样的形式,那接下来类似的我们也可以写成这个样子啊,其实这个公式呢可以把前面这个东西写成下,但这个特别注意啊,其实这个离散化的过程,这个其实就是一个离散化的工程。

这里边这个加速度这一项啊,我用的是vn加一减vn啊,但是这个i特别注意i其实是一个怎么说呢,它是一个转动惯量,它跟这个当前的状态有关啊,当然理论上你可以写成i n加一,但它就变成这个求解变得非常复杂了。

所以通常来讲这个iphone当前时刻来写,那类似这个omega x成i omega n也是当前时刻啊,这是一个运动模式的一个一个矩阵的一个形式,离散化的一个形式,那再进一步的。

其实整个的对一个单个缸体的一个,仿真的流程啊,大概就是这个样子,那首先呢我其实是根据当前钢铁的朝向,加上单缸体本身的一个初始的转动惯量,来构造这样一个方程,挂到这个方程之后呢,我们可以求解啊。

这本质是一个比非常简单的线性方程了,我们可以解除v和omega就是加速度和角加的解释,速度和角速度在下一个时刻啊,这样一个速度的值,那接下来做再做一部欧拉积分,那就可以更新我当前这个缸体的位置。

和这个朝向,那做成动画的话,你就可以看到这个钢铁在那旋转了,那产生这样的一个效果,那当然这是一个缸体,啊但如果是两个钢铁该怎么办,其实两个钢铁很简单,如果说是两个钢铁,质量就是刚才我们所说的那几个量嘛。

质量张灯光亮位置朝向速度角速度啊,如果说我们知道这两个缸体分别的这个量的话,我们可以很容易把前面这个把这个公式,它其实是一个钢铁啊,我可以很容易地把它扩展成两个缸体。

因为如果说这两个缸体没有任何关系的话,它就是两个独立的钢铁,我们总是可以写成,就是相当于把这个原来是两行,我直接扩展成四行啊,写成这样一个公式,但这个公式太大了,不太好记,我就再简化一点。

这个v时间是代表什么,代表这四个量啊,v的导数,然后这个代表了前面这一大串这个这个矩阵,no sorry,然后这个c啊其实是是中间这一块,当然c是同时是x和v的矩阵函数,因为v是比较好理解。

因为包括了欧米伽那x s,那这个x体现在哪里呢,x t是体现在i里面,我们知道转动惯量里边是需要这个朝向的,然后朝向其实是xr的这两个东西,所以说实际上我们可以写成这样的一个,简单的写成记记录。

是这样的一个方式,那这个实际上是后面这一坨啊这样一个公式,那这样其实就相当于我是总之实现了,写出了这两个缸体的这样的一个旋转公式啊,他这个equation motion运动公式,那如果说我做一次积分。

那就发现诶这两个物体分开了,因为确实分开了,因为我们对染物体没有任何的约束嘛,它们它们就是两个互不相干的物体,只是我们硬把它放在了一块,那当然这个东西怎么说呢,我们通常来讲觉得他不是特别有意思。

我们更加关心的是什么呢,我们更加关键的是说,这两个缸体中间有一个关节,关节是一个什么东西呢,它其实相当于是一个约束,它会禁止啊,禁止这两个物体分开,它运动过程中,他总是会不能把这个关关键给破坏掉。

该怎么禁止的啊,我其实实际上对于我们这个至于世界来说,我们为了能够禁止一件事发愁,我们肯定要加一点力呀,不加力的话,你怎么能把它禁止掉,所以实际上本质上来说,这个关节它在这个运动过程中会产生一对。

比如说他会在这个物体上加一个fg,然后在另外一个物体上呢加一个,因为你问第三定律嘛,他会加一个负向的f j,然后这两个分别作用在对应的物体上,导致这个物体在旋转过程中是不会分开的,所以说本质上来说。

本来原来这个没有任何约束的这样一缸体,它其实公式是这样子,我外面加这个力f是我随便加的,但是呢对于如果说我这里加了一个dt,加了一个关节,这个关节呢会出在我这个自己啊,外面外加这个力f之外。

我又额外加了一个约束力f g,他这个fg会跟这个f共同作用,让这两个物体产生移动,那同时又不会分开,这是一个问题,那当然这里问题有什么问题,有一个什么情况呢,就是说这里我们是知道的。

那肯定是我问我这个外面加的嘛,我是知道我加了多少,但是这个fj我是不知道的,因为它本质上来说是这个关节,根据我这个缸体的状态啊,以及我外面加的这个力来算出来来提供的啊,所以说这个fg是不知道。

那或者我们再简单再进一步的简化一下,这个问题,再简化一下这个问题,就比如说我要求这个物体,我们先不管关节,我觉得空间里有一个曲线啊,平面上有个曲线,别空间了,平面上一个曲线。

这个曲线的方程是gx等于c啊,但是其实是x是二维的一个量,g2 等于c,然后一个小球啊,是一个平面的小球,我要它必须是沿着这个曲线进行移动,那这个代表什么呢,代表这个小球,它每一时刻它的位置都是要满足。

gf等于c这样的一个关系,在这样一个条件下呢,实际上因为它每一时刻都满足嘛,那我们其实可以两边对时间求导,那就可以得到这个小球的位置呃,这个左边那个导数是这样子,右边是因为c是一个常量。

所以右边导数是零,那左边这个应链应用链式法则,我们就可以把它写成什么呢,写成g相当于x,因为g是一个x的函数,它是一个曲线,然后以及x的导就是速度这样的一个形式,那可以把它再简化一下,不是简化。

就是换一个形式,就是又又把我们当年这个非常熟悉的这个,雅克比矩阵捞回来,比如说这个左边那个打求导,我们其实可以写成一个甲壳b矩阵,一个j乘以v,然后等于零的这样一个形式。

那这个g其实是一个价格比雅克比矩阵啊,它是g的梯度的这个转置啊,可以写成这样的一个形式,也就是说这个这其实就代表了一个什么,代表了一个约束,约束是什么,就是在任何一个时刻,我们的这个物体高管在哪。

它的速度一定要满足这个公式啊,这是我们这个约束的一个定义,那当然呢为了能够让他满足这个公式呢,我们必须啊就这轨道嘛,这相当于是一个轨道,这个轨道肯定要给这个小物体一个力的,如果不给力的话。

那就物理就飞了呀,根据牛顿第一定律啊,它就飞掉了,所以说为了为了能够让它沿着轨道移动,我一定要加一个力,那这个力叫做约束力,但实际上对于在物理上来说呢,其实约读出了一个非常基本的要求。

就是它不会产生能量,其实想象一下,如果他产生能量会出现什么问题,能量吧就相当于带了速度,就是这个物体放在这不动,我就往上范围,没有加力,它就自己加速了,这肯定是不对的,所以实际上约束力啊。

从物理的角度讲来讲,它是不会产生能量的,不会产生能量意味着什么呢,意味着约束力始终跟物体移动的方向是垂直的,这是这是不会产生能量的一个必要条件,比如说这个约束力它是一个向量,他点乘这是就是谁的点乘啊。

点乘这个v应该始终等于零,这是我的这个没有能量的这样一个基本要求,那在这个压缩之下,其实回到结合我们前面的叫g乘以v也等于零,首先这两个是看起来形式是很像的,首先j是什么,这是雅克比矩阵。

对于一个这样一个二维来说,它其实是一个向量,所以一个向量点乘一个v等于零,然后会作为另外一个向量,它点成v也等于零,然后v又是一个任意一个量,那其实说明什么呢,说明实际上f和g就是至少它是共线。

其实这里应该是点乘啊,这里其实没有写,应该是点乘,所以实际是f t乘以v等于零,所以你是可以得到什么呢,可以跟fc呢应该等于g的转置乘以lond啊,代表london是一个数,这是一个方向。

他这个代表的是说我这个fc,因为它肯定是跟j是共线的,当然共啊跟gt是贡献的,贡献之后呢,当然这个贡献我只是个表的方向,那个大小是多少,我是不知道的,所以说这个大小我用ladder来表示。

所以整体这个代表了我的约束力,当我们前面提到了,约束率大小是需要根据当前物体移动的状态,然后以及外力等等共同结合起来计算的,那这个问题就是说我们怎么算啊,这是一个非常重要的问题,那怎么算呢。

比如说我们现在这个状态下,比如这个还是刚才那个问题,这个小球上呢它的质量我知道,然后位置和速度都知道,然后呢在小钱上我加了另一个力f,那我们其实知道对于这个角色做事例分析啊。

我们知道时间他也肯定是至少受两个力啊,一个是我给出的外力f,另外一个是一个不知道大小的一个约束力,但是方向我是知道的,所以实际上这个应应用这个牛顿公式,我们只考虑这个位置的情况下的话。

那其实可以ma等于f,f等于ma嘛,然后f里面有两部分,一个是外力加上一个约束力,约束力的方向是gt大小是london london,我不知道,同时呢,我要求我的速度必须满足这样的一个。

gv等于零的这样一个要求,ok,那我们可以把这个公式,其实是一个连续的一个公式,我们可以把它离散化,离散化是什么呢,把v点啊写成欧拉欧拉求和的这样一个,就是用欧拉求和来代替这个v点啊。

其实可以写成这样的一个关系,然后呢我是要求下一时刻的,因为当前时刻肯定是满足的,这是在我的这个假设之下,我是要求下一时刻的,也要满足g一乘以v等于零,这样一个约束关系啊。

其实写成这样的一个g一分加1=0,的这样一个形式,那可以看一下这个方程,那这个方程里谁是不知道呢,lambda是不知道的,vn加一是不知道的,这两个量不知道,但是vn我是知道的,随着时间。

我是通过这两个方程联立去求解,vn加一个兰达,ok当然这个其实求解就比较简单,它是一个线性方程,我们可以直接写成矩阵的形式,然后求逆啊就可以完成这个计算,当然这个过程中有几个问题啊,一个问题就是说。

我其实是假设,当前时刻的是满足这个g v加1=0的,这样的要求,但这个其实并不难实现了,但是呢我们最初的要求,我们最早的那个约束,其实是想让这个物体始终在这个轨迹上。

也要求g x等于c这件事情有可能是不整理的,为什么呢,因为还是那个问题,这是一个非线性的函数,我们总是在用一个线性的东西去逼近它,它会有误差的,所以你会发现这个物体在移动过程中呢。

虽然它的速度满足这个要求,但是呢物体会逐渐的离远离了这个这个轨道,因为我只约束速度,我不能就对他那个位置上会有点误差,所以为了解决这个问题呢,我们通常来讲这个速度这边并不是零,这个是什么呢。

这个是说我会把这个零替换成什么呢,我说要求我这个物体下一时刻的速度啊,应该满足是说如果它偏离的轨道,它需要把他拉回来啊,它会有一个把它拉回来的速度,那这个拉回来时间是以写成这样的方式。

就是我要求的一个c啊,减掉我当前它已经偏离了轨道之后呢,它它会它这个用g,他的gx的这个值会跟c不同啊,那这两个其实有偏差,那这个偏差乘一个系数,就代表了我需要用多快的速度把它拉回来。

那这个系数那配置有一个名字,那通常有一个叫做e r p啊,叫error reduction parameter,其实这个在很多地方都可以见到,那叫e r p,它本质上是做这个做这个作用。

ok那我们可以简单把这东西写成一个b啊,有的为了简单起见,那这个函这个方程我们可以进一步求解啊,就比如说可以用前面那个把,因为m是一个质量矩阵吗,它是可逆的,我可以把这个m的逆乘到右边去。

然后可以把vn加一写成右边这一坨的形式,然后再把vn加一代入到下面这个公式,大家可以自己下去自己算一下,它最终可以大概的形成这样的一个形式,就是说把这个原因vn加一已经替换掉了。

所以现在只是lambda的一个一个一个函数啊,只是lada的一个一个啊公式,一个切线方程k大概是gmt逆乘以g t,这是非常非常容易经常看到的一个形式,那为了求解下面这个方程啊,前面是已知的。

lambda是未知的,所以我本质上来说是要把gm逆乘以g t,这东西是一个矩阵对它进行求逆啊,乘到右边去,但这里有个问题,我们每次求逆的时候都需要特别小心,因为那个矩阵有可能是奇异的,它可能不可逆。

或者他这个数值条件非常差,会给我们这个求解带来一些困难,所以为了解决这个问题呢,我们可以在这个请问这个,其实我们前面讲的那个x数,已经用过这个trick了,就是这个东西可能它不是不可逆的。

那我们加上一个小的一个贝塔,乘以一个对称阵啊,sorry成一个单位阵,那加上完之后这东西肯定是可逆的,那这个时候右边这个贝塔怎么说呢,就是它一方面可能让我的求解不是很精确。

但另一方面它能改善我的数值误差,那实际有这样的效果,那这个贝塔其实也有个名字叫cfm,the constraint false mixing,那就是另外一个参数,也是我们在这个物理仿真。

实现物理仿真器的实现过程中,也非常重要的另外一个参数,那通常来讲这个cfm这个b应该是比较小,本的话这个误差会非常大,ok那其实我们就讲完了这个关于这个constrain,这个约束的这样一个定义。

那实际上刚开始是非常简单的,我是在一个线上做一个这样的一个,约束的一个计算,但实际上对于我们这个john的来说,我们其实可以做类似的一个方式,因为dt一个关节,他是有什么要求呢,就是我们在旋转过程中。

这个点是不能分开的,不能分开意味着什么呢,因为这个点相对于两个两个钢铁中心啊,质心这个相对位置,在局部坐标系肯定是保持不变的,然后呢我从这边一个坐标系啊,这个缸体从它的执行加上这个相对位置。

可以算出这个缸体啊这个关节的位置,然后从这边也可以算一个关键的位置,如果说他那个没有分开的话,那说明这两次计算的关节的位置应该是相同的,如果不相同,说明就分开了,所以实际上这个这个矩阵啊,扫这个约束啊。

其实本质上来说是从左边计算的关节的位置,和从右边计算的关键位置应该是相同的啊,这其实刚才我的那个gx等于c,那对这个求导啊,求导我们其实可以就直接可以得到一个很简单,很容易得到一个差成的一个形式。

是左边那个位置啊,乘以欧米伽x r,然后右边那个速度加上欧米伽二插上r,那这个再整理一下,那其实可以写成这样一个东西,这是一个矩阵,这是一个3x12的一个矩阵,那i是一个单位阵,3x3的单位阵。

然后这个r是这个叉乘的矩阵,其实可以从这个差成获得,然后呢,接下来是接下来这个,然后接下来右边是我们还是我们非常熟悉的,这个v的啊,速度那些项目,那这个其实我可以把它再简化一点。

就是符号化写成g乘以waiting,就前面这个就是我的假牙科比矩阵了,右边是我的速度,那这个就得到了我们的这个约束的,这个这个方程公式,所以进一步的就是跟我们前面提到的,那个是那个两个缸体的运动方程。

加上我的这个关节的约束方程合在一起啊,那其实合在一起,或者我们把它其实前面就这样一个形式,合在一起,那其实就构成了我这样一个两个缸体,加上一个关节啊,这么一个小的一个系统。

它所构成的一个完整的运动方程啊,运动方程加上约束方程,那这个东西求解,我就可以得到约束力的大小,lander是约束力嘛,约束力大小以及下一时刻的每一个钢铁的速度,可以保证我在运行过程中它不会分开。

那当然这个约束是一个非常简单的约束了,本质上来说它是这个bgt的约束啊,就说我不关心这两个,这两个缸体之间的相对的朝向关系,我只关心这个位置啊,它不能分开,但是对于前面那两种。

比如说这个universal啊,对于那个hinge上的hdht黑照呢,它的约束其实要再多一点,就是除了我这个关关节的位置不能分开之外呢,我其实还是要求这两个物体的角速度,必须是满足这个性质关系。

比如这两个角速度,只有在这个轴方向上的速度可以不一样,在另外两个轴必须相同,所以相应的我下面会多两行啊,为了为了实现这个角色的匹配,那类似这个universal joint也是类似的。

我们可以分析一下到底哪两个,哪两个轴应该是对称和对应的,那我们可以把它约束掉,也可以写成类似的方程啊,等于就是不同的关节,可能还有其他的关节,比如说一个平面关节,它只能在平面上移动。

那其实对应的也是另外一类不同的一个,亚科比矩阵,那怎么去实现呢,你总是可以写出这个这个约束本身的方程,然后求导啊,它总是一个类似于叉乘,和这个类似于这样的一个形式啊,大家可以自己去想。

当你知道这些约束之后呢,那我们就知道一个完整的,比如说一个人,一个虚拟角色,那通常来讲我身上比如20个钢琴好,19个关节,把所有这些东西放在一起,就是跟前面两个关节,两两个钢铁关节本质没有本质区别。

就只是说我这个运动方程前面这个会更大一点,然后下面那个矩阵呢这个行数更多一点啊,所以说构成一个更大的这样一个方式,但是本质上它的数学推导是相同的,当然我们前面提到的,就是说这个东西还是在天空中啊。

随便乱动啊,但是通常有一个很大的一个常用的,常见的一个新问题,就是我这个人怎么站在地上,因为我站在地上的时候,地面肯定是要给我一个支撑力吧,那这里其实有一个问题,就是说我跟地面,就我站在地上的时候。

我肯定是跟地面有一个接触,那这个接触的力,肯定是在这个接触的这个位置上产生的,所以这里其实有几个问题,就说我们对这个接触该怎么处理,就是怎么让怎么处理好这个接触,能够让我这个人站在地面上。

难道这里其实有两部分需要解决的问题,第一个问题是碰撞检测,接触点检测,那这个其实是一个,相对来说是一个几何的问题的,就比如说是根据我的这个接触的,那个物体的形状,比如它是球形啊,或者他是一个正方形。

长方形啊,或者一个mesh啊,或者是一个曲线曲面,那我们可以用它的相应的方程啊,加上地面的方程来去寻找啊,来去检测到底有没有点进行碰撞,然后以及这个碰撞的深度啊,这个深度是一个非常关键的一个量。

因为为什么有这个深度呢,其实主要是因为我们这个整体,我们的积分是离散的,离散的意味着什么呢,比如他在上一时刻,他可能连一个地面有点距离,但是有一个很大的速度,然后在下一时刻隔了00:00:01之后呢。

因为这个速度呢会导致它移动一个距离,这个距离会导致我在下一时刻,它落到了这个地面之下,那你说说他其实本质上来说,是在这两个时刻中间去碰撞的,但是因为我们检测的时候。

我因为我们并没有去计算中间的这个点的位置,所以时间它会带来一个穿入啊,就有一点这个进入深度这样一个一个点,那单只是因为我们是做在做离散的碰撞检测,但实际上我们知道有另外一个方法,做所谓的连续碰撞检测。

它其实是会使真实去计算出,我到底在这两个点之间哪一时刻发生碰撞,那当然这种就更加复杂一点,就是我们很多时候它带来的这个效率,可能跟它带来的好处,就是你可能就需要一个平衡。

就是很多时候我们做不需要做很精确的,仿真的时候,这个碰撞关系我们是可以不用关系的,我们都只是允许它有一些这种陷,陷进地面的这样一个效果,当碰撞检测我们就不关心,就总而言之,我们总是可以找到一个办法。

可以算出这个碰撞点的位置,那当然我们算出高点的位置之后呢,那碰撞点那肯定要加一些力,才能保证这个物体不会继续陷进去,或者说至少把这个人正能够站在地面上,那这个力的大小该怎么算。

但这个大小其实也是有几种不同的计算方法,其实对应了什么呢,就是每一种计算方法,对应了一种所谓的碰撞模型,最简单的碰撞模型就是所谓的penalty base,就是法向的这个碰撞模型。

其实它本质上来说是什么呢,因为我知道这个物体,比如我的脚跟他已经陷进地面里了,那我呢可以是根据我跟线进地面的这个深度,比如陷得越深,那我就加的力就大一点,避免他陷得更深,那线的不是很深的话。

那相对小一点,就是这个总体来说是这样一个关系,所以我这个力可以写上一个,有点类似于弹簧的形式,大概就是我在这里加了一个弹簧,弹簧,把这个物体拽上去,这个拽的大小是说是一个弹簧劲度系数乘以。

我陷进去的深度啊,这么一个值当然要特别注意,说深度大于零的时候,而且深度小于零的时候,比如说我这个物体没有碰撞的时候,这个f项也是零,应该是零,就它有一个它是就是你如果没有碰到地面的话。

你是不应该有这个象的,所以实际上只是说只有当深度大于零的时候,才会有这个力,但只有前面这个力是不够的,它会带来什么效果,但是这个这个弹簧像一个蹦床一样,一落地就被弹飞了。

所以实际上其实还是为了为了能够让这个力啊,让这个弹就是地面,其实说落地之后,因为比如我知道我穿鞋嘛,或者我的皮肤它是软的,它就会吸收这个力量,它会有一点好散性,所以说第二部分其实是一个阻尼项。

它代替了代表这个耗散作用,就是我落进去之后呢,我会越漏越慢,而不是说会被弹飞啊,它会根据我的当前的速度来更改我的力的值,那这个其实代表了我的一个,对他其实提供了什么效果,就是这个人弄在地上。

他会有一些的penetration,会有一些的这个陷入,但是呢这个它不会陷入太多啊,取决于我这个刚度系数,但另外一个方向呢就是说时间,这只是我的支持力的大小,但是我们知道我们地面总是有摩擦力的。

因为不是光滑的,因为不光滑的皮表面,你总是互相会有摩擦,但带来一个相应的效果,然后摩擦力的大小我们知道虎克定律,虎克摩擦定律啊,sorry,不好意思,不是虎克库伦摩擦定律。

它其实是给我告诉我们一个经验的一个关系,就是相对的一个经验公式,就是说这个动摩擦动摩擦,动摩擦的大小是等于支持力的大小,乘以一个摩擦系数,当然我们通常来讲摩擦系数是小于一的啊,大部分情况下可能用0。

8或者一,就就就足够模拟大部分的情况,那所以说对于我们前面这个penalty base contact,我们其实前面两分成两部分,一部分是计算出地面给它的支持力,这是跟它的限制镜的深度以及它的速度相关。

另外一个就是它的动摩擦的带来的摩擦力,就摩擦力的方向跟我的速度方向是相反的,同时呢大小应该是这个力的方向啊,支持力乘以一个系数,单只是动摩擦,但是我们知道大部分情况下我们是静摩擦,静摩擦是什么呢。

就是说这个物体是没有发生任何移动的,但我依然要有一个摩擦力,但这个摩擦力大小是可以指零的,但是从0~1个静摩擦系数这样一个范围内,可以,它的大小是可以变化的,但在这个情况下,我们该怎么去建模呢。

那个劲空空架复杂一点,因为panel的base方法就是说你没有移动就没有力,你有了移动才有力,所以这种情况下它不但容易去建模这个静摩擦,但是要建模的话,其实也有一些方法去做了。

但是这个相对来说是一个比较比较,这个这个怎么说呢,比较这个at hot就是拍脑袋拍出来的一些想法,但你多少还是能够模拟一些这个静脉上的效果,但另外一种方式啊,其实这种panel的被子方式。

一个最大的问题是什么,是这个k啊,这个kb啊,还有kd,就这两个东西通常来讲是要调的非常大的,如果不是很大的话,你会发现,就好像一个真的,就是像一个泥泥船或者b蹦床啊,这个脚踩上去之后就陷就很深。

所以为了能让这个角,比如我踩在地面上的时候,不要线就很深,我需要这个kb非常大,才能保证我线距的深度是比较小的,但是非常大会带来一个什么问题呢,会带来我们前面仿真的数值不稳定啊,他会非常容易就崩。

所以时间这个这个为了能够让它稳定的话,我们通常来讲是需要一个比较小的,一个一个不长时间不长才能保证稳定性啊,或者是甚至有啊,我们是没有办法,就是这个东西其实很难去使用,那个影视的方法去计算的。

对普通人来讲是一个很小的步长,所以说这个其实也是一个,也是一个需要非常小心去调调整的一个问题,因为步长太小的话,我计算量就会很大,所以另外一个方式呢,就是说我其实是如果说我能够把这个摩擦啊。

不是能够把这个contact把它建模成一个约束,因为本质上就是一个约束嘛,它禁止我这个物体跟地面进行碰撞啊,进行这个接触,甚至甚至往接触下面的下面进行移动,所以说另外一种方式呢。

就是说常用的就是把一个contact,把一个接触点把它建模成一个约束啊,有点像关节约束一样这么一个东西,那当然约束其实我们这个方程是什么呢,这个方程其实跟冠军很像,就本质上来说我是要求我在移动的过程中。

这个点其实更关心的是,应该说是这个点在竖直方向,就跟这个跟接触面垂直的这个方向啊,它的位置,要满足有关系的啊,就是实际上我们可以算出来,这个这个点在整个缸体移动的过程中,它在竖直方向的这个速度啊。

我们可以写成写出这样的一个关系来,可以写出这样的一个关系来,但在过程中呢我们是要求什么呢,我们我们的约束是要求,我在竖直方向的速度必须是大于等于零的,那意味着什么呢,就是说它可以向上移动,向上移动。

因为向上移动我就离开了接触点,而不能向下移动,因为向下移动会造成这个接触更加厉害,所以它是一个单边的,就跟前面那个关节约束不一样,关节约束说我这个点必须在这个位置,所以他那边是等于零。

但是呢我现在这个对于接触点来说呢,你是可以向一个方向离开,你不是一定要在这个位置,但是你不能向另外一个方向移动,所以它是一个单点,它是大于等于零,同时呢这个接触力的大小应该也是大于零的,因为接触力嘛。

地面我踩在地上,这个地面应该只能把我推开地面,而不能把我拉向地面,拉向地面,就是万有引力,这不再是一个接触力了,所以说对应那个力大小,也应该是大于等于零的啊,所以说这个构成了一个完整的一个约束。

那除除此之外呢,其实还有一些另外一个条件就是什么呢,如果说我这个物体在这个点,他已经开始向外移动了,因为它已经开始脱离接触了,那在这个情况下呢,我就不应该再给他额外的加一个力了,为什么呢。

因为这个物体已经在向外移动的过程中,如果再加力的话,那这个力就会产生就会做功了对吧,就是说如果说这个力,比如我在这个点上加了一个力,然后这个点就像了连着力的方向产生了移动,那这个力就做功了。

但是我们知道这个约束力是不做功的,所以他就要求必须是说什么呢,就这个点如果再开始移动了,就它速度大于零了,我的力必须要等于零,这才能保证它不做功,那相反的,如果说这个点呢当时的力是大于零的。

那这个时刻下它一定是不能移动的,那否则他这个力也做功,所以说其实有这样的一个要求,那这两个整体来说,这所有的这些约束合在一起,构成了一个更加复杂的一个方程,这个方程呢叫做线性互补方程啊,线性互补问题。

lcp问题他吃,这是另外一种,我们通常会把这个啊碰撞,进行建模的一个方式啊,就是说首先速度要大于零啊,必须要离开,不能深入,第二呢力只能拉啊,只能推不能拉,就用力是要大于等于零的。

那另外呢就是为了避免做功,那力和速度不能同时不等于零啊,必须有一个等于零,这是一个线性互补条件,当然这个方程比较难解了,通常来讲有各种不同的方法去求解,比如说像o d e啊或bullet。

用的是是那个嗯单词的方法,单词其实是一个单纯形的,一个单纯形法的一个实现,那当然还有一些其他的方法,那我们这里就不多介绍了,总而言之,就是通常来讲,我们的物理引擎会给我们提供这样的功能。

那当然这里只是支持力量,但是如果说你想讲解摩擦力的话,其实会更加复杂一点,大家有兴趣的话,可以去看一些这个tutorial或者是paper啊,比如这个非常经典的194年的一个paper。

那就是机可以用一个非常快的方法去实现,这样一个动摩擦的,静摩擦的这样一个啊约束的一个建模啊,其实我们后面很多的仿真的引擎都是采用的,就是ba啊,david ba他们当年的这些很多工作。

在我们后面常见的引擎里都会都会被使用到,那最后其实我们就是完整的介绍完了,我们这一个比如说我想一个放一个人,那这个人该怎么仿真呢,我们把这个人设成关节这种骨骼,那骨骼其实对应的就是钢体。

因为骨骼不会发生形变,那骨骼它有它的质量啊,它有它的转动惯量,它的速度有它的角速度,然后同时呢关节有一个约束,它会静止,骨骼会发生分开啊分离,那再接下来呢这个人站在地上,那地面需要给他一个支持力。

那这个仿真过程大概就是这个样子,首先这是一个人啊,看起来非常抽象,它包括了我们上面说的所有这些信息,那通常来讲,首先我需要做一些简单的初始化的运算,比如说需要根据当前的每一个骨骼的朝向。

计算这个骨骼的这个嗯转动惯量啊,过量矩阵,然后以及如果说我用这个penalty base contact的话,那我需要计算这个contact false,比如支持力。

那接下来呢我们其实要构造这么一个运动学,方程里面最关键的是这个关节的这个约束,然后对这个运动是方程求解啊,我们可以得到下一时刻的速度,和下一时刻的角速度啊,这就是包括在里面了。

然后呢我再做一次这个对速度对位置的积分啊,对速度积分得到位置,然后再把角速度呢,通常来讲,比如说我是一个用cturning,用四元数来表示旋转的话,那我可以用这个公式来更新我的四元数的值。

那这样的话我们不断进行迭代,时间就完成了对一个人啊,对一个钢铁系统这样的一个仿真,但这里其实有一个非常重要的部分是什么呢,是这个呀,这里没有写啊,其实还有一个主动力f我在每个关节上加的力。

这个力其实是一个非常关键的因素,它是这个立本最终能推动这个角色产生运动,那这个力该怎么计算呢,那其实是我们后面几几节课会讲的内容,所以今天回顾一下我们今天主要讲什么,我们其实主要是讲的内容比较多嘛。

但是公式也很多,主要是讲的是一些仿真的一些基础,特别是钢铁,运动学和动力学的各种参数啊,各种属性以及它们相应的之间的关系,以及钢铁的运动学公式,也就是牛顿欧拉公式,但是钢铁其实有其他种不同的这个嗯。

表示方式啊,但我们这里就不讲了,比如说非常典型的这个牛顿公式,其实本质上牛顿欧拉方程,其实对应的是所谓的这个最大坐标啊,表示maxim coron,就是它其实相当于是说,我需要显示着去算每个缸体的位置。

速度等等等等,同时加上关节的约束,那就还有另外一套这个,建立这个运动学方程的方法,就是所谓用的拉格朗日力学啊,那个其实相当于我就不用关心这个关节约束了,因为它变成了一个参数的一部分,它自动满足这个约束。

当然拉格朗日力学有他拉格朗日力学的问题,那另外呢就是我们稍微讲了一下,关于这个碰撞模型,这个其实讲的比较简单,就是大家可能有这样一个概念,就碰到是怎么回事啊,应该就完成,就就是我们主要的要求。

那最后呢如果大家有兴趣呢,一个比较老的这个西瓜的这个course,这个课程很老了,但其实也有一些新的课程,就是可能会讲的更多一点,就是关于这个刚体运动学的,这个基本的一些方法啊。

大家有兴趣的话可以去看一看,好的,那我们今天其实进内容比较多呀,所以讲的比较时间比较久啊,看看大家有什么问题,嗯p p t我应该就不讲了,因为时间不够了,还有兴趣的话,我觉得可能其他专门讲仿真的课程。

会讲的更多一点,牛顿欧拉公式现在有什么进展,我觉得这个公式应该是比较怎么说呢,就好像学数学一样,我们学的基本都是八九十年代,几十年代这个几十年之前的这个工作,应该说从这个缸体仿真来说。

这个很多年来没有特别大的变化,因为钢铁这个问题,基本就是,基本来说钢铁仿真算是一个solve problem,但是很多问题来自于哪呢,其实contact怎么处理啊,这是一个挺复杂的问题啊。

其实后面有些工作是做这件事情的,就说我我比如说一堆小球,它们之间碰撞和连续不有有碰撞,我怎么实现稳定的这样的碰撞,比如对称的碰撞,就是必须满足的一些要求,那这是可能需要做的事情,然后还有一些就是说。

比如说可能是根据不同的表示,比如缸体跟软体啊,怎么混合仿真,那其实是另外一些问题的,就是可能单纯纯钢铁这边嗯,可能这个学术上的相对来说,可能就是就是就是大的问题,可能是不是太不是太多了,应该是。

啊刚体运动学怎么和骨骼动画联系,我们其实一开始就说了嘛,我们刚体运动学里边,我们前面这个公式里边的这个缺少的这部分,右边这一项我们需要再加一个力的那角色动画,其实本质上是去算这个力加在右边。

来推动整个钢力系统移动,那这个力该怎么算呢,其实是我们决动画需要研究的内容,呃影视积分是否需要改引擎,那这个至少现在我们看到的引擎,大部基本来说你是要改的啊,这或者你自己写一个。

就是基本来说现在常见的引擎是不支持饮食,主要也是积分,是否为什么呢,因为钢铁的饮食积分,你学下求解啊,求解一个方程,这个方程里边特别是影视这个c,这里边c和是一个非线性函数。

这个j其实本质上也是非线函数,就你要求解的话,其实这个非线性非常强的一个一个球根,这是很麻烦的,他可能跟那个软体仿真还不太一样,就是软体或者流体,相对来说它只是就是系统比较大,但是但是很多时候。

我的这个方程可能不是线性的,就只是规模大而已,或者方程本身的体验都很差,但是这个但是本身还是一个线性方程,但是钢铁麻烦的地方在于旋转,一碰到旋转就是就是非线性,一非线性就特别麻烦啊,这是一个很难的问题。

嗯刚体动力学的话,实际上其实我们讲的很多内容都是什么呢,本质上如果说你去学物理四大力学吗,有几个力学,理论力学其实主要是讲这个讲这个缸体呀,啊就是各种方程的,就这种是很相关的。

我们其实是讲了非常非常简化了一点,理论力学的知识,比如后面如果要写这个物理引擎的话,你肯定要了解更多的,比如说这种拉格朗日力学啊,甚至哈密顿力学的各种表达方式,那个其实会更容易一些。

服装动画仿真我们应该不会讲了,因为服装动画是软体,我们这边这节这门课不接触软体,ok行啊,我觉得时间也差不多了,今天其实时间比较久啊。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

那我们今天的这个课程就到这里对,然后那个我们的作业啊,当然也是欢迎大家继续来完成,我们其实中间还有一次作业,是关于关于这个这个skinning的,就是蒙皮的,我们也会尽快的把它发布出来。

好的那我们今天的课就上到这里。

GAMES106-现代图形绘制流水线原理与实践 - P1:1. 现代图形绘制流水线导论 - GAMES-Webinar - BV1Uo4y1J7ie

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

好的嗯,大家好,今天是我们games 106的第一节课,首先是跟大家介绍一下,这个课是叫做现代图形学的一个现代图形,绘制流水线的一个原理和实践,然后的话我本人叫惠池。

现在是浙江大学的一个cad的一个老师啊,还先介绍一下我们这个团队,就是说我们这次授课的话是有一个团队来授课,一共有五个主讲的老师呃,我本人是cad的霍雨池,然后也在光线云,还有一个浙江实验室做一些任职。

另外的话呢呃我们还邀请了袁娅镇,高新峰,胡一伟和高涛啊,另外四位老师来一起讲这个课程,由于这个课程啊就是题目所说的是说,我们希望是强调一些理论和实践并重,所以的话邀请了很多一线的。

正在做相关研究和相关开发的一些人员,直接参与了讲课,那其中像我的话呢,我主要是做图形绘制出身的,然后包括一些啊真实感绘制,实时绘制,还有神经绘制等等,还有口碑绘制,基本上都会涉及,然后由于一些个人兴趣。

还有一些其他的原因吧,我也做一些机器设计视觉,做一些计算光学相关的研究,相关的一些入门的话会在呃top啊,西格cpr啊,nc啊,各个方面,还有np啊,乱七八糟的,其实都会有一些发布。

这里就不去进一步的呃细讲了,然后袁娅证的话,他是在腾讯游戏任职啊,现在的话它主要是做一些实时绘制,还有绘制管线方面的一些研究,高西风是啊,老师是在那个北美,腾讯光子的一个资深研究员啊。

他是做几何部分的几何计算,网格处理相关的研究,然后胡立伟的话,胡斌老师现在是在耶鲁拉,耶鲁大学即将毕业,已经啊马上就要入职adobe,他主要是做一些纹理,还有一些可微绘制相关的一些呃工作。

然后还有我们的这个整个课业的一个主程序,高涛同学啊,高涛老师啊,现在是他是在向新科技,目前在做一个跨平台的一个绘制引擎的研发,所以的话啊,其实我们就每一个人都会是,在自己的相关的领域发过。

不仅是做一些呃开发,而且是发过很多配合吧,我们整个团队加起来我估计百来篇呃,然后各种顶配啊什么其实还是有的,所以这个地方就没必要去很详细的去往下讲了,然后除此之外呢,我们啊这个课。

首先要感谢一下我们一些助教的同学,这就是我们目前啊招聘,招聘到的一些助教的团队啊,来我就不一一细讲了,大家有兴趣的话可以去添加他们的呃,发邮件去跟他们联系啊,可以扫码入群,最后设计下方是我们的一个主页。

整个课程的一个主页,包括一些课程的介绍,还有一些那个相关的呃作业啊等等,其实都会在网上发布,这个是欢迎各位同学去添加。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

然后的话我们今天的第一个问题啊,就是开宗明义,就是说games 106这个课要讲什么,而后我们为什么要讲这个东西。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

其实总的来说嘛,这个我们还是做一个图形绘制的东西,图形绘制的话可能因为我想大家都很熟悉了,包括这个前面101集,一零几其实都是有很多的,很多课程就是讲图形绘制的,包括这个101对吧。

然后图形绘制的应用在我们现在其实很多啊,像这个工业设计,就是说设计一个车,设置一个房子,现在都是要用计算机先去把它绘出来,在用通过设计师,还有工程师做一些技术和美学上的一些呃交流,这个是必不可少的。

然后呃另外一个就是艺术创作,艺术创作的话,像现如今的话,这个电子艺术其实已经登堂入室了,就在很多电子博物馆啊,还有各种收啊,还有正式的线下的博物馆,其实都会有一些收藏。

那这个电子艺术家或者是这些cg艺术家,创作这些艺术的平台,就是或者技术支撑,就是计算机图形学,然后的话就是可视化,可视化的话呃,就用途就非常广泛了,就是我们t还有各种mt医学的。

还有天气的各类各类的数据,都需要通过一个图形学的方式去把它呃,可视化出来,帮助这个后续人员的研发和分析啊,另外的话影视影视的话包不管是真人电影吧,上面那些对影特效还是说动画电影。

动画电影的话就是一个完整整个动,整个电影,每一帧其实都是计算机图形学画出来的,绘制出来的,那还有游戏,游戏的话,这个也不用多讲,但主要是一些3a大作的话啊,他多了一个比电影还有其他类型用多得多。

他更多的还是多了一个可交互的一个过程,并且它主要是做一些实时绘制的东西,所以在这几个里面呃,其实跟我们这个嗯绘制流水线,可能更相关的是游戏,因为游戏的话它需要一个实时的performance。

对这个效率的要求会比较高啊,然后那下一个问题就是说这些广泛的应用场景,去支撑这些应用场景的一个呃引擎,就叫绘制引擎,其实绘制引擎那个范围会很广啊,它其实不仅仅包括呃游戏引擎,也还有其他的各种离线引擎啊。

还有各种啊,包括甚至我们在那个操作系统啊,还有各种手机上面,其实都需要有一套绘制引擎,可以做这些图形元素的一些可视化呈现呃,比如说像什么呃,离线的,像b瑞啊,这些都是用一些光线追踪。

然后unity and real这些的话就是会用一些呃,呃光栅化的及光栅化的一些绘制流水线,那其实呃会是引擎,还有或者是一个引擎吧,其实还不还不是跟那个流水线还不一样,因为引擎的话。

他要处理的其实是一个很综合的一个业务,包括像角色的ai动画,还有这个跟用户的一些业务和一些交互呃,甚至包括一些网络的传输啊,安全啊,怎么存储啊,怎么样去做一些编辑啊,这些都是那个引擎要考虑的一个问题。

而引擎里面最核心的就是说,把这个引擎跟其他的一些普通的啊,非图形的程序区分开来的,其实最核心的就是其中的一个图形部分,图形部分的支撑就是我们今天要讲的,就是说引擎呃,我们是怎么把这个东西真正画出来的。

一个引擎,有可能我们做一个应用的时候,直接调用这个引擎就画东西了,这个引擎要是具体是怎么去连接这个硬件的呢,就是说呃比如说硬件有cpu,gpu,还有现在的npu啊,还有可能还有一些显示端的。

像一些vr眼镜,ar眼镜,还有一些c r t l e d,各种各样的显示器,甚至mob,这个东西其实都会都不是,我们在游戏引擎会,或者是绘制引擎去直接操纵的中间,其实如果大家去调用过那个游戏引擎。

或者游戏里面的一些设置,它里面还有一个叫后端的东西,就是像一个open gl,或者是direct x或者是open这些东西,就是所谓的啊绘制引擎的后端,这个后端就是我们今天要讲的内容啊,绘制流水引线。

这个绘制流水线呢,它呃其实是一个你可以认为是一个抽象层,它有它不仅仅是包含了一个软件,它还是包含了一套硬件规范,也就是说呃不同的硬件厂商,包括显示器,还有一个gpu的厂商。

他会做一个工业的流水线的标准去build up啊,然后基于这个标准,还有这些过程式的东西,我们再去做一个统一的一个规范化啊,总结出了一个图形api来,所以这个规范化的一个绘制过程。

硬件绘制过程加上这个图形api加起来,才是我们的一个绘制流水线,那绘制流水线,它因为在网上他就直接承接了算法,在和一个具体的数据相对,几何三角面片文理这些数据往下呢,直接就连接了这个gpu和显示。

所以它可以你可以认为是这个绘制流水线,就是我们做各种图形绘制,还有各种啊,真正画图的这么一个抓手和一个控制的点,如果说我们从那个呃把这个图形业界,现在的一个生态去画一个图吧,大概就是这么一个生态链。

就是说最上层有大量海量的应用,包括像什么vr ar,虚拟现实游戏等等等等,然后再往下一面呢,一层就是有很多大量的绘制引擎,当然因为一个绘制引擎它可以支撑很多的应用。

所以的话呢这个绘制引擎的数量其实会比呃,会是一个相对比较少的呃,但是呢绘制引擎,它其实还没办法直接连接这个硬件了,所以它中间会通过一个后端a b啊,一个后端具有若干的流水线标准。

这些是都是对业界的一些统一的规范,这个流水线标准往下之后才会连接,又会连接五花八门的硬件啊,其实就是通过它的api,其实具体来说就是通过硬件的驱动来去连接,控制的一些硬件。

那所以说啊如果说我们呃描述一下这个图形学,业界的现在这个生态的话,其实它就是一个杠铃的形态,杠铃的上边就是各种引擎,各种面向应用层的东西,然后啊下端就是各种硬件,就是一些实现层的东西。

然后这个流水线就是这个杠铃,中间的一个啊杠杆,所以呢就很自然嘛,如果是说我们在做一些新算法,然后去做一些引擎,做一些特效啊,各种各样的去优化一些规则程序,做科研啊,做各种事情的时候。

那这些东西啊一般来说就会去考虑,首先考虑就会在这个绘制流水线上,出面去做开发,因为嗯这很自然吧,就是说我如果需要去一一的匹配不同的引擎,不同的应用,然后要去一匹匹配不同的硬件,那是一个非常麻烦的事情。

所以就会去汇聚成啊这么一个形态,那所以呃这很自然,就是说如果我们想不管是想做程序啊,在产业界的一些需求啊,或者是想做科研啊,想去进入这个学术界,如果要去掌握一个比较核心的一个,绘制的一个技术。

可能一个比较好的出发点,就是先去来学习这个绘制流水线,也是我们开这门课的一个目的啊,那我们后面会去接下来会去举一个例子吧,举一些例子,就是说为什么我们会把这个灰色流水线,它既不是206,也不是二零几啊。

三零几它是一个106,它是一个基础课程,就是说嗯我们认为把这个图形学,它其实是一个实践科学了,就不论是要去搞学术还是搞产业,那我们其实都是基于一些硬件,和一些当前可以用的一些啊算力去设计算法的。

就每一个东西,其实我们每一个算法,每个引擎的开发啊,都是在带着这个硬件的镣铐去做这个舞蹈,那如果是如果说像是我们完全脱离了硬件,去设计一些算法,那这些算法设计出来,其实是没有太多的实用价值。

它就变成一些纯理论研究了,那所以说的话呃我们做不管是做引擎吧,做算法首先就要考虑这个硬件,那考虑硬件,学习硬件,那就要去了解这个绘制流水线啊,然后要举一个很早很古早的例子。

就是说那个如果有的同学比较年纪大的同学,或者是说对这个历史比较感兴趣的同学,其实会知道这个是红白机fc呃,当年那个呃,任天堂的一个很有名的一个游戏平台,当时这个也可能就是说我们现在大家接触到的。

呃绘制引擎最早的一个形态,也因为当时那红白机的一些呃硬件的限制吧,它显示的时候都是通过一些胎儿,就是8x8的一些像素块,去把这个图像整个图像去拼接起来的,而且在这个整个场景里面。

我们他没办法去同时去刷新所有的tr,它只能一块一块的去刷新,那么有一些连续的动作游戏,它就会需要去不断的变换场景了,比如说像这个很经典的洛克人,他一直往前横版过关游戏,它一直在动啊。

所以说当时的技术人员和当时的那个啊,任天堂的引擎开发人员,就在这个根据这些技能的限制,去设计的这么一个卷轴式的一个场景刷新方法,那个像上面这个图,绿线的部分是我们实际能看到的。

然后但是在我们啊把这个画面展示给玩家之前,它实际上在前面一块一块的,去把这个场景给刷新出来了,这个就是一个非常典型的根据呃,是根据引擎或者是根据硬件去做绘制。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

引擎开发的一个例子,那另外一个比较重要的例子就是说啊,我们在做一些产业,做一些公司的时候呃,经常可以老板叫你去ok,要今天要开发一个新特效,要把这个粒子系统啊,要把这些某某某某效果啊给做出来。

那这些新的效果怎么做呢,比如说像一个例子,要做一个天气,要做一个广告牌,做一些曲面积分。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

你去做一些全局光照效果,这个怎么办,那你还是得去通过硬件,首先你去看一下这个硬件到底能够支撑,然后再去根据这硬件去做一些相应的开发呃,比较经典的一个例子,像近期的话就是这个rtx光线追踪这个事情。

光线追踪或者是这个全局光照,其实在学术界就研究了,研究了十几20年了,这个东西一点都不新鲜,但是为什么最近几年才去,真正在这个民用市场上去有一些落地呃,一个很关键就是说现在硬件支撑了。

就是那个vidia的这个rt扣rtx这个事情,支撑了这个我们真正在引擎端去部署这个事情,去实现这个特效啊,说明这个图你看一下,就是这个全局光照跟传统的绘制的传统光照,一些局部光照的区别。

就是说全局光照可以去通过一些多次的光射的,光线的折射去仿真更自然的一些光照变化,更符合我们人啊物理过程的一些光照变化,比如说像在左边这个就一些灰阶,一些过渡就会更自然,然后再如果我们把这个在右边这一块。

如果我们把这个光线追踪关了,那他就只能去呃,由于每缺少这种多次的全局的光照,它这个游戏设计师就只能去把这个场景给一些,比较灰白的呃,ambient polite去做的啊,这样的话失去了很多一些动态。

一些真实的效果,第三个关键呢就是说我们要回去,流水线可以做的事情呢,就是说我们可以去优化性能,因为呃就是我们所说嘛,就是说你要去优化一段绘制程序,或者一个绘制效果的一个性能,那比如跑到多少帧。

然后那你首先想到的应该是去去啊,调整这个会跟流程绘制流水线相关的一些代码,都和它一些控制代码,还有它的一些衰的着色器代码,因为呃这个这个我们到后面再细讲啊,然后这个同样去举一个例子。

就是说为什么说优化图形程序,需要去跟那个硬件相关,呃这个是一个非常有名的例子,就是在那个雷神之锤里面,那个我不知道你们知不知道那个卡马克反转啊,这个就是用一个快速的算这个呃。

倒数平方根的一个快速逼近算法,这个东西其实就是一个津津乐道的,就是一个话题,就是说你如果是不了解这个硬件,你去做这个事情,然后你真的让他那个gpu cpu去做一个平方根,然后再做一个倒数哦。

这是quick,sorry,好像这个截图是有问题,这个都回头我再查证一下,这个没关系嗯,anyway,然后的话呃平方增刚才讲到这个是,所以的话如果是真的去做这个东西的话,可能会有个大的问题。

就是说呃我们g p u,c p u里面其实是没有这么多运算资源,没有这么多的可以做一个倒数和开根的运算啊,op,那所以的话他呃这个核心算法,就是找了一个牛顿迭代法,去把这个作为一个泰勒展开去求解。

这个近似的求解这个事情,嗯具体的话在这个地方我就不展开了,因为网上其实蛮多这个讨论的,还有一些paper专门去研究,为什么一些magic number可以产生,有兴趣的同学可以继续找一找。

然后如果下面的课程里面有机会的话,我也会去再展开说一下,然后到了科研部分,就是说绘制流水线,其实是呃支撑了各类图形绘制的一些算法呃,我们做这个图形绘制,或者是这个图形绘制算法的开发的时候,其实是用。

其实是要在大部分是在这个流水线做开发的,不管是实时的还是这个离线的呃,因为你在一个引擎,引擎是一个非常抽象的一个封装了,大部分他已经面向的是一些引擎的使用,其实大部分是面向一些呃脚本语言。

还有一些艺术家,一些亲类别的一些面向应用层的一些开发人员,那我们真正要去做这个图形算法的开发,那自然需要去走到更下一层,也就是这个汇率引擎的支撑层,走这个绘制流水线,当然你更下一层也会有一些。

现在有一些比较牛逼的程序员,他会直接去搞这个driver,去搞中非编,但是这个东西有要求有点高,所以我们作为一个平民开发员的话,或者平民科员科研人员,我们就大部分还是,在这个绘制流水事件上去做开发。

另外一个呢,就是说这个废水流水线,本身也是一个很重要的研究对象,因为他绘制流水线在工业里面用途很广泛,包括各种引擎,各种硬件呃,算法都要去跟这个绘制流行啊流水线打交道。

那怎么去提升绘制流水线的一个效能嗯,就是一个本身就是一个很重要的科研问题了,比如说像去有些工作去优化它的那个io,有些工作去优化它的能耗呃,有些去优化它的那个并行度,还有一些呃去羽化成代码。

要在这个流水线做一些可悲的分析啊,去做一个全局的优化,这些在我们后续有机会的时候,我们再去更详细的介绍,呃另外一个再下一个重要的例子,就是说这个绘制流水线,去支撑一些科研数据集的一些生成。

呃比如说像一些交通仿真啊,或者是一些呃实际绘制的一些算法,那这些因为这些数据的生成,其实都是非常定制化的,一般的游戏引擎很难去产生,这种啊特意的定制化的数据,所以的话这个我们去做一些呃。

机器学习相关的开发的时候,也会用到一些绘制流水线的一些相关的知识,在下的话就是做一些我们不管是做流体啊,做物理啊,各种东西,你把这些科研结果最终呈现出来,可视化出来,也需要一个支撑工具。

这个也是我们绘制流水线可以做的一个事情啊,这个就先简单的讲,所以啊那我们总结一下,就是绘制流水线这个事情,它其实是一个支撑,不管是工业需求还有学术需求的一个杠杆,一个入门砖。

那我们这个课程主要就是讲这个事情啊,怎么用,然后他的一些背后的理论,还有是硬跟硬件相关的一些原理,是怎么发展过来的啊。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这就是我们回答第一个问题,然后来到第二个问题,就是说我们首先呃讲了他这个背景,然后我们想一想,为怎么样去认识这个绘制流水线,这绘制流水线到底是什么东西。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

嗯流水线我们先说一个流水线的概念吧,就是说到这三个字,你可能最容易想到就是工业流水线,这个工厂里面有很多工人啊,一个接一个的排着去做一些特定的操作,那么a a操作员他接受一堆物料做。

这就是物料做了一个操作,然后把这个结果啊留给b操作员,然后b操作员的接到a的输入,然后再做一些输出,基本上就是一个嗯顺序的一个操作,那当然这个真实的流水线,或者是包括这个图形绘制流水线。

中间有很多工序的啊,交交叉,还有一些互相的协作,这个我们不用管,但是从那个非常抽象或者高层的呃角度来理解,绘制流水线或者是流水线,它就是一个给一堆物料,然后产生一个结果。

这么一个工序化的step by day的一个过程啊,具体到我们这个图形领域,图形绘制领域,那我们给进了物料,就有在主要的物料就是三个,一个是几何,一个纹理,一个光照,因为啊外观我们给到一个物体的形状。

给到一个物体的外观嗯,再给到一个当前场景的一个光照环境,然后我们做一些计算,产生图片,这个是一个固定的绘制流水线,写成一个函数,或者写成一个方程的话,就是下面这个f就是这个。

你可以认为f就是这种绘制流水线,然后它的输入啊,几何纹理光照,然后在左边是它输出一个图片,然后到后期呢,呃我们就会涉及到一个可编程的绘制,流曲线就发展出来了,就是说嗯嗯我们现在这个工厂吧。

不仅希望说我们可以去生产一些固定的东西,我们希望可以把里面的一些操作员给替换掉,可以做一些各种各样的一些操作,去对这个流水线产生的结果做一些变化,定制化的一个变化,那所以在这个可编程的绘制流水线里面呢。

就多了一个新的输入,叫做着色器语言,这个着色器的话其实就是用一堆程序代码呃,他去控制这种或者个性化,这个绘制流水线的中间的一些过程,产生更丰富的一些效果,把整个图形的绘制流水线画出来。

大概就是长这么个样子啊,就是首尾相连,一块连一块的一个个不同的模块,然后这个每一个模块都会有相应的硬件支撑,然后我们要去调用这些模块的时候呢,就要去给定一些啊正确的输入,从左边的话。

比如说我们先去给另一个几何,就是这个流水线的入口,一般是先给一些几何的表达,这个场景的几何表达,900多呢,一般是用一些顶点,还有一些索引来表示,就是说每个三角面片,在这个世界位置的哪个位置啊。

然后他会然后再用一些index索引,这些顶点去形成一个三角面片带,嗯然后这些在装配好之后呢,这些顶点会被送进这个顶点啊,着色器里面最顶点着色如tax税的这个东西,顶点着色器会对这些啊三角面片做一些转换。

像play一些相机坐标啊,各种作用啊,把它做一个形状啊,或者是视图的一个转换,但中间这里有几个省略号吧,就是说呃中间是因为它可能还有一些呃,几何着色器,这个地方是一个可选项。

所以我在这个地方不去深入的细讲,那第三部分就是说呃,我们把这个呃顶点送到了这个光栅化,光栅画的话,我想之前的课程一些101啊,或者是其他的课程应该有去提到这个事情,就是把这些三角面片。

往这个屏幕空间做一个投影,把它像素化啊,然后的话呢呃下一部分的话,这个时候这个顶点就已经变成了一个嗯,呃像素了,就所有的计算都跑到像素来啊,好的我们这个ppt崩了,稍等一下,一个小小的插曲。

我也顺便喝口水的,ok所以我们经过了一个光圈化之后,这流水线的一个输出就会变成了一堆,堆在每个像素上的一堆啊资产了,这是win 10哦,anyway,然后的话到了fragment shade这个阶段。

就是这个这个时候我们会有一些新的呃,材料输入输入进来,一个叫做纹理,一个叫做光照,这两个材料是在这个fragment水的阶段啊,输进来的,然后所以这个光照计算就在这个地方。

几何和纹理和光照去做一个trading,去计算这个三角面片,或者每个像素,最终应该是呈现一个什么样的颜色,那最后的话就把这些不同的图层啊叠加起来,跟包括跟背景什么的叠加起来。

最后输到了一个frame buffer,这个这个friend buffer就真缓冲,就直接就可以跟我们的显示图片,显示设备做一对接,就产生了最后的一个图片了,嗯行这个就是一个呃总的一个pine。

那其中呢这个pipeline里面呢有些地方是固定的,有些地方是可编程的,像这个呃图蓝图绿的,这些地方就是一些固定的固定的管线,这个是厂商运行,或者是这整个工业标准就把这个地方固定住了。

认为不需要太多的一个定制化操作,所以它把它用一些非常高效的方法,把它给实现掉,然后中间的vertex shader和那个fragment shader呃,这两个部分的话是可以做各种各样的一个编程。

这个时候我们往上面去输送一些着色器,就可以做各种各样的操作,那所以说第四个元素啊,fragment shader,还有这个shader program也放进来了,那总体的看一下这个整个绘制流水线。

那对应的就是说我们刚才这个函数下面有呃,ok,下面它其实就是有一个f,一个管线本身有一个几何,有个纹理,有个光照,有个着色器,那我们就根据这几个不部分的不同,把这个对这个课程进行了一个划分。

那首先呢我们去有一个课程零吧,就是说我们一个准备部分,我们去主要是讲怎么样去做这个api,这个api相关的一些东西,然后这个主要是由高超啊来讲,然后的话第二部分就是那个呃,我们这里写错一啦。

就是我们要讲这个f这个管线管线对象,管线对象的话,就是说我们怎么去配置这个管线了,或者是管线的输出,呃就是重新,有可能你可以认为是对一些管线,做一个重新的组合啊,各种排列啊,各种调制优化。

这个地方是由原亚正来讲,然后第三呃,再接下来呢我们有那个高晓峰来讲这个几何,就说我们怎么样去对几何做一些处理和优化,来产生更好的一个效率,然后最后是文理,文理是由胡一伟来讲。

他这个胡一伟一直是在做这个纹理相关的工作,然后我会来讲一下这个着色器,语言相关的一些东西,着色器的话会跟光照一起讲吧,因为这个光照是本来是一个比较简啊,就是说他输入的形式会比较简单。

所以的话并且他跟那个着色器语言,有时候是耦合比较紧密的,他也要正视它的大部分情况下,它会直接作为一个参数,直接就给到那个着色器语音去了,所以这个地方我一起来讲嗯,那个其中呢去做一个感性的分解。

就是说我们会在这个图形语言的部分呢,我们主要是做一些加法,做一些就是怎么样去把这个东西,把一个场景build up起来啊,怎么去用这个东西,比如给你一些呃原始的物料,然后你怎么把这个东西给生产出来。

然后到了后面的管线对象,几何纹理着色器的部分,我们主要是做一些减法,就是说你给到一个管线,然后生产出一个东西,但这些东西其实啊有时候是在这个计算机,或者是在一个给定的硬件上,它是跑不起来的。

然后我们去怎么去对每一部分做一个,对应的优化,去做一个对应的嗯啊各种分析,然后得到他这个呃,每一个部分都可以得到一个很好的效率,所以呃最终的话这个东西就是,大概大概是这么一个东西。

我们希望这个前面这个构建部分,或者是我们向你们产生一个非常呃复杂的,或者不能说复杂,但是就是说一个非常fancy的一个场景啊,相对不是那么toy的,然后我们在这个优化部分呢。

我们在对这些先进的一些技术做一些拆解,然后让你们去可以去了解对每一部分,对这个复杂的绘制过程的每一部分,绘制管线的每一部分可以做哪些操作,哪些研究啊,哪些检索大体就是这个样子嗯。

ok所以这个又回到我们的一个答案,就是这个绘制流水线,第二个问题,这个东西是怎么样的一个结构啊,就有很多模块,step by step的一个输入,我们输入几个重要的输入,几何纹理光照,还有一个c的语言。

然后最终我们输出一个图片,这么一个呃标准化的一个流程。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

然后今天的课程呢,第三部分呢就呃讲一些比较轻松的话题,就是说这个因为我们今天主要是一个,introduction的部分,就是说这个我们讲一下,这配置流水线,是怎么去一步步演变成今天这样的。

它背后的一个驱动力,或者是说呃是也是跟其实也是跟硬件和软件,还有对产业界的需求紧密相连,然后才一点点地发展成今天这个样子。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

首先来讲一个呃背景,就是这个经典绘制流水线,就是绘制流水线是怎么产生,或者为什么产生呢,就是我们刚才提到了很多像那个嗯光栅化呃,我不知道大家有没有做过一些,软光栅化的一个东西。

就是用一个cpu程序去啊做这个三角面片的投影,还有g8 t的t,除去实际上产生一个个像素的颜色啊,这个东西其实不需要gpu,在cpu上也可以做呃,那cpu gpu最大区别是什么,就cpu顺序执行啊。

更像一个传统的就是我们想象中的流水线,如gpu并行执行,就是说我们这个流水线不是一条线,我们上面有很多很多的工人,可以同时有很多并行的流水线,然后可以同时一把就把整个呃几百万,几千万的那个三角面片啊。

三三角顶点去给处理掉了,画出来这个就是gpu和cpu最大的区别,然后那很自然就是说我们这个绘制进入了,最初是在一个专用市场,但是他想要进入民用市场,他必须提速,那这个或者是进入更多的应用领域。

它必须提速,这个时候就有了gpu去做一个并行的一个东西啊,图形的图源的一个绘制,那想到的一个方法就是说我们用cpu去,因为这些数据吧,这个gpu上其实不太容易去做编程的有很多啊,呃这特别是在最早期。

相对还没有一些标准化的gpu编程语言的时候,那你只能够通过cpu去你,你你最好的一个比较好的方法,就是把gpu的一个啊绘制的过程固定下来,做成一个标准化的东西,然后让cpu去控制gpu。

那cpu只要去把这些呃要处理的数据,还有面片啊,纹理啊什么的,打包好啊,gp一发,然后gpu就按顺序执行了,这个就是最早的一个固定绘制流水线,精湛的绘制流水线呃,这个大概是要追溯到这个上世纪啊。

就是1990年代了,那个时候,这个图形学其实还没有进入消费级市场,它主要是在一些高端的图形工作站上去,有应用啊,在产业界用的比较多,但是比较一个比较有名的公司就叫s g i啊,他是有地位。

有点类似于今天nba啊,他那个啊它主要是用sgi做一个图形工作,s3 主要是做一些啊图形工作站,去做一些影视级的一个绘制,比如说这个很早很古早的一个经典电影,侏罗纪公园,那就是sgi的工作站去做出来的。

sgi它不仅做硬件了,他还去做一些图形的api,为了让这个方便编程,他自己有一个专利性的一个图形app,叫做啊i i i s g2 ,后来呢这个spi他就觉得啊这个api我们自己用。

可能对这个产业界的影响太小,他就会觉得啊,如果这个api我们统一个工业界的api,可以在跨硬件,跨平台去使用,那对推动整个业界的发展,甚至是推动这个东西的民用化,应该是一个很大的帮助。

所以他基于这个自己的一个呃graphic language,就做成了一个开放的标准,推动了一个开放标准的诞生,这个就是最早的open主要一点版本,但是1992年,然后这个呃open gl的话。

它并不是由一个stratt的公司自己推动的,他其实去成立了一个叫open drill呃,r a r b啊,architecture review ball的一个成员啊一个。

然后这个里面的初始成员包括很多大公司,就是像嗯康柏,ibm,intel,微软dc,还有包括之后惠普啊,media t i啊,都加入这个啊,open tra 2 b,这个op制药呢其实就是第一个跨跨平台。

跨语言的一个啊,其实不能说跨语言了,就反正是一个跨平台的这么一个,跨硬件的这么一个编程接口,它去来归,把整个呃图形绘制这个过程给规范化了,它不仅仅是用于三维图形的绘制,它还可以做一些呃二维图形的绘制。

那所以说有时候我们在一些操作系统和一些呃,ui里面做的一些各种各样的2d的一些工作,其实也是可以通过o o g l来做的,所以呃它其实那在很大程度上,推动了这个图形化界面的。

还有一些图形化应用的一个发展吧,它支撑的平台包括什么windoi,unix linux,mac os啊,还有手机啊,这些手机的话主要是open gl e x,这个我们会有稍后再讲。

他们啊去做一个跨平台的支持,那所以我们用户只需要去,或者说我们程序员就只需要开发一套啊,针对open gl的一个算法,就可以在所有的硬件上去run,这就是一个非常美好的事情了。

右边的话其实这个图是它的一个简单的框架吧,像这个没啥3d,他因为open主要定义的是一个标准,然后这个其实它会有很多具体的实现,那个mate 3 d就是一个开源的。

一个非常有名的一个开源的open gl实现,那他会再去对接下面的系统层的一些color,和一些driver去产生各种各样具体的呃操作,然后这些china啊,这些driver再去驱动一个各种显示设备。

还有各种计算设备的,还有一个呃ram的一个使用,然后又到了这个呃93年底吧,就是这个呃有一些比较重要的,像什么动漫,一些很牛逼的游戏就开发出来了,然后这个3d游戏就变得一时之间变得很火爆。

那sgi的一些工程师的时候就去离开了这个,去重新创办了一个创业公司叫3d fx,然后他这个东西推出了一个巫毒卡,就是一个叫3d加速卡,专门叫做巫毒,这个如果是我们当年做一呃,还有一些电脑报啊。

或者是那个什么电脑之家那些老用户,其实乌托卡应该是比较呃熟悉的一个名词了,但是这个3d x呢这个退出的过度卡它很牛逼,技术上很牛逼,但是它又很封闭,他不想用open gl。

所以他去推出了一个叫做德莱的一个图形api啊,这个glide图片啊api它只能用在自己的显卡上,但是所以说他虽然硬件很牛逼吧,但是就引起了一些图形学界的一些呃,重量级大脑,比如说像一些呃约翰卡马克。

他就会觉得ok我们还是图形学,他希望这个图形学和谈硬件,还是有一个呃规范化公开化的一个标准,可以让大家可以更好地去促进整个东西的发展,所以呃ok所以这个在他就搞了这个gal quick吧。

因为当时quick是一个非常火的一个东西,它这个机制jo jo quick呃,它只支持那个open gl,那乌度卡不支持这个,所以这个最后乌度卡也很尴尬,就只能灰溜溜的就在自己的呃。

那个api上面又加了一层来去兼容这open gl,但是这个刀的时候呢其实就已经比较晚了,因为他这个支持兼容的东西也很,也不是一时半会儿的事儿,最后等他们真正支持的时候,这个已经啊啥都凉了呃。

3d f o x最后就呃失去了大部分市场,到200年,2000年的时候左右就已经被那个media收购了,media继承了很多,这个3d f的那个乌图卡的一些技术了,包括他现在用的是xl i这些显卡。

多联啊,吉林的技术其实都是,当时那个乌读卡就已经推出了,同年嘛就是95年,这个当时不太被看好的一个东西,就是dk x是由微软推出的,dx的话,他呃有这个cg加去实现,然后还遵循去扣不要犯。

所以说的话呃它主要最大的一个问题呢,就是说它只能够用于microsoft的windows xbox 360啊,还有一些呃什么嗯,polla就等等,这些他自己自身生态的一些硬件和软件系统。

而且呃当时的话这个东西,它的影响力还没有今天这么大,所以的话呃,当时业界的话也不是特别的去重视这个东西,但是我们还是说看现在再看回来他这个第二,但在他的一点的时代呢,就已经支持了3d呃。

direct 3 d,然后并且包了很多先进的特性,呃并且有一个很重要的点,就是说微软,它其实啊执行效率是非常高的一个机构,而且他研究水平也很强,包括今天的微软亚研呢啊,到今天还是这个全球这个。

图形学的一个领先的研究机构,嗯呃那他经过了几年的开发之后,到了大概到了97年,他发布到了这个directx五点的时候,它就已经包含了很多后发先制,就已经包含很多那个分区,要包含那些特效了。

然后这个时候那个业界才开始反应过来,就是说这个德3d可能会变成一个真正领先的,一个图形api或者图形标准,包括一些卡马克啊,这些东西都会,大佬就其实不想看到这种三私有的3d api了。

所以就会呃在一些公开信上面去啊,去质疑这个事情啊等等,不过这个最终都没有什么办法,因为微软的当时那个操作系统,32这个东西是当时正到了,已经到了他的一个巅峰时期吧。

基本上基啊我们小时候玩的一个各种电脑游戏,都是在这个windows上面去玩的啊,渐渐的这个德尔塔x就变成了这个业界的一些,领先技术,领先平台的一个代言词了,到了2000年左右呃,这个德瑞克3d八点。

率先去推出了这个可编程绘制流水线,去支撑了这个可编程的啊,呃这个可定制化的这个绘制,那个当时最初早的版本的话,他们是只能够用一些汇编去做这个shader,但是仅仅2年之后,把2022年,2002年。

他们就推出了一个高级的一个飞的编程语言,h l g啊,h l s l,我看这个地方是不是写错了嗯,anyway,回头我们会再校准一下呃,然后的话这个东西,所以这个编可编程的绘制语言写出呃,弄出来之后。

就其实对光照或者整个画面效果,就会有一个颠覆性的变化,下面的地方看到这个是左边是标准绘制fix的,你可以,当然这个不是啦,这个因为是一个mc的东西,我们只是拿这个东西啊来做个例子。

就是说如果是一个标准的绘制流水线,那我们只能做一些简单的光照,然后啊,我们没办法体现出这个程序员的牛逼在哪里,然后后面的话会去引入了这个可编程,绘制流水线之后,就啊就可以去真正的去做一些带全局光照。

或者是基于物理的,还有一些基于各种fancy特效的一些绘制了,就包括一些高光阴影,各种东西就非常容易做了,嗯这个年代比较经典的游戏的话,就是像那个魔兽啦,所以大家如果稍微回忆一下。

大概可以看到这个绘制流水线,可编程绘制流水线,对这个整个画面的提升有多大,就是从前面的一些古早的,像一些像素一样的东西,就直接一口气奔啊,走到了这个,已经有我们今天现代游戏的一些雏形了。

open g2 呢,就是在这个阶段的open gl其实是就全面落后了,他这个一直到2004年了,就才推出了自己的一个编程语言,整整比达的3d去晚了2年。

所以就是因为你media包括a media t i这些啊,公司都想去把自己的一些技术,还有一些先进的东西,技术强项,还有一些东西加到这个标准里面,那自然就会有很多哎有很多宫斗了。

那这个扯皮过程啊还要怎么样去集成啊,就会变得非常低效,那比起来,微软这个当然就会有一些距离上的差距,所以到了这个2006年的时候,这个open gl a r b这个open gl的这个官方组织。

就把整个的控制权交给了一个新的一个呃,呃呃呃norr cho chronos的这个组织,chronos,这个组织其实也是一个由很多大公司组成的,一个呃标规范化的一个组织,它也是非盈利的。

嗯然后这个组织rose啊,做做一个比较牛逼的一个事情呢,就是说他后来去发布了一个呃一个叫做open追,要yes的东西,中国分jl yes,就是完全面向那个嵌入端,就是手机端的一个图形开发。

然后这个东西就啊终于为这个open出道吧,回家颜面吧,因为微软在这个移动端,并没有很强的一个控制力,所以这open gl es就沿用了十几20年,一直是作为这个手机端开发的一个很重要的。

跨平台的api标准啊,然后到了这个第三个阶段,大概是到了嗯06年啊,其实这个这个阶段,其实你看到这个呃技术的更新迭代非常快,我们这个来到了open gl三点的时代,这个或者是呃d差十。

这里面比较重要的一个呃标准诶,一个比较有名的一个东西,就是这个引入了几何着色器,这个时候就不仅仅是对于光照做边界了,我们还可以做一些几何,做一些定制化的编辑了,因为就是在这个绘制的时候。

这个管线绘制流水线,它首先是接触一些3d坐标嘛,在这个顶点着色器里面做几何变换,然后这些顶点数据在装配完之后,变成一个几何形状,就称为图源,像三角形啊啊点啊线啊,这些东西其实是有那个程序员来指定的。

那个几何着色器呢,现在就可以接受这些图片作为一个输入,然后去做一个新的输出,那当然就诞生了很多新的玩法了啊,他就可以去通过新的零啊,构建新的或者其他的图片或者其他的形状,然后这一个比较典型的应用。

就是说这个实现了这个物体的l d就是level of details,呃,就是说我们那个物体,其实如果每个物体都用一个很筋膜啊,那其实在这个图形绘制里面是没办法。

这个gpu是没办法支撑这样大规模的绘制的啊,面片太多,然后绘制太复杂,那所以的话通过这个l d的话,这个场景里面就可以通过近大远小远的,我就用一些粗模,比如说相机比较远的东西,我用一个粗模来表示。

近的用一些筋膜来表示嗯,所以到了这个阶段,像这个孤岛危机二一个比较经典的系列,当时是技术上非常惊艳的一个东西呃,就可以支持很多同频的大场景了,这个时候我看那个模型精度其实也做了,有了大量的提升嗯。

到了另一个重要的阶段是到了曲面细分啊,到了open gl就是到了10年代,这个因为计算机其实本身是不能直接产生曲线,也不能产生曲面的,所以说我们的计算机上看到的一些曲线,曲面实际上是由很多多边形构成啊。

那多边形越多,这个展现的曲面就越真实越光滑,所以这个时候呃,这些业界就引入了一个,在现有的模型顶点之间去嵌入新顶点,自动插入新顶点的一个技术,这些模型可以被分得非常细腻,看上去很平滑,很紧致。

之前这些东西可以用啊,在这个teslation这个东西出来之前啊,这些东西一般是由cpu做,但是cpu性能有限,所以之前的游戏还是有点非常粗糙的,一些非常棱角分明的东西。

这个tablation引入了之后嘛,就gpu来参与这个工作,把这个在图形芯片内部去创造,自动创造顶点是模型细化嗯,最后就可以获得一些非常好的画面效果,一些比较重要的,像一些做毛发,还有一些做这个呃材呃。

自然景物的一些呃,细节优化就支撑了,我们,已经非常接近现在这些3a大作的一些结果了,像有名的巫师三这些野外的场景,其实嗯还有他的一些飘逸的,这头飘逸的长发,都是通过一些群众细分。

还有相关的一些技术去做出来的,呃所以说在这个open gl四点,其实就是我们现今的open gl最高的就四点多了,就是这个大版本是四点啊,就是我们现在呃最主流的,或者现阶段我们主要发展的一个嗯。

所达到的一个位置,在这二三十年的发展时间里面呢,其实这个open gl整个家族他不仅说en gl,它还有一个非常庞大的体系了,首先是有一个叫open cl的东西。

open cl其实当初是有点对标cod呃做的一个东西,他想做的是一个跨平台的,通用的并行编程的一个开放标准,嗯这个东西也啊,他不仅仅其实他当时的野心非常大,它不仅仅是想去做这个gpu上的一个并行开发。

做一个通用开发,他还想去跨做一些呃cpu的并行,然后cell类型的并行还选择这些disappear并行啊,像在所有的跨平台上面去做多做这个事情,而且它在实际上也产生了一定的影响吧,在这个游戏啊,娱乐啊。

科研医疗就是很多地方都有一个应用,不过这个东西最初是苹果公司开发,但是后来苹果公司也不维护了,这个东西就转移到了啊,coronos的这个组织里面去,而且最终又并到了open里面去了。

呃另外一个比较重要的东西就是open gl es,就是我们当初提过的一个东西啊,这个主要是面对了一个,它是一个喷制药的一个子集啊,针对一个手机pda,还有游戏啊,这些主机的做一些开发,它的性能。

一般说认为它的功能性上,它是一个open trial的一个集嗯,但是呢它是因为是免费的跨平台的,而且呃这个东西怎么说呢,呃我们做手机的适配,可能要比这个电脑的适配还要复杂。

因为手机的有各种各样的呃配置环境,有更甚至一些私有的gpu啊等等等等,所以的话这个open gl es,1度是最有具有非常大的影响力,所以就超过了open gl啊。

然后的话另一个比较重要的事情就是web,主要web制药的话,其实它是一个把这个html和和这个open gl,给结合起来了,它是一个通过一个javascript的一个东西,把这两个东西呃。

中n g l e s跟那个呃js不是绑定,然后他直接可以用tm的cameras去提供,在上面去做一些3d加速的一个渲染,这样这个bb开发人员,就可以直接在浏览器里面去画这种3d。

复杂的3d场景和3d模型,它甚至可以做一些啊,非常复杂的导航和数据的视觉化了,那并且这个开发的时候就免去了,做出各种渲染插件的安装,那我们基本上就是啊只要像现在一些先进的啊。

five fox saf chrome等等这些,只要是主流的浏览器,你都可以直接去调用底层的gpu,去做各种分析的东西,那就不用去下各种奇怪的东西,各种奇怪的图形插件。

这个所以他对这个3d互联网的开发或者产生,其实是产生了很大的助力,嗯基本上这个open gl家族就是这么一个现状,但是这个open gl家族呢呃随着现代游戏啊,现在的同屏物体越来越多。

然后这个越来越复杂,open之药渐渐的也开始力不从心,那现在所以基本上就进入了,这个所谓的现代绘制流水线了,就是说我们现在正在开发的正在用的东西,就是以vocal为主,这个中间经历的事情还蛮多的。

就是说这个是在13年就amd首先是开发了mental,mental是做这个3d游戏,它是面向3d游戏开发,去做了一个新的新一代的途径,飞车api,所以让这个开发人员直接去操作这个gpu,硬件底层。

他把这个java层弄得很小啊,然后这个把application层弄的很大是吧,所以让你们直接去控制这个事情啊,来提升效率,然后的话呃mental的话,他的发布,然后就带动了那个微软。

还有一些那个苹果它的一些跟风啊,也不叫跟风啊,就跟跟住,所以说是amd那个微软的话,在这个2014就推出了dx 12,然后这个苹果是推出了meta,然后这个a amd嘛,然后他原本的这个manta。

因为他这个amd,他当时已经对这个图形界的一个影响力,已经下降了,他没有办法去进一步推动,所以他退出,然后把这个呃维护的一些东西全部交给chronos,chromos的话,在这个基础上就推出了van。

在1年呃,他才首先就是这个功劳,他本身就是open gl的这个管理者,我去直接推出一个新的open,这个其实也是有一些可以理解的原因,就是open gl嘛,它已经其实一个存在了20年的一个东西了。

他对这个软件开发者友好,他因为当初的话,我们呃以前的gpu是不支持,直接去对这个硬件做了一个开发的,所以他对于软件友好,对软件开发友好,然后做那个硬件封装,做了一个很厚很复杂的硬件封装。

那就造成他这个东西driver层越来越庞大,而且他要去做各种兼容,这样的话这个不需要显示驱动,要维护一些啊状态啊,要对这个api调用进行检查呀,运行检查,然后等等等一系列的这些overhead。

造成他的负担越来越大,嗯所以最后中的话他只能快刀转乱码转了啊,转乱麻,把这些东西把一些历史的包袱全部丢掉,开发了这个open,这里呃简单的去做一些啊这两个东西的对比吧,但是主要是主要说明g和wen。

就是目前这个op gl都已经不开发了,而且open cup open啊主要一起合并成了这个嗯,这个我看基本上就是我们现在说的,就是下一代或者下一代的这个呃图形接口,主要是用来跟那个dx 12做一个竞争。

它的一个最重要的一些东西啊,就是说它可以直接控制这个gpu的底层驱动,然后程序员啊需要直接去控制底层的一些状态,队列,线程管理,然后内存,然后渲染队列等等,并且它一个比较重要的是。

它可以支持一个多线程序调度,所以的话它既有好的地方,就是说我们提供更大的优化空间,但相对的其实对这个开发人员要求会更高,你必须去了解这个底层的硬件的一些架构,你才能够去比较好的去做这个vocal的开发。

所以这里有一个小小的video去去看一下,这个性能的比较,没关系吧,我们跳过吧,好像最大二级,ok最后的话就是啊这个是目前的一个状况了,就是低差d32 ,然后mama还有一个vocal 3大块。

然后我们这个wen是兼容性最好的,也就是我们games 106,想要去重点去介绍的一个东西,嗯再往下的话我们看一下,就说我们当前是做了一些meta,是现在时现在进行时,我们在看一些将来时。

就是说呃将来或者是正在前沿发展的一些东西,可能会对我们整个汇聚流水线,会产生一些什么样的变化,首先就是一个最近比较火热的,一个是混合绘制流水线,这个是随着这个rt cor啊media去做的推出的。

这个article去流行起来的一个东西,就我们会一个东西,可以去包含了光栅化和那个光线追踪,两种技术的一个结合呃,这样的话做一些镜面反射,还有一些折射,这些东西原来做包装盒很难处理的,现在就可以支撑了。

而且加入了一些rt扣天色扣之后呢,我们可以做一些全局光照的计算啊,去产生非常fancy的绘制结果,这个是一个呃大的一个很重要的一个趋势,然后另外一个我们觉得可能会呃需要讲的就是。

这个ai对这个绘制流水线,还有整个绘制流程的一些推动,其中就包括一些常见的应用,像插针啊,还有像d l s的,还有些采样蒙特卡洛,采样蒙特卡罗降噪,还有一些做超分,把一个低分贝的物体变成高更高分嘛。

这些都是一些很重要的应用嗯,第三个比较可能会对这个整个绘制流水线的发,展会产生比较大影响的呢,就是这个影视神经厂的一个诞生,就是我们所做的乐死,我发现我这个地方所有的b调都放不了啊,没关系。

就是简单的讲的话,就是说呃我们做这个3d嗯,是做这个点到了一个数字模型,然后就把它呈现出来,但是呢在一个有个前端的地方,就是说计算机视觉是把一个看到的东西,转换成一个数字模型。

那就是这个感知或者是重建的部分,然后这个懦夫或者是这个一时间场表达的话,用过一个通过一个可悲的全可分,全可悲的一个场神经厂,把这两个事情连起来了,所以他再去做这些具有真实感的。

或者是呃真实场景的重现或者汇聚上面,它会有非常好的优势,它像这些场景都是用一些照片直接去生成,创建出来,然后就直接进行绘制呃,所以我觉得这个东西对将来的也会整个绘制,流水线的变化也会有很大的发展吧。

包括最近有一些已经把这些弄斧啊,或者影视场的东西放到一些实时的引擎啊,或者是离线的引擎里面去了,然后另外一个比较呃重要的一个发展,可能性的话就是一些神经绘制的权力光照嗯,这个传统的话。

现有的绘制管线还是要借助一些像光穿啊,谁等啊,还有一些阿提库啊,这些定制化的一些图形加速硬件去做这些啊,光照的计算,去做一些绘制的实现,那现在有一些工作就想去直接把这些东西拿掉。

就是说我们只用一些通用的m p u啊,做一个纯神经的计算,去达到一个全局光照的一个动态,绘制的一个效果,嗯这个我们最近也有一些工作去做相关的事情,大家有兴趣的话可以去到时候了解一下。

目前还在那个ready to publication,然后的话还有一些就是a i p c这个词很火呃,就是说我们现在这些trash gp t,还有stable fusion这些大模型出来之后。

可以去重生成非常方便的方法,去让用户定制和生成各种各样的呃,3d数字资产,像右边这个话其实是一个呃一个是可动的,体重上的,应该是可动的一个3d模型,直接去用text生成的3d模型,他对于这个我们以后。

我觉得对于我们后的一些呃场景的生成,还有整个绘制管线的一个过程,可能也会产生一个非常大的影响,嗯所以呃总结一下,就是最后呃这个绘制流水线的演变史吧,从90年代的固定绘制流水线,到2000年可编程。

然后几何着色器,然后到这个现代的一些呃多线程的绘制流水线,然后到将来可能我们还会迎来一波新高峰,包括一些ai和一些神经技术的引入,至于是怎么样去发展这个事情,我们可能只能拭目以待了。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

ok啊所以基本上我们今天的课程,第一个课程入门课程就到这个地方,最后是来了一个小小的作业啊。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

首先是我们介绍一下我们这个game,1106,可能会给大家留下一个什么样的一个课程,架构吧,嗯我们呃希望做的是这个一个,系统性的一个东西,就是说我们首先去给定一些简单的资源。

一些包括这个a language设定language,然后一些呃模型,一些纹理,一些光照,我们希望大家去学习这个api,把这个场景b出来,然后我们去分析这些场景里面的io啊啊指令啊。

各种部分所造成的一些消耗,去了解它到底是呃,他跟那个在硬件实现画出来的时候,它会产生一些什么样的影响,会产生什么样的事情,然后我们希望去从这个管线对象,结合纹理着色器这四个部分去尝试。

对这个呃我们b出来的这个场景做一个优化,那最后去得到一个high performance的,比较好的一个结果,呃,那这个所以呢我们先来一个homework 0,就是一个hello world的东西。

就是说要先让大家画一个三角形,配一个环境,然后这个梗图是我们一个助教同学,强烈要求我们放上来,所以我就放了,所以是一个老梗,然后有点不同,我们希望大家在win上面去做配置,在win上面去画呃。

那个作业的链接放到了呃,右上方那个左上方,sorry呃如果大家嗯感兴趣的话,欢迎大家把这个作业提交上来,我们后续的话也会有一些打分,还有一些呃后续的一个看看,我看看能不能找几个赞助商。

给大家讲的一些东西,ok ok好行啊,这就是我们第一课提交作业的链接啊,这个网站上面会有一个你直接进进这个网站,它上面会有一些说法,ok,呃它上面会有一些具体的要求,然后你不懂的话。

也可以去问我们的助教同学,有个有还有扫码进群,我应该把我那个全链接放到最后来,我们重新来一下,把群链接放出来,大家有什么问题都可以到群里去搞,啊,ok那我不知道我们这有没有答疑的环节啊,应该是没有的。

如果没有的话,没有的话,那就结束了啊,我们可以在群里做一些课后交流,如果好吧行,谢谢大家,然后下周我说一下,就是下周同样还是从这个周三,我们现在是每周三的下午两点开始讲这个课。

因为我们有一些在北美的同事啊,所以要照顾一下他们的时间表啊,所以会在你选择一个对我们两边都会比,较友好的时间,周三下午两点,接下来的话会有那个重点,先讲一下一些api啊,满人了,那个群,sorry。

那个群后来嗯我确认一下啊,如果应该是扩了,扩群了没有,如果是我们还可以继续扩的话,我就会把这个群扩一下,如果没有办法扩的话,我们会再开一个二群,现在是2000人群还是1000人群呢,我先问一下。

这个一拳是已经扣过了吗,嗯有没有大家知道的,就是一群现在是2000人群,ok那一群的话,我们还可以再过一次形态,这个是教那个图形学绘制的图形,绘制的一个东西,ok啊,看看有什么新问题,二泉的话。

如果我们一群能容纳进来的话,那就大家都在一拳解决吗,阿权阿权,他因为我估计是因为都是一个呃助教开的,他没有那个他没有那个vip账户吧,所以说他一拳开的时候能给1000人,二全开了就只剩800啊。

只剩500人了,所以我们可能得换一个人来开第一节课,1000行代码量嗯,这个我跟我们的高超同学反映一下啊,让他加大一下代码量,对我们全部都会用open,ok那高潮听到了,我希望高潮看了一下。

这个是1000行三角形,准备起来我们做一个呃课外作业,就是一个加分项,嗯看来还有其他,呃多线程线程也会讲,有不肯,现在其实开始啊越来越多了,不肯从我们这里学就挺好的,然后那个高涛他那个我们的那个主城说。

希望大家去学一下这个ban编程指南这个书呃,我倒没有列出来,因为这个等佳佳先看完他的课再去看吧,就是说我希望是说我们在这个地方,因为三有可能课程的上没办法去讲的非常细,因为我可能要讲很细的话。

可能本身就要十几20节课了,那是没办法去讲的,所以我们希望给大家把这个锅可能做什么,它有些哪些特性,把这个事情首先给大家理清楚,然后有一些vocal编程指南的东西啊,其实可以作为一个工具书。

大家需要的时候去查就可以了,包括我们其实我们也不可能去把握,每一个非常细节都记得很清楚,那关键是说你要对它,整个模型有一个非常感性的认识,要去自己做一个重新的理解,那最终你要用到的时候。

再去查那些具体的api就好了,这个会讲到时候会说啊,讲一下的,大家会去提一下,但是最终的话不同的版本的区域啊区别,这个都是都要讲的,open g l e s我们准备就略过了。

因为一个是网上有很多成熟的教程,而且的话因为他这个我们觉得呃,就是说我们还是讲一些新的东西吧,而且其实开始讲波肯不肯也不算是特别新的了,我们在后面会会讲一些混合绘制啊,一些那个呃各种光栅光。

追一些甚至一些神经绘制的东西,这个可能在后面我们会陆续的加入一些业界,比较前沿的一些研究型的东西嗯,open gl其实是可以作为一个上手的东西,呃,我但是他那个working gil的话。

你会对这个历史或者看一些遗留算法,会比较有帮助,就是理性他一些过程,但我觉得对未来的话,肯定是van的占比会越来越大的,因为open gl本身那个呃业界,它已经停止对他的一个更新了。

啊会会讲光追哦对其实那个我们之前讨论过,可能会有一两节课去扩展的,jo g l e s就是那个手机端的开发嗯,行的我看看还有什么要讲的,嗯呃我们这个其实跟motion tutory。

我想象应该是不太一样的,因为我们这个votion的api讲解,其实只占了1/5的章节吧,大概我们后面要讲一些呃,像一些d,像一些几何压缩,几何优化,还有一些纹理压缩。

还有包括一些shader language优化,自动优化,还有一些那个什么啊,matt resolution啊等等一些,这些其实是在业界真正会用的一些技术,还有说我们在学术界会真正去做开发的。

关注的一些问题,而不仅仅是api,所以这个api应该只是一个入门啊,是让大家可以去做这个事情,这个就要你要你得去问那个van的那个,chronos组织的组织了,但是我觉得会有,因为这个web主要。

他本来web主要也是那个coronos组组织,去开发的嘛,那他既然说他已经全面倒向了loken,那他将来应该会去做一个相应的事情,目标平台主要是pc的,嗯因为大家我想象大家的主要的平台,应该都是pc。

所以的话我我们还是基于pc来做讲解,然后并且pc的话比较方便去讲一些呃,比较方便大家做作业,l d的话有包括其实l d很多了,就包括一些啊纹理l d几何l d,还有甚至是一些c的l o d这些都会去讲。

就是我们把这个本身是把这个呃,流水线做了一个呃,从信号处理的角度去做一个划分,它会有几个输入,一个是呃几何纹理啊shader,然后这些输入我们去每一个部分都去讲,嗯有不同的老师教数学要学到什么程度啊。

我觉得你们这个线性代数会一些就好了,ai会ai主要是ai其实会讲讲很多穿插的讲,因为现在不管是做那个几何也好,做那个呃纹理也好,还是做那个shader也好,呃前沿的技术都会大量的用到ai。

然后所以在这几个主课程里面,我们都会讲ai在精神分,然后ai节这几个主课程完了之后,我们最后会有专门的一个section,一个很大的一个章节去讲一些前沿技术。

对操作系统现在主要是你用windows肯定是可以的,云渲染的话,我们主要就是介绍一下好了,因为云渲染现在其实没有非形成非常系统的呃,学术界上没有一个非常系统的一个东西,作业咋交啊,对就是作业的话。

我们还是你可以到这个主页上去,上面会有包括这个作业地址,还有相关的一些说明,如果现在没更新的话,我们今天下去之后会去把它更新出来,看一下还有其他的问题吗,o麦克呃,我去跟那个mac,你可以用那个虚拟机。

但是我想应该是可以的,因为vocal本身支持,我们如果要支持两个平台的话,会支持mac和那个windows mac,我之前的话他们沟通的时候是正在支持,然后目前已经支持了没有,我要去呃,确认一下对的。

linux的话可能不会去特别的支持了,但是理论上这个代码都是通用的,就是说你需要自己配环境,你配好环境之后,这个代码后啊,后面的代码其实可能相差不大,好的,那我们可能呃再等一会,如果没有新的问题的话。

ai渲染是个加分项目,ai渲染会用的越来越多,因为这个t p u现在每年他的那个性能还在提,升,他提升速度其实会比gpu还快,ai现在最主流的最标准化的是在那个d i s,就是我们呃用户可以接触到的。

然后另外的话据我了解很多大厂都在背后推ai,但是这个是不会直接在这个客户机上就run ai,它主要是在做一些资源的生成,还有一些前期的优化上面去,下面看这个有的不用你们写他那个配好了。

有mesh shader会有的,mesh shader其实也不是新内容了,注册课程的验证码,这个是什么东西啊,我们我不太这个我不太清楚,可以在那个之后,在这个教练群里问一下调试工具。

这个时候到时候我们会去呃,介绍对调试工具很重要的,ok好像没有特别新的问题了,那我们今天到这里吧,今天哎祝大家今天也是休假嘛,谢谢大家来观看啊。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值