美文网首页
捏脸系统中的差异矩阵推导

捏脸系统中的差异矩阵推导

作者: duanoldfive | 来源:发表于2022-06-15 18:49 被阅读0次

在上篇文章<<Unity 人物捏脸的实现>>中,最后留了一个悬念,就是

差异矩阵
这个矩阵是怎么计算来的。这里给大家补上。

几何意义

Mesh绑定(图1)

还是以上图为例,蓝色小球Vertex是Mesh上的一个顶点,它绑定骨骼BN_20(在BN_20本地坐标空间下,坐标值保持不变)。捏脸的时候不可能逐顶点调整位置,那就要调整骨骼,因为存在绑定关系,所以调整骨骼的时候,顶点小球的世界坐标也会跟着变化,以保证在骨骼本地坐标下位置不变。有点绕口。好好理一下就明白了。
假设调整骨骼到一个新的位置,比如我们把骨骼BN_10绕Z轴旋转90度(会带动BN_20移动,进而影响顶点蓝色小球)


骨骼旋转后顶点的新位置(图2)

现在顶点已经到了新位置,我们的目的是要计算新位置(图2中的篮球位置)相对于调整前的骨骼(图1中的BN_20)的Bindpose(从模型空间到骨骼本地坐标的转换矩阵),这样,骨骼动画把骨骼重置位置后,小球就能保证还在调整后的位置了。我们为了达到下图的效果:


目的效果(图3)

还记得上篇文章中的公式吧:


移动顶点,得到新的坐标(图4)
这里这个M_translation就是一个矩阵,原来的骨骼乘上这个矩阵,就会到新的位置(红色骨骼从图1的位置到图2的位置),同样,顶点位置乘上这个矩阵,也会到新的位置(由图1到图2中篮球位置).所以我们可以叫它差异矩阵。

差异矩阵推导

假设原本(图1中)BN_20本地空间内的一点A 两边都乘上差异矩阵就会到新位置(图2中).
A的新位置,即可以用原来骨骼的本地到世界矩阵乘上差异矩阵来求出,也可以用新姿态下骨骼的本地到世界矩阵来求出,则推导出
其中骨骼的新旧姿态下的本地到世界矩阵都是已知量,则差异矩阵就可以求出来了。 图5
第一行,可以看做等号两边的尾部都乘上原骨骼的本地到世界矩阵的逆矩阵,则左边成了差异矩阵乘以单位矩阵,右边就是结果。其中本地到世界的逆矩阵就是世界到本地矩阵,所以推出第二行。这里的M_delta就是图4中的M_translation,命名有点混乱。上篇文章说了图4中下面一行括号中的就是新的bindpose,把图5结果带入图4的括号中,则
新的Bindpose
对应的代码如下:
Matrix4x4 newBindPose = oldBone.transform.worldToLocalMatrix * newBone.transform.localToWorldMatrix * oldBone.transform.worldToLocalMatrix * mesh.localToWorldMatrix;

至此骨骼的新Bindpose已经计算完毕,下面给Mesh应用上,这样骨骼位置不变,但是顶点相对于骨骼的位置发生了改变,骨骼动画驱动骨骼不停变化过程中,顶点始终和骨骼保持新的相对位置,从而达到捏脸的效果。应用新的bindpose代码入下:

    //给模型应用新的BindPose
    private static void ApplyNewBindpose(GameObject meshObj, Dictionary<string, Matrix4x4> bindposes)
    {   
        SkinnedMeshRenderer smr = meshObj.GetComponent<SkinnedMeshRenderer>();
        if (smr == null)
        {
            Debug.LogError("Not found SkinnedMeshRenderer " + meshTransform.name);
            return;
        }
        //实例化一份新的mesh,因为要修改mesh的数据,原始的mesh不要动,只读
        Mesh mesh = GameObject.Instantiate<Mesh>(smr.sharedMesh);
        
        Matrix4x4[] bindposes = mesh.bindposes;
        Transform[] bones = smr.bones;
        for (int i = 0; i < bones.Length; ++i)
        {
            if (bindposes.ContainsKey(bones[i].name))
            {
                bindposes[i] = bindposes[bones[i].name];
            }
        }

        mesh.bindposes = bindposes;
        smr.sharedMesh = mesh;
    }

今天的内容都是数学公式,比较枯燥,大家如果不喜欢推导过程,可以直接拿结果去用,bindpose_new那个公式。
好了,捏脸系统的完整思路就是这样了,欢迎大家指出错误和不足之处,共同进步。
【转载请注明出处】

相关文章

  • 捏脸系统中的差异矩阵推导

    在上篇文章< >[https://www.jianshu.com/p/0a9ad1e03992]中,最后留了一个悬...

  • 【GEO数据库挖掘】四、差异分析(limma)、绘图和富集分析

    参考代码在这: 1 差异分析 需要的数据:表达矩阵、分组矩阵、差异比较矩阵 至此获得了差异分析矩阵nrDEG 2 ...

  • Unity 人物捏脸的实现

    捏脸: 不知什么时候,捏脸几乎已经成为游戏的标配,用户通过捏脸系统创建出个性化角色,彰显独特的形象,增强了沉浸感。...

  • Jensen不等式

    (hessan矩阵是根据泰勒公式推导)

  • 天涯明月刀捏脸人设图赏 打造古风最美脸

    捏脸是当前MMORPG网游里面最常有的系统玩法,有的人会捏自己喜欢的人物,有的人会捏一些奇葩的人物。捏脸会让很多玩...

  • 多元logistic回归矩阵推导

    网上的文章很少多元logistic回归的矩阵推导, 这里写一下我的推导, 欢迎交流.

  • 捏脸

    有时候我竟然会捏捏自己的脸蛋。 偶尔想起你了吧。 害怕果然没有我,你好像会更开心,少了很多负能量。抱歉,没有办法控...

  • 捏脸?

    萧弈顿住脚步。 捏……脸? 原来是捏脸。 男人满腔的怒意,瞬间烟消云散。 他不自然地蹭了蹭鼻尖:“哦,是捏脸啊。”...

  • 捏脸?

    萧弈顿住脚步。 捏……脸? 原来是捏脸。 男人满腔的怒意,瞬间烟消云散。 他不自然地蹭了蹭鼻尖:“哦,是捏脸啊。”...

  • 捏脸?

    萧弈顿住脚步。 捏……脸? 原来是捏脸。 男人满腔的怒意,瞬间烟消云散。 他不自然地蹭了蹭鼻尖:“哦,是捏脸啊。”...

网友评论

      本文标题:捏脸系统中的差异矩阵推导

      本文链接:https://www.haomeiwen.com/subject/ldpxvrtx.html