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键控制左转向灯;…...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...
AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...
【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...
Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...
大模型多显卡多服务器并行计算方法与实践指南
一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...
JDK 17 新特性
#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的ÿ…...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...
视觉slam十四讲实践部分记录——ch2、ch3
ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...
使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...
