Unity项目捏脸解决方案BlendShapes

  • 引子
  • BlendShapes
  • 具体使用
    • 代码
  • 参考链接

引子

最近公司在开发一个捏脸的SDK,使用的核心功能就是使用Unity的SkinnedMeshRenderer上的BlendShapes来实现的。这个功能在Maya和3ds Max中都可以找到。

BlendShapes

BlendShapes是一种动画制作方式,与骨骼动画相比,它主要应用在很小的局部,比如角色的面部表情。
骨骼只适合控制整体的动作,但太局部的动作使用骨骼制作会非常繁琐,同时太多的骨骼对性能也有影响。
BlendShapes的原理很简单,就是在相邻两个网格间做插值运算,从一上形状融合到另一个形状;或者说是单个网格变形以实现许多预定义形状和任何数量之间组合的技术,在Maya/3ds Max中我们称它为变形目标,例如单个网格是默认形状的基本形状(例如无表情的面),并且基本形状的其他形状用于混合/变形,是不同的表达(笑、皱眉、闭合眼皮),这些被统称为混合形状或变形目标。所以美术只要制作若干个形状的模型即可,比摆骨骼要方便很多,特别是对于面部这种很局部的动作来说。
模型在导入时,Import BlendShapes选项默认是选中的。

具体使用

  1. 要在Maya或者3ds Max里面制作一个含有BlendShapes的形变动画Avator
  2. Avator导入到Unity中。
  3. 导入的模型上面有组件SkinnedMeshRenderer,面板上有BlendShapes参数,它的下面有一连串的数值可以手动或编码设置,来实现捏脸效果。

代码

Unity提供的一些相关接口(组件SkinnedMeshRenderer中):

  • void SetBlendShapeWeight(int index, float value):用于直接设置BlendShape的值,使用index按照面板上的自上而下顺序下标来索引设置的“部位”。
  • float GetBlendShapeWeight(int index):根据index获取对应的BlendShape值。
  • sharedMesh.blendShapeCount:组建中BlendShape的数量。
  • sharedMesh.GetBlendShapeName(int shapeIndex):根据index获取对应的BlendShape名称字符串。
  • sharedMesh.GetBlendShapeIndex(string blendShapeName):根据名称获取索引的下标(第几个)。

这里我只用了了几个,还有一些并没有使用测试过。

  • void AddBlendShapeFrame(string shapeName, float frameWeight, Vector3[] deltaVertices, Vector3[] deltaNormals, Vector3[] deltaTangents):添加一个新的BlendShape框架。
  • int GetBlendShapeFrameCount(int shapeIndex):返回BlendShape的帧数。
  • void GetBlendShapeFrameVertices(int shapeIndex, int frameIndex, Vector3[] deltaVertices, Vector3[] deltaNormals, Vector3[] deltaTangents):检索BlendShape框架的deltaVertices,deltaNormals和deltaTangents。
  • float GetBlendShapeFrameWeight(int shapeIndex, int frameIndex):返回BlendShape框架的权重。

之后下面是我使用的一个脚本,当使用的一个模型(FBX)下有好多分支模型节点时,使用这个脚本统一管理设置BlendShape

using UnityEngine;public class BlendShapeModel : MonoBehaviour
{private SkinnedMeshRenderer[] skinnedMeshRenderers;private string[] m_bsNameAll;void Start(){//获取初始化skinnedMeshRenderers = GetComponentsInChildren<SkinnedMeshRenderer>();m_bsNameAll = new string[skinnedMeshRenderers.Length];for (int i = 0; i < skinnedMeshRenderers.Length; i++){for (int j = 0; j < skinnedMeshRenderers[i].sharedMesh.blendShapeCount; j++){m_bsNameAll[i] += skinnedMeshRenderers[i].sharedMesh.GetBlendShapeName(j) + ',';}}}/// <summary>/// 设置BlendShape值/// </summary>/// <param name="name">BlendShape的名字</param>/// <param name="value">BlendShape设置的值</param>public void SetBlendShapeValue(string name, float value){for (int i = 0; i < m_bsNameAll.Length; i++){if (m_bsNameAll[i].Contains(name)){int lenght = m_bsNameAll[i].IndexOf(name);int index = m_bsNameAll[i].Substring(0, lenght).Split(',').Length - 1;skinnedMeshRenderers[i].SetBlendShapeWeight(index, value);}}}
}

代码中,我是使用的名称检索对应的BlendShape,所以各个分支所对应的相同的BlendShape的名称要有相同的字符串,或一定的规律。

参考链接

  1. BlendShapes:https://www.jianshu.com/p/b8c1210dd12e
  2. Unity3D Blend Shape简析:https://www.jianshu.com/p/4ae6662a40df
  3. Unity工具类之BlendShape捏脸的实现:https://blog.csdn.net/u014361280/article/details/103929611

Unity项目捏脸解决方案BlendShape相关推荐

  1. 【游戏开发Unity】捏脸系统(附源码)

    本着"没有捏脸系统算什么RPG"的想法,着手做一个2d简易捏脸demo.其实换装游戏都差不多啦~ github代码地址:Simple-Character-Edit-System ( ...

  2. Unity 工具类 之 Blender 的下载和简单使用(为捏脸做准备)

    Unity 工具类 之 Blender 的下载和使用(为捏脸做准备) 目录 Unity 工具类 之 Blender 的下载和使用 一.简单介绍 二.下载地址 三.安装 四.简单使用 1.设置成中文界面 ...

  3. Unity 捏脸整理及基于骨骼的捏脸功能实现

    目前实现捏脸功能的方式主要有两种.一个是Blendshape(融合变形),一个是基于骨骼驱动的方式,通过修改骨骼矩阵(bindpose)来影响SkinMesh.这两种方式的最终原理都是在shader ...

  4. unity 捏脸相关

    捏脸 https://blog.csdn.net/u014361280/article/details/103929611?depth_1-utm_source=distribute.pc_relev ...

  5. unity捏脸游戏捏脸系统实现原理和代码

    unity捏脸游戏捏脸系统制作教程 unity3d捏脸系统实现原理和代码 捏脸实现原理 unity捏脸系统要用到3D建模软件,我用的是blender 不会用blender的朋友,请看这个链接: htt ...

  6. 骨骼捏脸功能的实现方法

    这是第132篇UWA技术知识分享的推送.今天我们继续为大家精选了若干和开发.优化相关的问题,建议阅读时间10分钟,认真读完必有收获. UWA 问答社区:answer.uwa4d.com UWA QQ群 ...

  7. 如何打造细致的2D捏脸系统

    大家好,我是汉家松鼠的CG,<江湖X>.<汉家江湖>的制作人和主程,今天给大家介绍一下我们游戏中的捏脸系统是如何设计和开发的. 背景介绍 游戏<汉家江湖>是我们一款 ...

  8. 《赛博朋克2077》是捏脸游戏?上科大学生社团开发了一款赛博“滤镜”

    作者 | eEhyQx 出品 | AI科技大本营 现象级大作<赛博朋克2077>终于没有跳票顺利发布了!你通关了吗? 来自上海科技大学的学生社团GeekPie打造了一款全新的"滤 ...

  9. 虚幻4 捏脸和换装系统实现

    http://blog.csdn.net/shangguanwaner/article/details/50392896 虚幻4 捏脸和换装系统实现 捏脸和换装系统基本上是一个游戏的标配了,这里记录下 ...

  10. 自定义角色外观之捏脸

    "捏脸"和"换装"在游戏中一般用来实现自定义角色外观的功能,今天先来说说"捏脸","换装"放在下一篇博文中介绍.所谓捏脸 ...

最新文章

  1. 【Leetcode】刷题之路2(python)
  2. pthread_cond_wait()函数的详解
  3. R语言ggplot2可视化自定义图例实战:添加自定义的图例、添加填充色的图例
  4. 计算机学院心理节活动,计算机学院成功举办 “说出你的故事” 心理交流互助活动...
  5. 动态创建DataGrid的模版列(转)
  6. 2016年-2020年 考研 国家线汇总
  7. 设备场景函数——72个
  8. 图解面试题:找出数组中重复的数字?
  9. 第十节(this关键字 static关键字)
  10. Redis回收进程如何工作的?
  11. C# Post接收发送XML
  12. mysql语句没出错一直抱错_为什么我的mysql语句一直报错,找不到错误,望各位大佬指点一番...
  13. 测试怎么保障软件的的质量,如何保障软件测试的质量
  14. PDF文件转化成mobi格式,亲测kindle或者iReader可用!
  15. 【最新】网站下载工具,整站下载工具汇总
  16. 英特尔第十代处理器为什么不支持win7_为什么7代CPU不支持WIN7操作系统?
  17. GOM引擎启动提示invalid filename怎么处理?
  18. python中reduce什么意思_python中的reduce
  19. Cadence allegro PCB快速自动创建差分对
  20. C语言核桃的数量问题

热门文章

  1. 团队价值观五个字_一个优秀的团队应该具有的价值观
  2. Java8 Stream经典示例
  3. mysql.sock 文件详解
  4. Torah RVP Claiming Tutorial
  5. 中文汉字错别字纠错方法
  6. virtualbox 菜单栏不见了---如何调出来
  7. 谢辉吉林大学计算机学院,【大科·数院】佳绩频传,成果丰硕——第12届中国大学生计算机设计大赛吉大赛区数院学子成绩斐然...
  8. python解压7z文件_如何读取用7z压缩的文本文件?
  9. 程序员口才练习的顶级绕口令
  10. Nginx网页优化(隐藏版本号,日志分割,更改进程数,网页压缩,防盗链详