unity - Blend Shape - 变形器 - 实践
文章目录
- 目的
- Blend Shape 逐顶点 多个混合思路
- Blender
- 3Ds max
- Unity 中使用
- Project
目的
拾遗,备份
Blend Shape 逐顶点 多个混合思路
blend shape 基于: vertex number, vertex sn 相同,才能正常混合、播放
也就是 vertex buffer 的顶点数量一样,还有 triangles 的 index 要一致
这样 blend shape 才能逐个顶点计算
计算公式:使用一张大佬整理的图,大佬的文章:BlendShapes基础与拓展练习(面捕与物体变形)

Blender
Shift+A 新建一个 sphere

选中

Tab 进入 Editor Mode,并且在 Data 页签属性的 Shape Keys 添加对应的 blend shape 状态


调整好每一个 Shape Keys (或是叫:blend shape) 的顶点位置
然后再 Object Mode 下,我们可以选中对应的 Shape Keys 然后调整 value 查看变形结果

最终我们尝试 K帧动画来查看 多个 shape keys 混合控制的情况

3Ds max
interlude _1 : working on Yui-chan’s face morphing. - 3Ds max 中的演示 二次元 脸部表情 FFD
Unity 中使用
先在 blender 导出 fbx

将 fbx 模型拖拽到 hierarchy

尝试拖拉 inspector 中的 blend shape 拉杆,即可查看效果

所以我们写脚本控制 blend shape 混合拉杆即可达到我们各种表情的混合控制

在原来 blendshape_1 基础上在混合 blendshape_2

blendshape_1 和 blendshape_2 一起播放

然后可以尝试看一下 blendshape_1 和 blendshape_2 不同速率的控制混合的情况
这里使用 pingpong 算法

下面是测试 csharp 脚本
// jave.lin 2023/10/07 测试 blend shapeusing System.Collections;
using UnityEngine;public class TestingBlendShape : MonoBehaviour
{public SkinnedMeshRenderer skinnedMeshRenderer;private int _BlendShape_1_IDX = -1;private int _BlendShape_2_IDX = -1;private IEnumerator _couroutine_blendShape1;private IEnumerator _couroutine_blendShape2;private IEnumerator _couroutine_pingpong;private void OnDestroy(){StopAllCoroutines();}private void Refresh(){if (skinnedMeshRenderer != null){_BlendShape_1_IDX = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("BlendShape_1");_BlendShape_2_IDX = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("BlendShape_2");}}public void ToBlendShape_1(){Refresh();if (_couroutine_blendShape1 != null){StopCoroutine(_couroutine_blendShape1);}StartCoroutine(_couroutine_blendShape1 = Play_ToBlendShape(_BlendShape_1_IDX, 100.0f));}public void ToBlendShape_2(){Refresh();if (_couroutine_blendShape2 != null){StopCoroutine(_couroutine_blendShape2);}StartCoroutine(_couroutine_blendShape2 = Play_ToBlendShape(_BlendShape_2_IDX, 100.0f));}public void ToBlendShape_1_2(){Refresh();if (_couroutine_blendShape1 != null){StopCoroutine(_couroutine_blendShape1);}StartCoroutine(_couroutine_blendShape1 = Play_ToBlendShape(_BlendShape_1_IDX, 100.0f));if (_couroutine_blendShape2 != null){StopCoroutine(_couroutine_blendShape2);}StartCoroutine(_couroutine_blendShape2 = Play_ToBlendShape(_BlendShape_2_IDX, 100.0f));}public void ToPingPong_BlendShape_1_2(){Refresh();if (_couroutine_pingpong != null){StopCoroutine(_couroutine_pingpong);}StartCoroutine(_couroutine_pingpong = PingPong_BlendShape());}public void StopAll(){StopAllCoroutines();}public void ResetAll(){if (skinnedMeshRenderer != null){var count = skinnedMeshRenderer.sharedMesh.blendShapeCount;for (int i = 0; i < count; i++){skinnedMeshRenderer.SetBlendShapeWeight(i, 0.0f);}}}private IEnumerator Play_ToBlendShape(int idx, float to_val){to_val = Mathf.Clamp(to_val, 0.0f, 100.0f);var start_val = skinnedMeshRenderer.GetBlendShapeWeight(idx);var cur_val = start_val;while (cur_val < to_val){cur_val = Mathf.MoveTowards(cur_val, to_val, (to_val - start_val) * Time.deltaTime);skinnedMeshRenderer.SetBlendShapeWeight(idx, cur_val);yield return null;}Debug.Log($"play to blend shape [{idx}] : [{to_val}] complete!");}private IEnumerator PingPong_BlendShape(){var now_time = Time.time;while (true){var _time = Time.time - now_time;var weight1 = Mathf.PingPong(_time * 200f, 100f);var weight2 = Mathf.PingPong(_time * 50f, 100f);skinnedMeshRenderer.SetBlendShapeWeight(_BlendShape_1_IDX, weight1);skinnedMeshRenderer.SetBlendShapeWeight(_BlendShape_2_IDX, weight2);yield return null;}}
}
Project
个人备份用
- blender 工程: TestingBlenderShapeKeys.blend
- unity 工程: TestingBlendShape_BRP_2020.3.37f1.rar
- 百人计划-BlendShapes基础(物体变形与面捕应用)
- google : how to implementing the blend shape in blender
- google : how to create shape keys animation in blender
- Shape Key / Blendshape Hacks to easily create expressions and actions for your avatar
- Blender 2.8 Shapekeys and Morphing
- How to Add Shape Keys in Blender
- 形态键
- 在Unity中实现BlendShape表情和骨骼动画混合的实践 - 讲得挺不错
- BlendShapes基础与拓展练习(面捕与物体变形) - 讲得挺不错
- GDC2011: Fast and Efficient Facial Rigging
- GDC jeremy_ernst_fastandefficietfacialrigging.pdf
- 技术美术百人计划-美术 3.5 BlendShape基础 笔记
- 3.5 BlendShapes基础
- 百人计划-BlendShapes基础(物体变形与面捕应用)
- 【技术美术百人计划】美术 3.5 BlendShape基础
- Unity通过导入器优化动画关键帧数据 - 删除仅仅只有 blend shape 的动画的其他骨骼信息,优化性能
- interlude _1 : working on Yui-chan’s face morphing. - 3Ds max 中的演示 二次元 脸部表情 FFD
相关文章:
unity - Blend Shape - 变形器 - 实践
文章目录 目的Blend Shape 逐顶点 多个混合思路Blender3Ds maxUnity 中使用Project 目的 拾遗,备份 Blend Shape 逐顶点 多个混合思路 blend shape 基于: vertex number, vertex sn 相同,才能正常混合、播放 也就是 vertex buffer 的顶点数…...
asp.net core mvc之路由
一、默认路由 (Startup.cs文件) routes.MapRoute(name: "default",template: "{controllerHome}/{actionIndex}/{id?}" ); 默认访问可以匹配到 https://localhost:44302/home/index/1 https://localhost:44302/home/index https:…...
前端设计模式之【访问者模式】
文章目录 前言介绍实现优缺点应用场景后言 前言 hello world欢迎来到前端的新世界 😜当前文章系列专栏:前端设计模式 🐱👓博主在前端领域还有很多知识和技术需要掌握,正在不断努力填补技术短板。(如果出现错误&#…...
通过docker-compose部署elk日志系统,并使用springboot整合
ELK是一种强大的分布式日志管理解决方案,它由三个核心组件组成: Elasticsearch:作为分布式搜索和分析引擎,Elasticsearch能够快速地存储、搜索和分析大量的日志数据,帮助用户轻松地找到所需的信息。 Logstash…...
【NLP】特征提取: 广泛指南和 3 个操作教程 [Python、CNN、BERT]
什么是机器学习中的特征提取? 特征提取是数据分析和机器学习中的基本概念,是将原始数据转换为更适合分析或建模的格式过程中的关键步骤。特征,也称为变量或属性,是我们用来进行预测、对对象进行分类或从数据中获取见解的数据点的…...
数据结构-单链表
1 链表的概念及结构 概念:链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的 。 从以上图片可以看出: 1.链式结构在逻辑上是连续的,但在物理上不一定是连续的。 2.现实中的节…...
红队系列-IOT安全深入浅出
红队专题 设备安全概述物联网设备层次模型设备通信模型 渗透测试信息收集工具 实战分析漏洞切入点D-link 850L 未授权访问 2017 认证绕过认证绕过 D-link DCS-2530Ltenda 系列 路由器 前台未授权RTSP 服务未授权 访问 弱口令命令注入思科 路由器 固件二进制 漏洞 IoT漏洞-D-Lin…...
亚数受邀参加“长三角G60科创走廊量子密码应用创新联盟(中心)”启动仪式
11月8日,在第六届中国国际进口博览会2023长三角G60科创走廊高质量发展要素对接大会上,亚数信息科技(上海)有限公司CEO翟新元作为密码企业代表之一受邀参加“长三角G60科创走廊量子密码应用创新联盟(中心)”…...
直方图学习
直方图均衡化(Histogram Equalization)是一种用于增强图像对比度的图像处理技术,通过重新分配图像的像素值,使图像中的亮度级别更加均匀,以改善图像的视觉质量。下面是进行直方图均衡化的一般步骤: 计算原始…...
Java / Android 多线程和 synchroized 锁
s AsyncTask 在Android R中标注了废弃 synchronized 同步 Thread: thread.start() public synchronized void start() {/*** This method is not invoked for the main method thread or "system"* group threads created/set up by the VM. Any new functionali…...
基于51单片机的万年历-脉搏计仿真及源程序
一、系统方案 1、本设计采用51单片机作为主控器。 2、DS1302采集年月日时分秒送到液晶1602显示。 3、按键年月日时分秒,心率报警上下限。 4、红外对接管传感器采集心率送到液晶1602显示。 5、心率低于下限或高于上限,蜂鸣器报警。 二、硬件设计 原理图如…...
【ARFoundation学习笔记】点云与参考点
写在前面的话 本系列笔记旨在记录作者在学习Unity中的AR开发过程中需要记录的问题和知识点。主要目的是为了加深记忆。其中难免出现纰漏,更多详细内容请阅读原文以及官方文档。 汪老师博客 文章目录 点云新建点云 参考点参考点的工作原理何时使用参考点使用参考点…...
uni-app:js实现数组中的相关处理-数组复制
一、slice方法-浅拷贝 使用分析 创建一个原数组的浅拷贝,对新数组的修改不会影响到原数组slice() 方法创建了一个原数组的浅拷贝,这意味着新数组和原数组中的对象引用是相同的。因此,当你修改新数组中的对象时,原数组中相应位置的…...
8 STM32标准库函数 之 实时时钟(RTC)所有函数的介绍及使用
8 STM32标准库函数 之 实时时钟(RTC)所有函数的介绍及使用 1. 图片有格式2 文字无格式二、RTC库函数固件库函数预览2.1 函数RTC_ITConfig2.2 函数RTC_EnterConfigMode2.3 函数RTC_ExitConfigMode2.4 函数RTC_GetCounter.2.5 函数RTC_SetCounter2.6 函数RTC_SetPrescaler2.7 函…...
ARMday04(开发版简介、LED点灯)
开发版简介 开发板为stm32MP157AAA,附加一个拓展版 硬件相关基础知识 PCB PCB( Printed Circuit Board),中文名称为印制电路板,又称印刷线路板,是重要的电子部件,是电子元器件的支撑体,是电子…...
国际腾讯云:云服务器疑似被病毒入侵问题解决方案!!!
云服务器可能由于弱密码、开源组件漏洞的问题被黑客入侵,本文介绍如何判断云服务器是否被病毒入侵,及其解决方法。 问题定位 使用 SSH 方式 或 使用 VNC 方式 登录实例后,通过以下方式进行判断云服务器是否被病毒入侵: rc.loca…...
Perl语言用多线程爬取商品信息并做可视化处理
首先,我们需要使用Perl的LWP::UserAgent模块来发送HTTP请求。然后,我们可以使用HTML::TreeBuilder模块来解析HTML文档。在这个例子中,我们将使用BeautifulSoup模块来解析HTML文档。 #!/usr/bin/perl use strict; use warnings; use LWP::User…...
认识计算机-JavaEE初阶
文章目录 一、计算机的发展史二、冯诺依曼体系(Von Neumann Architecture)三、CPU基本工作流程3.1 算术逻辑单元(ALU)3.2 寄存器(Register)和内存(RAM)3.3 控制单元(CU)3…...
you-get - 使用代码下载视频
文章目录 关于 you-get代码调用报错处理 源码简单分析 关于 you-get github : https://github.com/soimort/you-get you-get 是一个有名的开源视频下载工具包,这里不赘述。 代码调用 you-get 提供了命令行的方式下载视频,这里介绍使用 Python 调用源代…...
【Proteus仿真】【51单片机】汽车尾灯控制设计
文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真51单片机控制器,使用按键、LED模块等。 主要功能: 系统运行后,系统运行后,系统开始运行,K1键控制左转向灯;…...
css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...
Admin.Net中的消息通信SignalR解释
定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...
Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...
Linux-07 ubuntu 的 chrome 启动不了
文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了,报错如下四、启动不了,解决如下 总结 问题原因 在应用中可以看到chrome,但是打不开(说明:原来的ubuntu系统出问题了,这个是备用的硬盘&a…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...
SpringTask-03.入门案例
一.入门案例 启动类: package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...
聊一聊接口测试的意义有哪些?
目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开,首…...
ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...
在Ubuntu24上采用Wine打开SourceInsight
1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...
